libopenmpt-0.3.6+release.autotools/0000755000372100037210000000000013235362225014341 500000000000000libopenmpt-0.3.6+release.autotools/build/0000755000372100037210000000000013235362225015440 500000000000000libopenmpt-0.3.6+release.autotools/build/svn_version/0000755000372100037210000000000013235362225020013 500000000000000libopenmpt-0.3.6+release.autotools/build/svn_version/svn_version.h0000644000372100037210000000054712666471503022474 00000000000000 #pragma once #if defined(MPT_PACKAGE) #define OPENMPT_VERSION_IS_PACKAGE 1 #else #define OPENMPT_VERSION_IS_PACKAGE 0 #endif #if defined(MPT_SVNURL) #define OPENMPT_VERSION_URL MPT_SVNURL #endif #if defined(MPT_SVNVERSION) #define OPENMPT_VERSION_SVNVERSION MPT_SVNVERSION #endif #if defined(MPT_SVNDATE) #define OPENMPT_VERSION_DATE MPT_SVNDATE #endif libopenmpt-0.3.6+release.autotools/libopenmpt/0000755000372100037210000000000013235362226016513 500000000000000libopenmpt-0.3.6+release.autotools/libopenmpt/libopenmpt_modplug_cpp.cpp0000644000372100037210000006657613141053304023713 00000000000000/* * 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 "libopenmpt.hpp" #include #include #include #include #include #include #include #ifdef _MSC_VER /* msvc errors when seeing dllexport declarations after prototypes have been declared in modplug.h */ #define LIBOPENMPT_MODPLUG_API #else /* !_MSC_VER */ #define LIBOPENMPT_MODPLUG_API LIBOPENMPT_API_HELPER_EXPORT #endif /* _MSC_VER */ namespace { template void Clear( T & x ) { std::memset( &x, 0, sizeof(T) ); } } class LIBOPENMPT_MODPLUG_API CSoundFile; #include "libmodplug/stdafx.h" #include "libmodplug/sndfile.h" //#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] ) ); 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(); if ( !s ) { return 0; } 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 ); } } std::memcpy( s, buf, 32 ); return static_cast( std::strlen( buf ) ); } UINT CSoundFile::GetInstrumentName( UINT nInstr, LPSTR s ) const { mpcpplog(); if ( !s ) { return 0; } 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 ); } } std::memcpy( 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_HQRESAMPLER ) == 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 libopenmpt-0.3.6+release.autotools/libopenmpt/libopenmpt_version.mk0000644000372100037210000000027313235361343022703 00000000000000LIBOPENMPT_VERSION_MAJOR=0 LIBOPENMPT_VERSION_MINOR=3 LIBOPENMPT_VERSION_PATCH=6 LIBOPENMPT_VERSION_PREREL= LIBOPENMPT_LTVER_CURRENT=1 LIBOPENMPT_LTVER_REVISION=6 LIBOPENMPT_LTVER_AGE=1 libopenmpt-0.3.6+release.autotools/libopenmpt/libopenmpt_test.cpp0000644000372100037210000000317312563561160022354 00000000000000/* * libopenmpt_test.cpp * ------------------- * Purpose: libopenmpt test suite driver * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "BuildSettings.h" #include "libopenmpt_internal.h" #include "test/test.h" #include #include #include #include using namespace OpenMPT; #if defined( LIBOPENMPT_BUILD_TEST ) #if (defined(_WIN32) || defined(WIN32)) && (defined(_UNICODE) || defined(UNICODE)) #if defined(__GNUC__) // mingw-w64 g++ does only default to special C linkage for "main", but not for "wmain" (see ). extern "C" #endif int wmain( int /*argc*/ , wchar_t * /*argv*/ [] ) { #else int main( int /*argc*/ , char * /*argv*/ [] ) { #endif try { // run test with "C" / classic() locale Test::DoTests(); // try setting the C locale to the user locale setlocale( LC_ALL, "" ); // run all tests again with a set C locale Test::DoTests(); // try to set the C and C++ locales to the user locale try { std::locale::global( std::locale( "" ) ); } catch ( ... ) { // Setting c++ global locale does not work. // This is no problem for libopenmpt, just continue. } // and now, run all tests once again Test::DoTests(); } catch ( const std::exception & e ) { std::cerr << "TEST ERROR: exception: " << ( e.what() ? e.what() : "" ) << std::endl; return -1; } catch ( ... ) { std::cerr << "TEST ERROR: unknown exception" << std::endl; return -1; } return 0; } #endif // LIBOPENMPT_BUILD_TEST libopenmpt-0.3.6+release.autotools/libopenmpt/libopenmpt_c.cpp0000644000372100037210000014700513201261423021607 00000000000000/* * libopenmpt_c.cpp * ---------------- * Purpose: libopenmpt C interface implementation * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "BuildSettings.h" #include "libopenmpt_internal.h" #include "libopenmpt.h" #include "libopenmpt_ext.h" #include "libopenmpt_impl.hpp" #include "libopenmpt_ext_impl.hpp" #include #include #include #include #include #include #include #if defined(_MSC_VER) #pragma warning(disable:4702) /* unreachable code */ #endif #ifndef NO_LIBOPENMPT_C namespace openmpt { static const char * strdup( const char * src ) { char * dst = (char*)std::calloc( std::strlen( src ) + 1, sizeof( char ) ); if ( !dst ) { return NULL; } std::strcpy( dst, src ); return dst; } class logfunc_logger : public log_interface { private: openmpt_log_func m_logfunc; void * m_user; public: logfunc_logger( openmpt_log_func func, void * user ) : m_logfunc(func), m_user(user) { return; } virtual ~logfunc_logger() { return; } virtual void log( const std::string & message ) const { if ( m_logfunc ) { m_logfunc( message.c_str(), m_user ); } else { openmpt_log_func_default( message.c_str(), m_user ); } } }; // class logfunc_logger namespace interface { class invalid_module_pointer : public openmpt::exception { public: invalid_module_pointer() throw() : openmpt::exception("module * not valid") { return; } virtual ~invalid_module_pointer() throw() { return; } }; class argument_null_pointer : public openmpt::exception { public: argument_null_pointer() throw() : openmpt::exception("argument null pointer") { return; } virtual ~argument_null_pointer() throw() { return; } }; } // namespace interface static std::string format_exception( const char * const function ) { std::string err; try { throw; } catch ( const openmpt::exception & e ) { err += function; err += ": "; err += "ERROR: "; const char * what = e.what(); err += what ? what : ""; } catch ( const std::exception & e ) { err += function; err += ": "; err += "INTERNAL ERROR: "; const char * what = e.what(); err += what ? what : ""; } catch ( ... ) { err += function; err += ": "; err += "UNKNOWN INTERNAL ERROR"; } return err; } static void error_message_from_exception( const char * * error_message, const std::exception & e ) { if ( error_message ) { const char * what = e.what(); *error_message = ( what ? openmpt::strdup( what ) : openmpt::strdup( "" ) ); } } static int error_from_exception( const char * * error_message ) { int error = 0; if ( error_message ) { if ( *error_message ) { openmpt_free_string( *error_message ); *error_message = NULL; } } try { throw; } catch ( const std::bad_alloc & e ) { error = OPENMPT_ERROR_OUT_OF_MEMORY; error_message_from_exception( error_message, e ); } catch ( const openmpt::interface::invalid_module_pointer & e ) { error = OPENMPT_ERROR_INVALID_MODULE_POINTER; error_message_from_exception( error_message, e ); } catch ( const openmpt::interface::argument_null_pointer & e ) { error = OPENMPT_ERROR_ARGUMENT_NULL_POINTER; error_message_from_exception( error_message, e ); } catch ( const openmpt::exception & e ) { error = OPENMPT_ERROR_GENERAL; error_message_from_exception( error_message, e ); } catch ( const std::invalid_argument & e ) { error = OPENMPT_ERROR_INVALID_ARGUMENT; error_message_from_exception( error_message, e ); } catch ( const std::out_of_range & e ) { error = OPENMPT_ERROR_OUT_OF_RANGE; error_message_from_exception( error_message, e ); } catch ( const std::length_error & e ) { error = OPENMPT_ERROR_LENGTH; error_message_from_exception( error_message, e ); } catch ( const std::domain_error & e ) { error = OPENMPT_ERROR_DOMAIN; error_message_from_exception( error_message, e ); } catch ( const std::logic_error & e ) { error = OPENMPT_ERROR_LOGIC; error_message_from_exception( error_message, e ); } catch ( const std::underflow_error & e ) { error = OPENMPT_ERROR_UNDERFLOW; error_message_from_exception( error_message, e ); } catch ( const std::overflow_error & e ) { error = OPENMPT_ERROR_OVERFLOW; error_message_from_exception( error_message, e ); } catch ( const std::range_error & e ) { error = OPENMPT_ERROR_RANGE; error_message_from_exception( error_message, e ); } catch ( const std::runtime_error & e ) { error = OPENMPT_ERROR_RUNTIME; error_message_from_exception( error_message, e ); } catch ( const std::exception & e ) { error = OPENMPT_ERROR_EXCEPTION; error_message_from_exception( error_message, e ); } catch ( ... ) { error = OPENMPT_ERROR_UNKNOWN; } return error; } } // namespace openmpt extern "C" { struct openmpt_module { openmpt_log_func logfunc; void * loguser; openmpt_error_func errfunc; void * erruser; int error; const char * error_message; openmpt::module_impl * impl; }; struct openmpt_module_ext { openmpt_module mod; openmpt::module_ext_impl * impl; }; } // extern "C" namespace openmpt { static void do_report_exception( const char * const function, openmpt_log_func const logfunc = 0, void * const loguser = 0, openmpt_error_func errfunc = 0, void * const erruser = 0, openmpt::module_impl * const impl = 0, openmpt_module * const mod = 0, int * const err = 0, const char * * err_msg = 0 ) { int error = OPENMPT_ERROR_OK; const char * error_message = NULL; int error_func_result = OPENMPT_ERROR_FUNC_RESULT_DEFAULT; if ( errfunc || mod || err || err_msg ) { error = error_from_exception( mod ? &error_message : NULL ); } if ( errfunc ) { error_func_result = errfunc( error, erruser ); } if ( mod && ( error_func_result & OPENMPT_ERROR_FUNC_RESULT_STORE ) ) { mod->error = error; mod->error_message = ( error_message ? openmpt::strdup( error_message ) : openmpt::strdup( "" ) ); } if ( err ) { *err = error; } if ( err_msg ) { *err_msg = ( error_message ? openmpt::strdup( error_message ) : openmpt::strdup( "" ) ); } if ( error_message ) { openmpt_free_string( error_message ); error_message = NULL; } if ( error_func_result & OPENMPT_ERROR_FUNC_RESULT_LOG ) { try { const std::string message = format_exception( function ); if ( impl ) { impl->PushToCSoundFileLog( message ); } else if ( logfunc ) { logfunc( message.c_str(), loguser ); } else { openmpt_log_func_default( message.c_str(), NULL ); } } catch ( ... ) { fprintf( stderr, "openmpt: %s:%i: UNKNOWN INTERNAL ERROR in error handling: function='%s', logfunc=%p, loguser=%p, errfunc=%p, erruser=%p, impl=%p\n", __FILE__, static_cast( __LINE__ ), function ? function : "", reinterpret_cast( logfunc ), loguser, reinterpret_cast( errfunc ), erruser, static_cast( impl ) ); fflush( stderr ); } } } static void report_exception( const char * const function, openmpt_module * mod = 0, int * error = 0, const char * * error_message = 0 ) { do_report_exception( function, mod ? mod->logfunc : NULL, mod ? mod->loguser : NULL, mod ? mod->errfunc : NULL, mod ? mod->erruser : NULL, mod ? mod->impl : 0, mod ? mod : NULL, error ? error : NULL, error_message ? error_message : NULL ); } static void report_exception( const char * const function, openmpt_log_func const logfunc, void * const loguser, openmpt_error_func errfunc, void * const erruser, int * error, const char * * error_message ) { do_report_exception( function, logfunc, loguser, errfunc, erruser, 0, 0, error, error_message ); } namespace interface { template < typename T > void check_soundfile( T * mod ) { if ( !mod ) { throw openmpt::interface::invalid_module_pointer(); } } template < typename T > void check_pointer( T * p ) { if ( !p ) { throw openmpt::interface::argument_null_pointer(); } } } // namespace interface } // namespace openmpt extern "C" { uint32_t openmpt_get_library_version(void) { try { return openmpt::get_library_version(); } catch ( ... ) { openmpt::report_exception( __FUNCTION__ ); } return 0; } uint32_t openmpt_get_core_version(void) { try { return openmpt::get_core_version(); } catch ( ... ) { openmpt::report_exception( __FUNCTION__ ); } return 0; } void openmpt_free_string( const char * str ) { try { std::free( const_cast< char * >( str ) ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__ ); } return; } const char * openmpt_get_string( const char * key ) { try { if ( !key ) { return openmpt::strdup( "" ); } return openmpt::strdup( openmpt::string::get( key ).c_str() ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__ ); } return NULL; } const char * openmpt_get_supported_extensions(void) { try { std::string retval; bool first = true; std::vector supported_extensions = openmpt::module_impl::get_supported_extensions(); for ( std::vector::iterator i = supported_extensions.begin(); i != supported_extensions.end(); ++i ) { if ( first ) { first = false; } else { retval += ";"; } retval += *i; } return openmpt::strdup( retval.c_str() ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__ ); } return NULL; } int openmpt_is_extension_supported( const char * extension ) { try { if ( !extension ) { return 0; } return openmpt::module_impl::is_extension_supported( extension ) ? 1 : 0; } catch ( ... ) { openmpt::report_exception( __FUNCTION__ ); } return 0; } void openmpt_log_func_default( const char * message, void * /*user*/ ) { fprintf( stderr, "openmpt: %s\n", message ); fflush( stderr ); } void openmpt_log_func_silent( const char * /*message*/ , void * /*user*/ ) { return; } int openmpt_error_is_transient( int error ) { int result = 0; switch ( error ) { case OPENMPT_ERROR_OUT_OF_MEMORY: result = 1; break; default: result = 0; break; } return result; } const char * openmpt_error_string( int error ) { const char * text = "unknown error"; switch ( error ) { case OPENMPT_ERROR_OK: text = ""; break; case OPENMPT_ERROR_UNKNOWN: text = "unknown internal error"; break; case OPENMPT_ERROR_EXCEPTION: text = "unknown exception "; break; case OPENMPT_ERROR_OUT_OF_MEMORY: text = "out of memory"; break; case OPENMPT_ERROR_RUNTIME: text = "runtime error"; break; case OPENMPT_ERROR_RANGE: text = "range error"; break; case OPENMPT_ERROR_OVERFLOW: text = "arithmetic overflow"; break; case OPENMPT_ERROR_UNDERFLOW: text = "arithmetic underflow"; break; case OPENMPT_ERROR_LOGIC: text = "logic error"; break; case OPENMPT_ERROR_DOMAIN: text = "value domain error"; break; case OPENMPT_ERROR_LENGTH: text = "maximum supported size exceeded"; break; case OPENMPT_ERROR_OUT_OF_RANGE: text = "argument out of range"; break; case OPENMPT_ERROR_INVALID_ARGUMENT: text = "invalid argument"; break; case OPENMPT_ERROR_GENERAL: text = "libopenmpt error"; break; } return openmpt::strdup( text ); } int openmpt_error_func_default( int error, void * /* user */ ) { (void)error; return OPENMPT_ERROR_FUNC_RESULT_DEFAULT; } int openmpt_error_func_log( int error, void * /* user */ ) { (void)error; return OPENMPT_ERROR_FUNC_RESULT_LOG; } int openmpt_error_func_store( int error, void * /* user */ ) { (void)error; return OPENMPT_ERROR_FUNC_RESULT_STORE; } int openmpt_error_func_ignore( int error, void * /* user */ ) { (void)error; return OPENMPT_ERROR_FUNC_RESULT_NONE; } int openmpt_error_func_errno( int error, void * user ) { int * e = (int *)user; if ( !e ) { return OPENMPT_ERROR_FUNC_RESULT_DEFAULT; } *e = error; return OPENMPT_ERROR_FUNC_RESULT_NONE; } void * openmpt_error_func_errno_userdata( int * error ) { return (void *)error; } double openmpt_could_open_probability( openmpt_stream_callbacks stream_callbacks, void * stream, double effort, openmpt_log_func logfunc, void * loguser ) { return openmpt_could_open_probability2( stream_callbacks, stream, effort, logfunc, loguser, NULL, NULL, NULL, NULL ); } double openmpt_could_open_propability( openmpt_stream_callbacks stream_callbacks, void * stream, double effort, openmpt_log_func logfunc, void * loguser ) { return openmpt_could_open_probability2( stream_callbacks, stream, effort, logfunc, loguser, NULL, NULL, NULL, NULL ); } double openmpt_could_open_probability2( openmpt_stream_callbacks stream_callbacks, void * stream, double effort, openmpt_log_func logfunc, void * loguser, openmpt_error_func errfunc, void * erruser, int * error, const char * * error_message ) { try { openmpt::callback_stream_wrapper istream = { stream, stream_callbacks.read, stream_callbacks.seek, stream_callbacks.tell }; return openmpt::module_impl::could_open_probability( istream, effort, openmpt::helper::make_unique( logfunc ? logfunc : openmpt_log_func_default, loguser ) ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, logfunc, loguser, errfunc, erruser, error, error_message ); } return 0.0; } size_t openmpt_probe_file_header_get_recommended_size(void) { try { return openmpt::module_impl::probe_file_header_get_recommended_size(); } catch ( ... ) { openmpt::report_exception( __FUNCTION__ ); } return 0; } int openmpt_probe_file_header( uint64_t flags, const void * data, size_t size, uint64_t filesize, openmpt_log_func logfunc, void * loguser, openmpt_error_func errfunc, void * erruser, int * error, const char * * error_message ) { try { return openmpt::module_impl::probe_file_header( flags, data, size, filesize ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, logfunc, loguser, errfunc, erruser, error, error_message ); } return OPENMPT_PROBE_FILE_HEADER_RESULT_ERROR; } int openmpt_probe_file_header_without_filesize( uint64_t flags, const void * data, size_t size, openmpt_log_func logfunc, void * loguser, openmpt_error_func errfunc, void * erruser, int * error, const char * * error_message ) { try { return openmpt::module_impl::probe_file_header( flags, data, size ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, logfunc, loguser, errfunc, erruser, error, error_message ); } return OPENMPT_PROBE_FILE_HEADER_RESULT_ERROR; } int openmpt_probe_file_header_from_stream( uint64_t flags, openmpt_stream_callbacks stream_callbacks, void * stream, openmpt_log_func logfunc, void * loguser, openmpt_error_func errfunc, void * erruser, int * error, const char * * error_message ) { try { openmpt::callback_stream_wrapper istream = { stream, stream_callbacks.read, stream_callbacks.seek, stream_callbacks.tell }; return openmpt::module_impl::probe_file_header( flags, istream ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, logfunc, loguser, errfunc, erruser, error, error_message ); } return OPENMPT_PROBE_FILE_HEADER_RESULT_ERROR; } openmpt_module * openmpt_module_create( openmpt_stream_callbacks stream_callbacks, void * stream, openmpt_log_func logfunc, void * user, const openmpt_module_initial_ctl * ctls ) { return openmpt_module_create2( stream_callbacks, stream, logfunc, user, NULL, NULL, NULL, NULL, ctls ); } openmpt_module * openmpt_module_create2( openmpt_stream_callbacks stream_callbacks, void * stream, openmpt_log_func logfunc, void * loguser, openmpt_error_func errfunc, void * erruser, int * error, const char * * error_message, const openmpt_module_initial_ctl * ctls ) { try { openmpt_module * mod = (openmpt_module*)std::calloc( 1, sizeof( openmpt_module ) ); if ( !mod ) { throw std::bad_alloc(); } std::memset( mod, 0, sizeof( openmpt_module ) ); mod->logfunc = logfunc ? logfunc : openmpt_log_func_default; mod->loguser = loguser; mod->errfunc = errfunc ? errfunc : NULL; mod->erruser = erruser; mod->error = OPENMPT_ERROR_OK; mod->error_message = NULL; mod->impl = 0; try { std::map< std::string, std::string > ctls_map; if ( ctls ) { for ( const openmpt_module_initial_ctl * it = ctls; it->ctl; ++it ) { if ( it->value ) { ctls_map[ it->ctl ] = it->value; } else { ctls_map.erase( it->ctl ); } } } openmpt::callback_stream_wrapper istream = { stream, stream_callbacks.read, stream_callbacks.seek, stream_callbacks.tell }; mod->impl = new openmpt::module_impl( istream, openmpt::helper::make_unique( mod->logfunc, mod->loguser ), ctls_map ); return mod; } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod, error, error_message ); } delete mod->impl; mod->impl = 0; if ( mod->error_message ) { openmpt_free_string( mod->error_message ); mod->error_message = NULL; } std::free( (void*)mod ); mod = NULL; } catch ( ... ) { openmpt::report_exception( __FUNCTION__, 0, error, error_message ); } return NULL; } openmpt_module * openmpt_module_create_from_memory( const void * filedata, size_t filesize, openmpt_log_func logfunc, void * user, const openmpt_module_initial_ctl * ctls ) { return openmpt_module_create_from_memory2( filedata, filesize, logfunc, user, NULL, NULL, NULL, NULL, ctls ); } openmpt_module * openmpt_module_create_from_memory2( const void * filedata, size_t filesize, openmpt_log_func logfunc, void * loguser, openmpt_error_func errfunc, void * erruser, int * error, const char * * error_message, const openmpt_module_initial_ctl * ctls ) { try { openmpt_module * mod = (openmpt_module*)std::calloc( 1, sizeof( openmpt_module ) ); if ( !mod ) { throw std::bad_alloc(); } std::memset( mod, 0, sizeof( openmpt_module ) ); mod->logfunc = logfunc ? logfunc : openmpt_log_func_default; mod->loguser = loguser; mod->errfunc = errfunc ? errfunc : NULL; mod->erruser = erruser; mod->error = OPENMPT_ERROR_OK; mod->error_message = NULL; mod->impl = 0; try { std::map< std::string, std::string > ctls_map; if ( ctls ) { for ( const openmpt_module_initial_ctl * it = ctls; it->ctl; ++it ) { if ( it->value ) { ctls_map[ it->ctl ] = it->value; } else { ctls_map.erase( it->ctl ); } } } mod->impl = new openmpt::module_impl( filedata, filesize, openmpt::helper::make_unique( mod->logfunc, mod->loguser ), ctls_map ); return mod; } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod, error, error_message ); } delete mod->impl; mod->impl = 0; if ( mod->error_message ) { openmpt_free_string( mod->error_message ); mod->error_message = NULL; } std::free( (void*)mod ); mod = NULL; } catch ( ... ) { openmpt::report_exception( __FUNCTION__, 0, error, error_message ); } return NULL; } void openmpt_module_destroy( openmpt_module * mod ) { try { openmpt::interface::check_soundfile( mod ); delete mod->impl; mod->impl = 0; if ( mod->error_message ) { openmpt_free_string( mod->error_message ); mod->error_message = NULL; } std::free( (void*)mod ); mod = NULL; return; } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return; } void openmpt_module_set_log_func( openmpt_module * mod, openmpt_log_func logfunc, void * loguser ) { try { openmpt::interface::check_soundfile( mod ); mod->logfunc = logfunc ? logfunc : openmpt_log_func_default; mod->loguser = loguser; return; } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return; } void openmpt_module_set_error_func( openmpt_module * mod, openmpt_error_func errfunc, void * erruser ) { try { openmpt::interface::check_soundfile( mod ); mod->errfunc = errfunc ? errfunc : NULL; mod->erruser = erruser; mod->error = OPENMPT_ERROR_OK; return; } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return; } int openmpt_module_error_get_last( openmpt_module * mod ) { try { openmpt::interface::check_soundfile( mod ); return mod->error; } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return -1; } const char * openmpt_module_error_get_last_message( openmpt_module * mod ) { try { openmpt::interface::check_soundfile( mod ); return mod->error_message ? openmpt::strdup( mod->error_message ) : openmpt::strdup( "" ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return NULL; } void openmpt_module_error_set_last( openmpt_module * mod, int error ) { try { openmpt::interface::check_soundfile( mod ); mod->error = error; if ( mod->error_message ) { openmpt_free_string( mod->error_message ); mod->error_message = NULL; } return; } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return; } void openmpt_module_error_clear( openmpt_module * mod ) { try { openmpt::interface::check_soundfile( mod ); mod->error = OPENMPT_ERROR_OK; if ( mod->error_message ) { openmpt_free_string( mod->error_message ); mod->error_message = NULL; } return; } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return; } int openmpt_module_select_subsong( openmpt_module * mod, int32_t subsong ) { try { openmpt::interface::check_soundfile( mod ); mod->impl->select_subsong( subsong ); return 1; } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0; } int32_t openmpt_module_get_selected_subsong( openmpt_module * mod ) { try { openmpt::interface::check_soundfile( mod ); return mod->impl->get_selected_subsong(); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return -1; } int openmpt_module_set_repeat_count( openmpt_module * mod, int32_t repeat_count ) { try { openmpt::interface::check_soundfile( mod ); mod->impl->set_repeat_count( repeat_count ); return 1; } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0; } int32_t openmpt_module_get_repeat_count( openmpt_module * mod ) { try { openmpt::interface::check_soundfile( mod ); return mod->impl->get_repeat_count(); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0; } double openmpt_module_get_duration_seconds( openmpt_module * mod ) { try { openmpt::interface::check_soundfile( mod ); return mod->impl->get_duration_seconds(); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0.0; } double openmpt_module_set_position_seconds( openmpt_module * mod, double seconds ) { try { openmpt::interface::check_soundfile( mod ); return mod->impl->set_position_seconds( seconds ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0.0; } double openmpt_module_get_position_seconds( openmpt_module * mod ) { try { openmpt::interface::check_soundfile( mod ); return mod->impl->get_position_seconds(); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0.0; } double openmpt_module_set_position_order_row( openmpt_module * mod, int32_t order, int32_t row ) { try { openmpt::interface::check_soundfile( mod ); return mod->impl->set_position_order_row( order, row ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0.0; } int openmpt_module_get_render_param( openmpt_module * mod, int param, int32_t * value ) { try { openmpt::interface::check_soundfile( mod ); openmpt::interface::check_pointer( value ); *value = mod->impl->get_render_param( (openmpt::module::render_param)param ); return 1; } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0; } int openmpt_module_set_render_param( openmpt_module * mod, int param, int32_t value ) { try { openmpt::interface::check_soundfile( mod ); mod->impl->set_render_param( (openmpt::module::render_param)param, value ); return 1; } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0; } size_t openmpt_module_read_mono( openmpt_module * mod, int32_t samplerate, size_t count, int16_t * mono ) { try { openmpt::interface::check_soundfile( mod ); return mod->impl->read( samplerate, count, mono ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0; } size_t openmpt_module_read_stereo( openmpt_module * mod, int32_t samplerate, size_t count, int16_t * left, int16_t * right ) { try { openmpt::interface::check_soundfile( mod ); return mod->impl->read( samplerate, count, left, right ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0; } size_t openmpt_module_read_quad( openmpt_module * mod, int32_t samplerate, size_t count, int16_t * left, int16_t * right, int16_t * rear_left, int16_t * rear_right ) { try { openmpt::interface::check_soundfile( mod ); return mod->impl->read( samplerate, count, left, right, rear_left, rear_right ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0; } size_t openmpt_module_read_float_mono( openmpt_module * mod, int32_t samplerate, size_t count, float * mono ) { try { openmpt::interface::check_soundfile( mod ); return mod->impl->read( samplerate, count, mono ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0; } size_t openmpt_module_read_float_stereo( openmpt_module * mod, int32_t samplerate, size_t count, float * left, float * right ) { try { openmpt::interface::check_soundfile( mod ); return mod->impl->read( samplerate, count, left, right ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0; } size_t openmpt_module_read_float_quad( openmpt_module * mod, int32_t samplerate, size_t count, float * left, float * right, float * rear_left, float * rear_right ) { try { openmpt::interface::check_soundfile( mod ); return mod->impl->read( samplerate, count, left, right, rear_left, rear_right ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0; } size_t openmpt_module_read_interleaved_stereo( openmpt_module * mod, int32_t samplerate, size_t count, int16_t * interleaved_stereo ) { try { openmpt::interface::check_soundfile( mod ); return mod->impl->read_interleaved_stereo( samplerate, count, interleaved_stereo ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0; } size_t openmpt_module_read_interleaved_quad( openmpt_module * mod, int32_t samplerate, size_t count, int16_t * interleaved_quad ) { try { openmpt::interface::check_soundfile( mod ); return mod->impl->read_interleaved_quad( samplerate, count, interleaved_quad ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0; } size_t openmpt_module_read_interleaved_float_stereo( openmpt_module * mod, int32_t samplerate, size_t count, float * interleaved_stereo ) { try { openmpt::interface::check_soundfile( mod ); return mod->impl->read_interleaved_stereo( samplerate, count, interleaved_stereo ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0; } size_t openmpt_module_read_interleaved_float_quad( openmpt_module * mod, int32_t samplerate, size_t count, float * interleaved_quad ) { try { openmpt::interface::check_soundfile( mod ); return mod->impl->read_interleaved_quad( samplerate, count, interleaved_quad ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0; } const char * openmpt_module_get_metadata_keys( openmpt_module * mod ) { try { openmpt::interface::check_soundfile( mod ); std::string retval; bool first = true; std::vector metadata_keys = mod->impl->get_metadata_keys(); for ( std::vector::iterator i = metadata_keys.begin(); i != metadata_keys.end(); ++i ) { if ( first ) { first = false; } else { retval += ";"; } retval += *i; } return openmpt::strdup( retval.c_str() ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return NULL; } const char * openmpt_module_get_metadata( openmpt_module * mod, const char * key ) { try { openmpt::interface::check_soundfile( mod ); openmpt::interface::check_pointer( key ); return openmpt::strdup( mod->impl->get_metadata( key ).c_str() ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return NULL; } LIBOPENMPT_API int32_t openmpt_module_get_current_speed( openmpt_module * mod ) { try { openmpt::interface::check_soundfile( mod ); return mod->impl->get_current_speed(); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0; } LIBOPENMPT_API int32_t openmpt_module_get_current_tempo( openmpt_module * mod ) { try { openmpt::interface::check_soundfile( mod ); return mod->impl->get_current_tempo(); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0; } LIBOPENMPT_API int32_t openmpt_module_get_current_order( openmpt_module * mod ) { try { openmpt::interface::check_soundfile( mod ); return mod->impl->get_current_order(); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0; } LIBOPENMPT_API int32_t openmpt_module_get_current_pattern( openmpt_module * mod ) { try { openmpt::interface::check_soundfile( mod ); return mod->impl->get_current_pattern(); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0; } LIBOPENMPT_API int32_t openmpt_module_get_current_row( openmpt_module * mod ) { try { openmpt::interface::check_soundfile( mod ); return mod->impl->get_current_row(); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0; } LIBOPENMPT_API int32_t openmpt_module_get_current_playing_channels( openmpt_module * mod ) { try { openmpt::interface::check_soundfile( mod ); return mod->impl->get_current_playing_channels(); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0; } LIBOPENMPT_API float openmpt_module_get_current_channel_vu_mono( openmpt_module * mod, int32_t channel ) { try { openmpt::interface::check_soundfile( mod ); return mod->impl->get_current_channel_vu_mono( channel ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0.0; } LIBOPENMPT_API float openmpt_module_get_current_channel_vu_left( openmpt_module * mod, int32_t channel ) { try { openmpt::interface::check_soundfile( mod ); return mod->impl->get_current_channel_vu_left( channel ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0.0; } LIBOPENMPT_API float openmpt_module_get_current_channel_vu_right( openmpt_module * mod, int32_t channel ) { try { openmpt::interface::check_soundfile( mod ); return mod->impl->get_current_channel_vu_right( channel ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0.0; } LIBOPENMPT_API float openmpt_module_get_current_channel_vu_rear_left( openmpt_module * mod, int32_t channel ) { try { openmpt::interface::check_soundfile( mod ); return mod->impl->get_current_channel_vu_rear_left( channel ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0.0; } LIBOPENMPT_API float openmpt_module_get_current_channel_vu_rear_right( openmpt_module * mod, int32_t channel ) { try { openmpt::interface::check_soundfile( mod ); return mod->impl->get_current_channel_vu_rear_right( channel ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0.0; } LIBOPENMPT_API int32_t openmpt_module_get_num_subsongs( openmpt_module * mod ) { try { openmpt::interface::check_soundfile( mod ); return mod->impl->get_num_subsongs(); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0; } LIBOPENMPT_API int32_t openmpt_module_get_num_channels( openmpt_module * mod ) { try { openmpt::interface::check_soundfile( mod ); return mod->impl->get_num_channels(); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0; } LIBOPENMPT_API int32_t openmpt_module_get_num_orders( openmpt_module * mod ) { try { openmpt::interface::check_soundfile( mod ); return mod->impl->get_num_orders(); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0; } LIBOPENMPT_API int32_t openmpt_module_get_num_patterns( openmpt_module * mod ) { try { openmpt::interface::check_soundfile( mod ); return mod->impl->get_num_patterns(); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0; } LIBOPENMPT_API int32_t openmpt_module_get_num_instruments( openmpt_module * mod ) { try { openmpt::interface::check_soundfile( mod ); return mod->impl->get_num_instruments(); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0; } LIBOPENMPT_API int32_t openmpt_module_get_num_samples( openmpt_module * mod ) { try { openmpt::interface::check_soundfile( mod ); return mod->impl->get_num_samples(); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0; } LIBOPENMPT_API const char * openmpt_module_get_subsong_name( openmpt_module * mod, int32_t index ) { try { openmpt::interface::check_soundfile( mod ); std::vector names = mod->impl->get_subsong_names(); if ( names.size() >= (std::size_t)std::numeric_limits::max() ) { throw std::runtime_error("too many names"); } if ( index < 0 || index >= (int32_t)names.size() ) { return openmpt::strdup( "" ); } return openmpt::strdup( names[index].c_str() ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return NULL; } LIBOPENMPT_API const char * openmpt_module_get_channel_name( openmpt_module * mod, int32_t index ) { try { openmpt::interface::check_soundfile( mod ); std::vector names = mod->impl->get_channel_names(); if ( names.size() >= (std::size_t)std::numeric_limits::max() ) { throw std::runtime_error("too many names"); } if ( index < 0 || index >= (int32_t)names.size() ) { return openmpt::strdup( "" ); } return openmpt::strdup( names[index].c_str() ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return NULL; } LIBOPENMPT_API const char * openmpt_module_get_order_name( openmpt_module * mod, int32_t index ) { try { openmpt::interface::check_soundfile( mod ); std::vector names = mod->impl->get_order_names(); if ( names.size() >= (std::size_t)std::numeric_limits::max() ) { throw std::runtime_error("too many names"); } if ( index < 0 || index >= (int32_t)names.size() ) { return openmpt::strdup( "" ); } return openmpt::strdup( names[index].c_str() ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return NULL; } LIBOPENMPT_API const char * openmpt_module_get_pattern_name( openmpt_module * mod, int32_t index ) { try { openmpt::interface::check_soundfile( mod ); std::vector names = mod->impl->get_pattern_names(); if ( names.size() >= (std::size_t)std::numeric_limits::max() ) { throw std::runtime_error("too many names"); } if ( index < 0 || index >= (int32_t)names.size() ) { return openmpt::strdup( "" ); } return openmpt::strdup( names[index].c_str() ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return NULL; } LIBOPENMPT_API const char * openmpt_module_get_instrument_name( openmpt_module * mod, int32_t index ) { try { openmpt::interface::check_soundfile( mod ); std::vector names = mod->impl->get_instrument_names(); if ( names.size() >= (std::size_t)std::numeric_limits::max() ) { throw std::runtime_error("too many names"); } if ( index < 0 || index >= (int32_t)names.size() ) { return openmpt::strdup( "" ); } return openmpt::strdup( names[index].c_str() ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return NULL; } LIBOPENMPT_API const char * openmpt_module_get_sample_name( openmpt_module * mod, int32_t index ) { try { openmpt::interface::check_soundfile( mod ); std::vector names = mod->impl->get_sample_names(); if ( names.size() >= (std::size_t)std::numeric_limits::max() ) { throw std::runtime_error("too many names"); } if ( index < 0 || index >= (int32_t)names.size() ) { return openmpt::strdup( "" ); } return openmpt::strdup( names[index].c_str() ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return NULL; } LIBOPENMPT_API int32_t openmpt_module_get_order_pattern( openmpt_module * mod, int32_t order ) { try { openmpt::interface::check_soundfile( mod ); return mod->impl->get_order_pattern( order ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0; } LIBOPENMPT_API int32_t openmpt_module_get_pattern_num_rows( openmpt_module * mod, int32_t pattern ) { try { openmpt::interface::check_soundfile( mod ); return mod->impl->get_pattern_num_rows( pattern ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0; } LIBOPENMPT_API uint8_t openmpt_module_get_pattern_row_channel_command( openmpt_module * mod, int32_t pattern, int32_t row, int32_t channel, int command ) { try { openmpt::interface::check_soundfile( mod ); return mod->impl->get_pattern_row_channel_command( pattern, row, channel, command ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0; } LIBOPENMPT_API const char * openmpt_module_format_pattern_row_channel_command( openmpt_module * mod, int32_t pattern, int32_t row, int32_t channel, int command ) { try { openmpt::interface::check_soundfile( mod ); return openmpt::strdup( mod->impl->format_pattern_row_channel_command( pattern, row, channel, command ).c_str() ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0; } LIBOPENMPT_API const char * openmpt_module_highlight_pattern_row_channel_command( openmpt_module * mod, int32_t pattern, int32_t row, int32_t channel, int command ) { try { openmpt::interface::check_soundfile( mod ); return openmpt::strdup( mod->impl->highlight_pattern_row_channel_command( pattern, row, channel, command ).c_str() ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0; } LIBOPENMPT_API const char * openmpt_module_format_pattern_row_channel( openmpt_module * mod, int32_t pattern, int32_t row, int32_t channel, size_t width, int pad ) { try { openmpt::interface::check_soundfile( mod ); return openmpt::strdup( mod->impl->format_pattern_row_channel( pattern, row, channel, width, pad ? true : false ).c_str() ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0; } LIBOPENMPT_API const char * openmpt_module_highlight_pattern_row_channel( openmpt_module * mod, int32_t pattern, int32_t row, int32_t channel, size_t width, int pad ) { try { openmpt::interface::check_soundfile( mod ); return openmpt::strdup( mod->impl->highlight_pattern_row_channel( pattern, row, channel, width, pad ? true : false ).c_str() ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0; } const char * openmpt_module_get_ctls( openmpt_module * mod ) { try { openmpt::interface::check_soundfile( mod ); std::string retval; bool first = true; std::vector ctls = mod->impl->get_ctls(); for ( std::vector::iterator i = ctls.begin(); i != ctls.end(); ++i ) { if ( first ) { first = false; } else { retval += ";"; } retval += *i; } return openmpt::strdup( retval.c_str() ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return NULL; } const char * openmpt_module_ctl_get( openmpt_module * mod, const char * ctl ) { try { openmpt::interface::check_soundfile( mod ); openmpt::interface::check_pointer( ctl ); return openmpt::strdup( mod->impl->ctl_get( ctl ).c_str() ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return NULL; } int openmpt_module_ctl_set( openmpt_module * mod, const char * ctl, const char * value ) { try { openmpt::interface::check_soundfile( mod ); openmpt::interface::check_pointer( ctl ); openmpt::interface::check_pointer( value ); mod->impl->ctl_set( ctl, value ); return 1; } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod ); } return 0; } openmpt_module_ext * openmpt_module_ext_create( openmpt_stream_callbacks stream_callbacks, void * stream, openmpt_log_func logfunc, void * loguser, openmpt_error_func errfunc, void * erruser, int * error, const char * * error_message, const openmpt_module_initial_ctl * ctls ) { try { openmpt_module_ext * mod_ext = (openmpt_module_ext*)std::calloc( 1, sizeof( openmpt_module_ext ) ); if ( !mod_ext ) { throw std::bad_alloc(); } std::memset( mod_ext, 0, sizeof( openmpt_module_ext ) ); openmpt_module * mod = &mod_ext->mod; std::memset( mod, 0, sizeof( openmpt_module ) ); mod_ext->impl = 0; mod->logfunc = logfunc ? logfunc : openmpt_log_func_default; mod->loguser = loguser; mod->errfunc = errfunc ? errfunc : NULL; mod->erruser = erruser; mod->error = OPENMPT_ERROR_OK; mod->error_message = NULL; mod->impl = 0; try { std::map< std::string, std::string > ctls_map; if ( ctls ) { for ( const openmpt_module_initial_ctl * it = ctls; it->ctl; ++it ) { if ( it->value ) { ctls_map[ it->ctl ] = it->value; } else { ctls_map.erase( it->ctl ); } } } openmpt::callback_stream_wrapper istream = { stream, stream_callbacks.read, stream_callbacks.seek, stream_callbacks.tell }; mod_ext->impl = new openmpt::module_ext_impl( istream, openmpt::helper::make_unique( mod->logfunc, mod->loguser ), ctls_map ); mod->impl = mod_ext->impl; return mod_ext; } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod, error, error_message ); } delete mod_ext->impl; mod_ext->impl = 0; mod->impl = 0; if ( mod->error_message ) { openmpt_free_string( mod->error_message ); mod->error_message = NULL; } std::free( (void*)mod_ext ); mod_ext = NULL; } catch ( ... ) { openmpt::report_exception( __FUNCTION__, 0, error, error_message ); } return NULL; } openmpt_module_ext * openmpt_module_ext_create_from_memory( const void * filedata, size_t filesize, openmpt_log_func logfunc, void * loguser, openmpt_error_func errfunc, void * erruser, int * error, const char * * error_message, const openmpt_module_initial_ctl * ctls ) { try { openmpt_module_ext * mod_ext = (openmpt_module_ext*)std::calloc( 1, sizeof( openmpt_module_ext ) ); if ( !mod_ext ) { throw std::bad_alloc(); } std::memset( mod_ext, 0, sizeof( openmpt_module_ext ) ); openmpt_module * mod = &mod_ext->mod; std::memset( mod, 0, sizeof( openmpt_module ) ); mod_ext->impl = 0; mod->logfunc = logfunc ? logfunc : openmpt_log_func_default; mod->loguser = loguser; mod->errfunc = errfunc ? errfunc : NULL; mod->erruser = erruser; mod->error = OPENMPT_ERROR_OK; mod->error_message = NULL; mod->impl = 0; try { std::map< std::string, std::string > ctls_map; if ( ctls ) { for ( const openmpt_module_initial_ctl * it = ctls; it->ctl; ++it ) { if ( it->value ) { ctls_map[ it->ctl ] = it->value; } else { ctls_map.erase( it->ctl ); } } } mod_ext->impl = new openmpt::module_ext_impl( filedata, filesize, openmpt::helper::make_unique( mod->logfunc, mod->loguser ), ctls_map ); mod->impl = mod_ext->impl; return mod_ext; } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod, error, error_message ); } delete mod_ext->impl; mod_ext->impl = 0; mod->impl = 0; if ( mod->error_message ) { openmpt_free_string( mod->error_message ); mod->error_message = NULL; } std::free( (void*)mod_ext ); mod_ext = NULL; } catch ( ... ) { openmpt::report_exception( __FUNCTION__, 0, error, error_message ); } return NULL; } void openmpt_module_ext_destroy( openmpt_module_ext * mod_ext ) { try { openmpt::interface::check_soundfile( mod_ext ); openmpt_module * mod = &mod_ext->mod; mod->impl = 0; delete mod_ext->impl; mod_ext->impl = 0; if ( mod->error_message ) { openmpt_free_string( mod->error_message ); mod->error_message = NULL; } std::free( (void*)mod_ext ); mod_ext = NULL; return; } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod_ext ? &mod_ext->mod : NULL ); } return; } openmpt_module * openmpt_module_ext_get_module( openmpt_module_ext * mod_ext ) { try { openmpt::interface::check_soundfile( mod_ext ); openmpt_module * mod = &mod_ext->mod; return mod; } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod_ext ? &mod_ext->mod : NULL ); } return NULL; } static int get_pattern_row_channel_volume_effect_type( openmpt_module_ext * mod_ext, int32_t pattern, int32_t row, int32_t channel ) { try { openmpt::interface::check_soundfile( mod_ext ); return mod_ext->impl->get_pattern_row_channel_volume_effect_type( pattern, row, channel ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod_ext ? &mod_ext->mod : NULL ); } return -1; } static int get_pattern_row_channel_effect_type( openmpt_module_ext * mod_ext, int32_t pattern, int32_t row, int32_t channel ) { try { openmpt::interface::check_soundfile( mod_ext ); return mod_ext->impl->get_pattern_row_channel_effect_type( pattern, row, channel ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod_ext ? &mod_ext->mod : NULL ); } return -1; } int set_current_speed( openmpt_module_ext * mod_ext, int32_t speed ) { try { openmpt::interface::check_soundfile( mod_ext ); mod_ext->impl->set_current_speed( speed ); return 1; } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod_ext ? &mod_ext->mod : NULL ); } return 0; } int set_current_tempo( openmpt_module_ext * mod_ext, int32_t tempo ) { try { openmpt::interface::check_soundfile( mod_ext ); mod_ext->impl->set_current_tempo( tempo ); return 1; } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod_ext ? &mod_ext->mod : NULL ); } return 0; } int set_tempo_factor( openmpt_module_ext * mod_ext, double factor ) { try { openmpt::interface::check_soundfile( mod_ext ); mod_ext->impl->set_tempo_factor( factor ); return 1; } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod_ext ? &mod_ext->mod : NULL ); } return 0; } double get_tempo_factor( openmpt_module_ext * mod_ext ) { try { openmpt::interface::check_soundfile( mod_ext ); return mod_ext->impl->get_tempo_factor(); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod_ext ? &mod_ext->mod : NULL ); } return 0.0; } int set_pitch_factor( openmpt_module_ext * mod_ext, double factor ) { try { openmpt::interface::check_soundfile( mod_ext ); mod_ext->impl->set_pitch_factor( factor ); return 1; } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod_ext ? &mod_ext->mod : NULL ); } return 0; } double get_pitch_factor( openmpt_module_ext * mod_ext ) { try { openmpt::interface::check_soundfile( mod_ext ); return mod_ext->impl->get_pitch_factor(); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod_ext ? &mod_ext->mod : NULL ); } return 0.0; } int set_global_volume( openmpt_module_ext * mod_ext, double volume ) { try { openmpt::interface::check_soundfile( mod_ext ); mod_ext->impl->set_global_volume( volume ); return 1; } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod_ext ? &mod_ext->mod : NULL ); } return 0; } double get_global_volume( openmpt_module_ext * mod_ext ) { try { openmpt::interface::check_soundfile( mod_ext ); return mod_ext->impl->get_global_volume(); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod_ext ? &mod_ext->mod : NULL ); } return 0.0; } int set_channel_volume( openmpt_module_ext * mod_ext, int32_t channel, double volume ) { try { openmpt::interface::check_soundfile( mod_ext ); mod_ext->impl->set_channel_volume( channel, volume ); return 1; } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod_ext ? &mod_ext->mod : NULL ); } return 0; } double get_channel_volume( openmpt_module_ext * mod_ext, int32_t channel ) { try { openmpt::interface::check_soundfile( mod_ext ); return mod_ext->impl->get_channel_volume( channel ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod_ext ? &mod_ext->mod : NULL ); } return 0.0; } int set_channel_mute_status( openmpt_module_ext * mod_ext, int32_t channel, int mute ) { try { openmpt::interface::check_soundfile( mod_ext ); mod_ext->impl->set_channel_mute_status( channel, mute ? true : false ); return 1; } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod_ext ? &mod_ext->mod : NULL ); } return 0; } int get_channel_mute_status( openmpt_module_ext * mod_ext, int32_t channel ) { try { openmpt::interface::check_soundfile( mod_ext ); return mod_ext->impl->get_channel_mute_status( channel ) ? 1 : 0; } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod_ext ? &mod_ext->mod : NULL ); } return -1; } int set_instrument_mute_status( openmpt_module_ext * mod_ext, int32_t instrument, int mute ) { try { openmpt::interface::check_soundfile( mod_ext ); mod_ext->impl->set_instrument_mute_status( instrument, mute ? true : false ); return 1; } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod_ext ? &mod_ext->mod : NULL ); } return 0; } int get_instrument_mute_status( openmpt_module_ext * mod_ext, int32_t instrument ) { try { openmpt::interface::check_soundfile( mod_ext ); return mod_ext->impl->get_instrument_mute_status( instrument ) ? 1 : 0; } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod_ext ? &mod_ext->mod : NULL ); } return -1; } int32_t play_note( openmpt_module_ext * mod_ext, int32_t instrument, int32_t note, double volume, double panning ) { try { openmpt::interface::check_soundfile( mod_ext ); return mod_ext->impl->play_note( instrument, note, volume, panning ); } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod_ext ? &mod_ext->mod : NULL ); } return -1; } int stop_note( openmpt_module_ext * mod_ext, int32_t channel ) { try { openmpt::interface::check_soundfile( mod_ext ); mod_ext->impl->stop_note( channel ); return 1; } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod_ext ? &mod_ext->mod : NULL ); } return 0; } /* add stuff here */ int openmpt_module_ext_get_interface( openmpt_module_ext * mod_ext, const char * interface_id, void * interface, size_t interface_size ) { try { openmpt::interface::check_soundfile( mod_ext ); openmpt::interface::check_pointer( interface_id ); openmpt::interface::check_pointer( interface ); std::memset( interface, 0, interface_size ); int result = 0; if ( !strcmp( interface_id, "" ) ) { result = 0; } else if ( !strcmp( interface_id, LIBOPENMPT_EXT_C_INTERFACE_PATTERN_VIS ) && ( interface_size == sizeof( openmpt_module_ext_interface_pattern_vis ) ) ) { openmpt_module_ext_interface_pattern_vis * i = static_cast< openmpt_module_ext_interface_pattern_vis * >( interface ); i->get_pattern_row_channel_volume_effect_type = &get_pattern_row_channel_volume_effect_type; i->get_pattern_row_channel_effect_type = &get_pattern_row_channel_effect_type; result = 1; } else if ( !strcmp( interface_id, LIBOPENMPT_EXT_C_INTERFACE_INTERACTIVE ) && ( interface_size == sizeof( openmpt_module_ext_interface_interactive ) ) ) { openmpt_module_ext_interface_interactive * i = static_cast< openmpt_module_ext_interface_interactive * >( interface ); i->set_current_speed = &set_current_speed; i->set_current_tempo = &set_current_tempo; i->set_tempo_factor = &set_tempo_factor; i->get_tempo_factor = &get_tempo_factor; i->set_pitch_factor = &set_pitch_factor; i->get_pitch_factor = &get_pitch_factor; i->set_global_volume = &set_global_volume; i->get_global_volume = &get_global_volume; i->set_channel_volume = &set_channel_volume; i->get_channel_volume = &get_channel_volume; i->set_channel_mute_status = &set_channel_mute_status; i->get_channel_mute_status = &get_channel_mute_status; i->set_instrument_mute_status = &set_instrument_mute_status; i->get_instrument_mute_status = &get_instrument_mute_status; i->play_note = &play_note; i->stop_note = &stop_note; result = 1; /* add stuff here */ } else { result = 0; } return result; } catch ( ... ) { openmpt::report_exception( __FUNCTION__, mod_ext ? &mod_ext->mod : NULL ); } return 0; } } // extern "C" #endif // NO_LIBOPENMPT_C libopenmpt-0.3.6+release.autotools/libopenmpt/libopenmpt_ext_impl.cpp0000644000372100037210000002370513124003512023203 00000000000000/* * libopenmpt_ext_impl.cpp * ----------------------- * Purpose: libopenmpt extensions - implementation * Notes : * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "common/stdafx.h" #include "libopenmpt_internal.h" #include "libopenmpt_ext.hpp" #include "libopenmpt_ext_impl.hpp" #include #include "soundlib/Sndfile.h" using namespace OpenMPT; namespace openmpt { module_ext_impl::module_ext_impl( callback_stream_wrapper stream, std::unique_ptr log, const std::map< std::string, std::string > & ctls ) : module_impl( stream, std::move(log), ctls ) { ctor(); } module_ext_impl::module_ext_impl( std::istream & stream, std::unique_ptr log, const std::map< std::string, std::string > & ctls ) : module_impl( stream, std::move(log), ctls ) { ctor(); } module_ext_impl::module_ext_impl( const std::vector & data, std::unique_ptr log, const std::map< std::string, std::string > & ctls ) : module_impl( data, std::move(log), ctls ) { ctor(); } module_ext_impl::module_ext_impl( const std::vector & data, std::unique_ptr log, const std::map< std::string, std::string > & ctls ) : module_impl( data, std::move(log), ctls ) { ctor(); } module_ext_impl::module_ext_impl( const std::uint8_t * data, std::size_t size, std::unique_ptr log, const std::map< std::string, std::string > & ctls ) : module_impl( data, size, std::move(log), ctls ) { ctor(); } module_ext_impl::module_ext_impl( const char * data, std::size_t size, std::unique_ptr log, const std::map< std::string, std::string > & ctls ) : module_impl( data, size, std::move(log), ctls ) { ctor(); } module_ext_impl::module_ext_impl( const void * data, std::size_t size, std::unique_ptr log, const std::map< std::string, std::string > & ctls ) : module_impl( data, size, std::move(log), ctls ) { ctor(); } void module_ext_impl::ctor() { /* add stuff here */ } module_ext_impl::~module_ext_impl() { /* add stuff here */ } void * module_ext_impl::get_interface( const std::string & interface_id ) { if ( interface_id.empty() ) { return 0; } else if ( interface_id == ext::pattern_vis_id ) { return dynamic_cast< ext::pattern_vis * >( this ); } else if ( interface_id == ext::interactive_id ) { return dynamic_cast< ext::interactive * >( this ); /* add stuff here */ } else { return 0; } } // pattern_vis module_ext_impl::effect_type module_ext_impl::get_pattern_row_channel_volume_effect_type( std::int32_t pattern, std::int32_t row, std::int32_t channel ) const { std::uint8_t byte = get_pattern_row_channel_command( pattern, row, channel, module::command_volumeffect ); switch ( ModCommand::GetVolumeEffectType( byte ) ) { case EFFECT_TYPE_NORMAL : return effect_general; break; case EFFECT_TYPE_GLOBAL : return effect_global ; break; case EFFECT_TYPE_VOLUME : return effect_volume ; break; case EFFECT_TYPE_PANNING: return effect_panning; break; case EFFECT_TYPE_PITCH : return effect_pitch ; break; default: return effect_unknown; break; } } module_ext_impl::effect_type module_ext_impl::get_pattern_row_channel_effect_type( std::int32_t pattern, std::int32_t row, std::int32_t channel ) const { std::uint8_t byte = get_pattern_row_channel_command( pattern, row, channel, module::command_effect ); switch ( ModCommand::GetEffectType( byte ) ) { case EFFECT_TYPE_NORMAL : return effect_general; break; case EFFECT_TYPE_GLOBAL : return effect_global ; break; case EFFECT_TYPE_VOLUME : return effect_volume ; break; case EFFECT_TYPE_PANNING: return effect_panning; break; case EFFECT_TYPE_PITCH : return effect_pitch ; break; default: return effect_unknown; break; } } // interactive void module_ext_impl::set_current_speed( std::int32_t speed ) { if ( speed < 1 || speed > 65535 ) { throw openmpt::exception("invalid tick count"); } m_sndFile->m_PlayState.m_nMusicSpeed = speed; } void module_ext_impl::set_current_tempo( std::int32_t tempo ) { if ( tempo < 32 || tempo > 512 ) { throw openmpt::exception("invalid tempo"); } m_sndFile->m_PlayState.m_nMusicTempo.Set( tempo ); } void module_ext_impl::set_tempo_factor( double factor ) { if ( factor <= 0.0 || factor > 4.0 ) { throw openmpt::exception("invalid tempo factor"); } m_sndFile->m_nTempoFactor = Util::Round( 65536.0 / factor ); m_sndFile->RecalculateSamplesPerTick(); } double module_ext_impl::get_tempo_factor( ) const { return 65536.0 / m_sndFile->m_nTempoFactor; } void module_ext_impl::set_pitch_factor( double factor ) { if ( factor <= 0.0 || factor > 4.0 ) { throw openmpt::exception("invalid pitch factor"); } m_sndFile->m_nFreqFactor = Util::Round( 65536.0 * factor ); m_sndFile->RecalculateSamplesPerTick(); } double module_ext_impl::get_pitch_factor( ) const { return m_sndFile->m_nFreqFactor / 65536.0; } void module_ext_impl::set_global_volume( double volume ) { if ( volume < 0.0 || volume > 1.0 ) { throw openmpt::exception("invalid global volume"); } m_sndFile->m_PlayState.m_nGlobalVolume = Util::Round( volume * MAX_GLOBAL_VOLUME ); } double module_ext_impl::get_global_volume( ) const { return m_sndFile->m_PlayState.m_nGlobalVolume / static_cast( MAX_GLOBAL_VOLUME ); } void module_ext_impl::set_channel_volume( std::int32_t channel, double volume ) { if ( channel < 0 || channel >= get_num_channels() ) { throw openmpt::exception("invalid channel"); } if ( volume < 0.0 || volume > 1.0 ) { throw openmpt::exception("invalid global volume"); } m_sndFile->m_PlayState.Chn[channel].nGlobalVol = Util::Round(volume * 64.0); } double module_ext_impl::get_channel_volume( std::int32_t channel ) const { if ( channel < 0 || channel >= get_num_channels() ) { throw openmpt::exception("invalid channel"); } return m_sndFile->m_PlayState.Chn[channel].nGlobalVol / 64.0; } void module_ext_impl::set_channel_mute_status( std::int32_t channel, bool mute ) { if ( channel < 0 || channel >= get_num_channels() ) { throw openmpt::exception("invalid channel"); } m_sndFile->ChnSettings[channel].dwFlags.set( CHN_MUTE | CHN_SYNCMUTE , mute ); m_sndFile->m_PlayState.Chn[channel].dwFlags.set( CHN_MUTE | CHN_SYNCMUTE , mute ); // Also update NNA channels for ( CHANNELINDEX i = m_sndFile->GetNumChannels(); i < MAX_CHANNELS; i++) { if ( m_sndFile->m_PlayState.Chn[i].nMasterChn == channel + 1) { m_sndFile->m_PlayState.Chn[i].dwFlags.set( CHN_MUTE | CHN_SYNCMUTE, mute ); } } } bool module_ext_impl::get_channel_mute_status( std::int32_t channel ) const { if ( channel < 0 || channel >= get_num_channels() ) { throw openmpt::exception("invalid channel"); } return m_sndFile->m_PlayState.Chn[channel].dwFlags[CHN_MUTE]; } void module_ext_impl::set_instrument_mute_status( std::int32_t instrument, bool mute ) { const bool instrument_mode = get_num_instruments() != 0; const int32_t max_instrument = instrument_mode ? get_num_instruments() : get_num_samples(); if ( instrument < 0 || instrument >= max_instrument ) { throw openmpt::exception("invalid instrument"); } if ( instrument_mode ) { if ( m_sndFile->Instruments[instrument + 1] != nullptr ) { m_sndFile->Instruments[instrument + 1]->dwFlags.set( INS_MUTE, mute ); } } else { m_sndFile->GetSample( static_cast( instrument + 1 ) ).uFlags.set( CHN_MUTE, mute ) ; } } bool module_ext_impl::get_instrument_mute_status( std::int32_t instrument ) const { const bool instrument_mode = get_num_instruments() != 0; const int32_t max_instrument = instrument_mode ? get_num_instruments() : get_num_samples(); if ( instrument < 0 || instrument >= max_instrument ) { throw openmpt::exception("invalid instrument"); } if ( instrument_mode ) { if ( m_sndFile->Instruments[instrument + 1] != nullptr ) { return m_sndFile->Instruments[instrument + 1]->dwFlags[INS_MUTE]; } return true; } else { return m_sndFile->GetSample( static_cast( instrument + 1 ) ).uFlags[CHN_MUTE]; } } std::int32_t module_ext_impl::play_note( std::int32_t instrument, std::int32_t note, double volume, double panning ) { const bool instrument_mode = get_num_instruments() != 0; const int32_t max_instrument = instrument_mode ? get_num_instruments() : get_num_samples(); if ( instrument < 0 || instrument >= max_instrument ) { throw openmpt::exception("invalid instrument"); } note += NOTE_MIN; if ( note < NOTE_MIN || note > NOTE_MAX ) { throw openmpt::exception("invalid note"); } // Find a free channel CHANNELINDEX free_channel = MAX_CHANNELS - 1; // Search for available channel for(CHANNELINDEX i = MAX_CHANNELS - 1; i >= get_num_channels(); i--) { const ModChannel &chn = m_sndFile->m_PlayState.Chn[i]; if ( chn.nLength == 0 ) { free_channel = i; break; } else if ( chn.dwFlags[CHN_NOTEFADE] ) { // We can probably still do better than this. free_channel = i; } } ModChannel &chn = m_sndFile->m_PlayState.Chn[free_channel]; chn.Reset(ModChannel::resetTotal, *m_sndFile, CHANNELINDEX_INVALID); chn.nMasterChn = 0; // remove NNA association chn.nNewNote = chn.nLastNote = static_cast(note); chn.ResetEnvelopes(); m_sndFile->InstrumentChange(&chn, instrument + 1); chn.nFadeOutVol = 0x10000; m_sndFile->NoteChange(&chn, note, false, true, true); chn.nPan = Util::Round( Clamp( panning * 128.0, -128.0, 128.0 ) + 128.0 ); chn.nVolume = Util::Round( Clamp( volume * 256.0, 0.0, 256.0 ) ); return free_channel; } void module_ext_impl::stop_note( std::int32_t channel ) { if ( channel < 0 || channel >= MAX_CHANNELS ) { throw openmpt::exception("invalid channel"); } ModChannel &chn = m_sndFile->m_PlayState.Chn[channel]; chn.nLength = 0; chn.pCurrentSample = nullptr; } /* add stuff here */ } // namespace openmpt libopenmpt-0.3.6+release.autotools/libopenmpt/libopenmpt_cxx.cpp0000644000372100037210000003526113157732541022205 00000000000000/* * libopenmpt_cxx.cpp * ------------------ * Purpose: libopenmpt C++ interface implementation * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "BuildSettings.h" #include "libopenmpt_internal.h" #include "libopenmpt.hpp" #include "libopenmpt_ext.hpp" #include "libopenmpt_impl.hpp" #include "libopenmpt_ext_impl.hpp" #include #include #include #include namespace openmpt { exception::exception( const std::string & text_ ) noexcept : std::exception() , text(0) { text = static_cast( std::malloc( text_.length() + 1 ) ); if ( text ) { std::memcpy( text, text_.c_str(), text_.length() + 1 ); } } exception::exception( const exception & other ) noexcept : std::exception() , text(0) { const char * const text_ = ( other.what() ? other.what() : "" ); text = static_cast( std::malloc( std::strlen( text_ ) + 1 ) ); if ( text ) { std::memcpy( text, text_, std::strlen( text_ ) + 1 ); } } exception::exception( exception && other ) noexcept : std::exception() , text(0) { text = std::move( other.text ); other.text = 0; } exception & exception::operator = ( const exception & other ) noexcept { if ( this == &other ) { return *this; } if ( text ) { std::free( text ); text = 0; } const char * const text_ = ( other.what() ? other.what() : "" ); text = static_cast( std::malloc( std::strlen( text_ ) + 1 ) ); if ( text ) { std::memcpy( text, text_, std::strlen( text_ ) + 1 ); } return *this; } exception & exception::operator = ( exception && other ) noexcept { if ( this == &other ) { return *this; } if ( text ) { std::free( text ); text = 0; } text = std::move( other.text ); other.text = 0; return *this; } exception::~exception() noexcept { if ( text ) { std::free( text ); text = 0; } } const char * exception::what() const noexcept { if ( text ) { return text; } else { return "out of memory"; } } std::uint32_t get_library_version() { return openmpt::version::get_library_version(); } std::uint32_t get_core_version() { return openmpt::version::get_core_version(); } namespace string { std::string get( const std::string & key ) { return openmpt::version::get_string( key ); } } // namespace string } // namespace openmpt #ifndef NO_LIBOPENMPT_CXX namespace openmpt { std::vector get_supported_extensions() { return openmpt::module_impl::get_supported_extensions(); } bool is_extension_supported( const std::string & extension ) { return openmpt::module_impl::is_extension_supported( extension ); } double could_open_probability( std::istream & stream, double effort, std::ostream & log ) { return openmpt::module_impl::could_open_probability( stream, effort, openmpt::helper::make_unique( log ) ); } double could_open_propability( std::istream & stream, double effort, std::ostream & log ) { return openmpt::module_impl::could_open_probability( stream, effort, openmpt::helper::make_unique( log ) ); } std::size_t probe_file_header_get_recommended_size() { return openmpt::module_impl::probe_file_header_get_recommended_size(); } int probe_file_header( std::uint64_t flags, const std::uint8_t * data, std::size_t size, std::uint64_t filesize ) { return openmpt::module_impl::probe_file_header( flags, data, size, filesize ); } int probe_file_header( std::uint64_t flags, const std::uint8_t * data, std::size_t size ) { return openmpt::module_impl::probe_file_header( flags, data, size ); } int probe_file_header( std::uint64_t flags, std::istream & stream ) { return openmpt::module_impl::probe_file_header( flags, stream ); } #if defined(_MSC_VER) #pragma warning(push) #pragma warning(disable:4702) // unreachable code #endif // _MSC_VER module::module( const module & ) { throw exception("openmpt::module is non-copyable"); } void module::operator = ( const module & ) { throw exception("openmpt::module is non-copyable"); } #if defined(_MSC_VER) #pragma warning(pop) #endif // _MSC_VER module::module() : impl(0) { return; } void module::set_impl( module_impl * i ) { impl = i; } module::module( std::istream & stream, std::ostream & log, const std::map< std::string, std::string > & ctls ) : impl(0) { impl = new module_impl( stream, openmpt::helper::make_unique( log ), ctls ); } module::module( const std::vector & data, std::ostream & log, const std::map< std::string, std::string > & ctls ) : impl(0) { impl = new module_impl( data, openmpt::helper::make_unique( log ), ctls ); } module::module( const std::uint8_t * beg, const std::uint8_t * end, std::ostream & log, const std::map< std::string, std::string > & ctls ) : impl(0) { impl = new module_impl( beg, end - beg, openmpt::helper::make_unique( log ), ctls ); } module::module( const std::uint8_t * data, std::size_t size, std::ostream & log, const std::map< std::string, std::string > & ctls ) : impl(0) { impl = new module_impl( data, size, openmpt::helper::make_unique( log ), ctls ); } module::module( const std::vector & data, std::ostream & log, const std::map< std::string, std::string > & ctls ) : impl(0) { impl = new module_impl( data, openmpt::helper::make_unique( log ), ctls ); } module::module( const char * beg, const char * end, std::ostream & log, const std::map< std::string, std::string > & ctls ) : impl(0) { impl = new module_impl( beg, end - beg, openmpt::helper::make_unique( log ), ctls ); } module::module( const char * data, std::size_t size, std::ostream & log, const std::map< std::string, std::string > & ctls ) : impl(0) { impl = new module_impl( data, size, openmpt::helper::make_unique( log ), ctls ); } module::module( const void * data, std::size_t size, std::ostream & log, const std::map< std::string, std::string > & ctls ) : impl(0) { impl = new module_impl( data, size, openmpt::helper::make_unique( log ), ctls ); } module::~module() { delete impl; impl = 0; } void module::select_subsong( std::int32_t subsong ) { impl->select_subsong( subsong ); } std::int32_t module::get_selected_subsong() const { return impl->get_selected_subsong(); } void module::set_repeat_count( std::int32_t repeat_count ) { impl->set_repeat_count( repeat_count ); } std::int32_t module::get_repeat_count() const { return impl->get_repeat_count(); } double module::get_duration_seconds() const { return impl->get_duration_seconds(); } double module::set_position_seconds( double seconds ) { return impl->set_position_seconds( seconds ); } double module::get_position_seconds() const { return impl->get_position_seconds(); } double module::set_position_order_row( std::int32_t order, std::int32_t row ) { return impl->set_position_order_row( order, row ); } std::int32_t module::get_render_param( int param ) const { return impl->get_render_param( param ); } void module::set_render_param( int param, std::int32_t value ) { impl->set_render_param( param, value ); } std::size_t module::read( std::int32_t samplerate, std::size_t count, std::int16_t * mono ) { return impl->read( samplerate, count, mono ); } std::size_t module::read( std::int32_t samplerate, std::size_t count, std::int16_t * left, std::int16_t * right ) { return impl->read( samplerate, count, left, right ); } std::size_t module::read( std::int32_t samplerate, std::size_t count, std::int16_t * left, std::int16_t * right, std::int16_t * rear_left, std::int16_t * rear_right ) { return impl->read( samplerate, count, left, right, rear_left, rear_right ); } std::size_t module::read( std::int32_t samplerate, std::size_t count, float * mono ) { return impl->read( samplerate, count, mono ); } std::size_t module::read( std::int32_t samplerate, std::size_t count, float * left, float * right ) { return impl->read( samplerate, count, left, right ); } std::size_t module::read( std::int32_t samplerate, std::size_t count, float * left, float * right, float * rear_left, float * rear_right ) { return impl->read( samplerate, count, left, right, rear_left, rear_right ); } std::size_t module::read_interleaved_stereo( std::int32_t samplerate, std::size_t count, std::int16_t * interleaved_stereo ) { return impl->read_interleaved_stereo( samplerate, count, interleaved_stereo ); } std::size_t module::read_interleaved_quad( std::int32_t samplerate, std::size_t count, std::int16_t * interleaved_quad ) { return impl->read_interleaved_quad( samplerate, count, interleaved_quad ); } std::size_t module::read_interleaved_stereo( std::int32_t samplerate, std::size_t count, float * interleaved_stereo ) { return impl->read_interleaved_stereo( samplerate, count, interleaved_stereo ); } std::size_t module::read_interleaved_quad( std::int32_t samplerate, std::size_t count, float * interleaved_quad ) { return impl->read_interleaved_quad( samplerate, count, interleaved_quad ); } std::vector module::get_metadata_keys() const { return impl->get_metadata_keys(); } std::string module::get_metadata( const std::string & key ) const { return impl->get_metadata( key ); } std::int32_t module::get_current_speed() const { return impl->get_current_speed(); } std::int32_t module::get_current_tempo() const { return impl->get_current_tempo(); } std::int32_t module::get_current_order() const { return impl->get_current_order(); } std::int32_t module::get_current_pattern() const { return impl->get_current_pattern(); } std::int32_t module::get_current_row() const { return impl->get_current_row(); } std::int32_t module::get_current_playing_channels() const { return impl->get_current_playing_channels(); } float module::get_current_channel_vu_mono( std::int32_t channel ) const { return impl->get_current_channel_vu_mono( channel ); } float module::get_current_channel_vu_left( std::int32_t channel ) const { return impl->get_current_channel_vu_left( channel ); } float module::get_current_channel_vu_right( std::int32_t channel ) const { return impl->get_current_channel_vu_right( channel ); } float module::get_current_channel_vu_rear_left( std::int32_t channel ) const { return impl->get_current_channel_vu_rear_left( channel ); } float module::get_current_channel_vu_rear_right( std::int32_t channel ) const { return impl->get_current_channel_vu_rear_right( channel ); } std::int32_t module::get_num_subsongs() const { return impl->get_num_subsongs(); } std::int32_t module::get_num_channels() const { return impl->get_num_channels(); } std::int32_t module::get_num_orders() const { return impl->get_num_orders(); } std::int32_t module::get_num_patterns() const { return impl->get_num_patterns(); } std::int32_t module::get_num_instruments() const { return impl->get_num_instruments(); } std::int32_t module::get_num_samples() const { return impl->get_num_samples(); } std::vector module::get_subsong_names() const { return impl->get_subsong_names(); } std::vector module::get_channel_names() const { return impl->get_channel_names(); } std::vector module::get_order_names() const { return impl->get_order_names(); } std::vector module::get_pattern_names() const { return impl->get_pattern_names(); } std::vector module::get_instrument_names() const { return impl->get_instrument_names(); } std::vector module::get_sample_names() const { return impl->get_sample_names(); } std::int32_t module::get_order_pattern( std::int32_t order ) const { return impl->get_order_pattern( order ); } std::int32_t module::get_pattern_num_rows( std::int32_t pattern ) const { return impl->get_pattern_num_rows( pattern ); } std::uint8_t module::get_pattern_row_channel_command( std::int32_t pattern, std::int32_t row, std::int32_t channel, int command ) const { return impl->get_pattern_row_channel_command( pattern, row, channel, command ); } std::string module::format_pattern_row_channel_command( std::int32_t pattern, std::int32_t row, std::int32_t channel, int command ) const { return impl->format_pattern_row_channel_command( pattern, row, channel, command ); } std::string module::highlight_pattern_row_channel_command( std::int32_t pattern, std::int32_t row, std::int32_t channel, int command ) const { return impl->highlight_pattern_row_channel_command( pattern, row, channel, command ); } std::string module::format_pattern_row_channel( std::int32_t pattern, std::int32_t row, std::int32_t channel, std::size_t width, bool pad ) const { return impl->format_pattern_row_channel( pattern, row, channel, width, pad ); } std::string module::highlight_pattern_row_channel( std::int32_t pattern, std::int32_t row, std::int32_t channel, std::size_t width, bool pad ) const { return impl->highlight_pattern_row_channel( pattern, row, channel, width, pad ); } std::vector module::get_ctls() const { return impl->get_ctls(); } std::string module::ctl_get( const std::string & ctl ) const { return impl->ctl_get( ctl ); } void module::ctl_set( const std::string & ctl, const std::string & value ) { impl->ctl_set( ctl, value ); } module_ext::module_ext( std::istream & stream, std::ostream & log, const std::map< std::string, std::string > & ctls ) : ext_impl(0) { ext_impl = new module_ext_impl( stream, openmpt::helper::make_unique( log ), ctls ); set_impl( ext_impl ); } module_ext::module_ext( const std::vector & data, std::ostream & log, const std::map< std::string, std::string > & ctls ) : ext_impl(0) { ext_impl = new module_ext_impl( data, openmpt::helper::make_unique( log ), ctls ); set_impl( ext_impl ); } module_ext::module_ext( const char * data, std::size_t size, std::ostream & log, const std::map< std::string, std::string > & ctls ) : ext_impl(0) { ext_impl = new module_ext_impl( data, size, openmpt::helper::make_unique( log ), ctls ); set_impl( ext_impl ); } module_ext::module_ext( const void * data, std::size_t size, std::ostream & log, const std::map< std::string, std::string > & ctls ) : ext_impl(0) { ext_impl = new module_ext_impl( data, size, openmpt::helper::make_unique( log ), ctls ); set_impl( ext_impl ); } module_ext::~module_ext() { set_impl( 0 ); delete ext_impl; ext_impl = 0; } #if defined(_MSC_VER) #pragma warning(push) #pragma warning(disable:4702) // unreachable code #endif // _MSC_VER module_ext::module_ext( const module_ext & other ) : module(other) { throw std::runtime_error("openmpt::module_ext is non-copyable"); } void module_ext::operator = ( const module_ext & ) { throw std::runtime_error("openmpt::module_ext is non-copyable"); } #if defined(_MSC_VER) #pragma warning(pop) #endif // _MSC_VER void * module_ext::get_interface( const std::string & interface_id ) { return ext_impl->get_interface( interface_id ); } } // namespace openmpt #endif // NO_LIBOPENMPT_CXX libopenmpt-0.3.6+release.autotools/libopenmpt/libopenmpt.h0000644000372100037210000024542013233134327020761 00000000000000/* * libopenmpt.h * ------------ * Purpose: libopenmpt public c interface * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #ifndef LIBOPENMPT_H #define LIBOPENMPT_H #include "libopenmpt_config.h" #include #include /*! * \page libopenmpt_c_overview C API * * \section libopenmpt_c_error Error Handling * * - Functions with no return value in the corresponding C++ API return 0 on * failure and 1 on success. * - Functions that return a string in the corresponding C++ API return a * dynamically allocated const char *. In case of failure or memory allocation * failure, a NULL pointer is returned. * - Functions that return integer values signal error condition by returning * an invalid value (-1 in most cases, 0 in some cases). * - All functions that work on an \ref openmpt_module object will call an * \ref openmpt_error_func and depending on the value returned by this function * log the error code and/xor/or store it inside the openmpt_module object. * Stored error codes can be accessed with the openmpt_module_error_get_last() * and openmpt_module_error_get_last_message(). Stored errors will not get * cleared automatically and should be reset with openmpt_module_error_clear(). * - Some functions not directly related to an \ref openmpt_module object take * an explicit \ref openmpt_error_func error function callback and a pointer to * an int and behave analog to the functions working on an \ref openmpt_module * object. * * \section libopenmpt_c_strings Strings * * - All strings returned from libopenmpt are encoded in UTF-8. * - All strings passed to libopenmpt should also be encoded in UTF-8. * Behaviour in case of invalid UTF-8 is unspecified. * - libopenmpt does not enforce or expect any particular Unicode * normalization form. * - All strings returned from libopenmpt are dynamically allocated and must * be freed with openmpt_free_string(). Do NOT use the C standard library * free() for libopenmpt strings as that would make your code invalid on * windows when dynamically linking against libopenmpt which itself statically * links to the C runtime. * - All strings passed to libopenmpt are copied. No ownership is assumed or * transferred. * * \section libopenmpt_c_fileio File I/O * * libopenmpt can use 3 different strategies for file I/O. * * - openmpt_module_create_from_memory2() will load the module from the provided * memory buffer, which will require loading all data upfront by the library * caller. * - openmpt_module_create2() with a seekable stream will load the module via * callbacks to the stream interface. libopenmpt will not implement an * additional buffering layer in this case which means the callbacks are assumed * to be performant even with small i/o sizes. * - openmpt_module_create2() with an unseekable stream will load the module via * callbacks to the stream interface. libopempt will make an internal copy as * it goes along, and sometimes have to pre-cache the whole file in case it * needs to know the complete file size. This strategy is intended to be used * if the file is located on a high latency network. * * | create function | speed | memory consumption | * | ----------------------------------------------: | :----: | :----------------: | * | openmpt_module_create_from_memory2() |

fast

|

medium

| * | openmpt_module_create2() with seekable stream |

slow

|

low

| * | openmpt_module_create2() with unseekable stream |

medium

|

high

| * * In all cases, the data or stream passed to the create function is no longer * needed after the openmpt_module has been created and can be freed by the * caller. * * \section libopenmpt_c_outputformat Output Format * * libopenmpt supports a wide range of PCM output formats: * [8000..192000]/[mono|stereo|quad]/[f32|i16]. * * Unless you have some very specific requirements demanding a particular aspect * of the output format, you should always prefer 48000/stereo/f32 as the * libopenmpt PCM format. * * - Please prefer 48000Hz unless the user explicitly demands something else. * Practically all audio equipment and file formats use 48000Hz nowadays. * - Practically all module formats are made for stereo output. Mono will not * give you any measurable speed improvements and can trivially be obtained from * the stereo output anyway. Quad is not expected by almost all modules and even * if they do use surround effects, they expect the effects to be mixed to * stereo. * - Floating point output provides headroom instead of hard clipping if the * module is louder than 0dBFs, will give you a better signal-to-noise ratio * than int16 output, and avoid the need to apply an additional dithering to the * output by libopenmpt. Unless your platform has no floating point unit at all, * floating point will thus also be slightly faster. * * \section libopenmpt_c_threads libopenmpt in multi-threaded environments * * - libopenmpt is thread-aware. * - Individual libopenmpt objects are not thread-safe. * - libopenmpt itself does not spawn any user-visible threads but may spawn * threads for internal use. * - You must ensure to only ever access a particular libopenmpt object from a * single thread at a time. * - Consecutive accesses can happen from different threads. * - Different objects can be accessed concurrently from different threads. * * \section libopenmpt_c_staticlinking Statically linking to libopenmpt * * libopenmpt is implemented in C++. This implies that linking to libopenmpt * statically requires linking to the C++ runtime and standard library. The * **highly preferred and recommended** way to do this is by using the C++ * compiler instead of the platform linker to do the linking. This will do all * necessary things that are C++ specific (in particular, it will pull in the * appropriate runtime and/or library). If for whatever reason it is not * possible to use the C++ compiler for statically linking against libopenmpt, * the libopenmpt build system can list the required libraries in the pkg-config * file `libopenmpt.pc`. However, there is no reliable way to determine the name * of the required library or libraries from within the build system. The * libopenmpt autotools `configure` and plain `Makefile` honor the custom * variable `CXXSTDLIB_PCLIBSPRIVATE` which serves the sole purpose of listing * the standard library (or libraries) required for static linking. The contents * of this variable will be put in `libopenmpt.pc` `Libs.private` and used for * nothing else. * * This problem is inherent to libraries implemented in C++ that can also be used * without a C++ compiler. Other libraries try to solve that by listing * `-lstdc++` unconditionally in `Libs.private`. However, that will break * platforms that use a different C++ standard library (in particular FreeBSD). * * See https://lists.freedesktop.org/archives/pkg-config/2016-August/001055.html . * * Dymically linking to libopenmpt does not require anything special and will * work as usual (and exactly as done for libraries implemented in C). * * Note: This section does not apply when using Microsoft Visual Studio or * Andriod NDK ndk-build build systems. * * \section libopenmpt_c_detailed Detailed documentation * * \ref libopenmpt_c * * In case a function is not documented here, you might want to look at the * \ref libopenmpt_cpp documentation. The C and C++ APIs are kept semantically * as close as possible. * * \section libopenmpt_c_examples Examples * * \subsection libopenmpt_c_example_unsafe Unsafe, simplified example without any error checking to get a first idea of the API * \include libopenmpt_example_c_unsafe.c * \subsection libopenmpt_c_example_file FILE* * \include libopenmpt_example_c.c * \subsection libopenmpt_c_example_inmemory in memory * \include libopenmpt_example_c_mem.c * \subsection libopenmpt_c_example_stdout reading FILE* and writing PCM data to STDOUT (usable without PortAudio) * \include libopenmpt_example_c_stdout.c * */ /*! \defgroup libopenmpt_c libopenmpt C */ /*! \addtogroup libopenmpt_c @{ */ #ifdef __cplusplus extern "C" { #endif /*! \brief Get the libopenmpt version number * * Returns the libopenmpt version number. * \return The value represents (major << 24 + minor << 16 + patch << 0). * \remarks libopenmpt < 0.3.0-pre used the following scheme: (major << 24 + minor << 16 + revision). */ LIBOPENMPT_API uint32_t openmpt_get_library_version(void); /*! \brief Get the core version number * * Return the OpenMPT core version number. * \return The value represents (majormajor << 24 + major << 16 + minor << 8 + minorminor). */ LIBOPENMPT_API uint32_t openmpt_get_core_version(void); /*! Return a verbose library version string from openmpt_get_string(). \deprecated Please use \code "library_version" \endcode directly. */ #define OPENMPT_STRING_LIBRARY_VERSION LIBOPENMPT_DEPRECATED_STRING( "library_version" ) /*! Return a verbose library features string from openmpt_get_string(). \deprecated Please use \code "library_features" \endcode directly. */ #define OPENMPT_STRING_LIBRARY_FEATURES LIBOPENMPT_DEPRECATED_STRING( "library_features" ) /*! Return a verbose OpenMPT core version string from openmpt_get_string(). \deprecated Please use \code "core_version" \endcode directly. */ #define OPENMPT_STRING_CORE_VERSION LIBOPENMPT_DEPRECATED_STRING( "core_version" ) /*! Return information about the current build (e.g. the build date or compiler used) from openmpt_get_string(). \deprecated Please use \code "build" \endcode directly. */ #define OPENMPT_STRING_BUILD LIBOPENMPT_DEPRECATED_STRING( "build" ) /*! Return all contributors from openmpt_get_string(). \deprecated Please use \code "credits" \endcode directly. */ #define OPENMPT_STRING_CREDITS LIBOPENMPT_DEPRECATED_STRING( "credits" ) /*! Return contact information about libopenmpt from openmpt_get_string(). \deprecated Please use \code "contact" \endcode directly. */ #define OPENMPT_STRING_CONTACT LIBOPENMPT_DEPRECATED_STRING( "contact" ) /*! Return the libopenmpt license from openmpt_get_string(). \deprecated Please use \code "license" \endcode directly. */ #define OPENMPT_STRING_LICENSE LIBOPENMPT_DEPRECATED_STRING( "license" ) /*! \brief Free a string returned by libopenmpt * * Frees any string that got returned by libopenmpt. */ LIBOPENMPT_API void openmpt_free_string( const char * str ); /*! \brief Get library related metadata. * * \param key Key to query. * Possible keys are: * - "library_version": verbose library version string * - "library_version_is_release": "1" if the version is an officially released version * - "library_features": verbose library features string * - "core_version": verbose OpenMPT core version string * - "source_url": original source code URL * - "source_date": original source code date * - "source_revision": original source code revision * - "source_is_modified": "1" if the original source has been modified * - "source_has_mixed_revisions": "1" if the original source has been compiled from different various revision * - "source_is_package": "1" if the original source has been obtained from a source pacakge instead of source code version control * - "build": information about the current build (e.g. the build date or compiler used) * - "build_compiler": information about the compiler used to build libopenmpt * - "credits": all contributors * - "contact": contact information about libopenmpt * - "license": the libopenmpt license * - "url": libopenmpt website URL * - "support_forum_url": libopenmpt support and discussions forum URL * - "bugtracker_url": libopenmpt bug and issue tracker URL * \return A (possibly multi-line) string containing the queried information. If no information is available, the string is empty. */ LIBOPENMPT_API const char * openmpt_get_string( const char * key ); /*! \brief Get a list of supported file extensions * * \return The semicolon-separated list of extensions supported by this libopenmpt build. The extensions are returned lower-case without a leading dot. */ LIBOPENMPT_API const char * openmpt_get_supported_extensions(void); /*! \brief Query whether a file extension is supported * * \param extension file extension to query without a leading dot. The case is ignored. * \return 1 if the extension is supported by libopenmpt, 0 otherwise. */ LIBOPENMPT_API int openmpt_is_extension_supported( const char * extension ); /*! Seek to the given offset relative to the beginning of the file. */ #define OPENMPT_STREAM_SEEK_SET 0 /*! Seek to the given offset relative to the current position in the file. */ #define OPENMPT_STREAM_SEEK_CUR 1 /*! Seek to the given offset relative to the end of the file. */ #define OPENMPT_STREAM_SEEK_END 2 /*! \brief Read bytes from stream * * Read bytes data from stream to dst. * \param stream Stream to read data from * \param dst Target where to copy data. * \param bytes Number of bytes to read. * \return Number of bytes actually read and written to dst. * \retval 0 End of stream or error. * \remarks Short reads are allowed as long as they return at least 1 byte if EOF is not reached. */ typedef size_t (*openmpt_stream_read_func)( void * stream, void * dst, size_t bytes ); /*! \brief Seek stream position * * Seek to stream position offset at whence. * \param stream Stream to operate on. * \param offset Offset to seek to. * \param whence OPENMPT_STREAM_SEEK_SET, OPENMPT_STREAM_SEEK_CUR, OPENMPT_STREAM_SEEK_END. See C89 documentation. * \return Returns 0 on success. * \retval 0 Success. * \retval -1 Failure. Position does not get updated. * \remarks libopenmpt will not try to seek beyond the file size, thus it is not important whether you allow for virtual positioning after the file end, or return an error in that case. The position equal to the file size needs to be seekable to. */ typedef int (*openmpt_stream_seek_func)( void * stream, int64_t offset, int whence ); /*! \brief Tell stream position * * Tell position of stream. * \param stream Stream to operate on. * \return Current position in stream. * \retval -1 Failure. */ typedef int64_t (*openmpt_stream_tell_func)( void * stream ); /*! \brief Stream callbacks * * Stream callbacks used by libopenmpt for stream operations. */ typedef struct openmpt_stream_callbacks { /*! \brief Read callback. * * \sa openmpt_stream_read_func */ openmpt_stream_read_func read; /*! \brief Seek callback. * * Seek callback can be NULL if seeking is not supported. * \sa openmpt_stream_seek_func */ openmpt_stream_seek_func seek; /*! \brief Tell callback. * * Tell callback can be NULL if seeking is not supported. * \sa openmpt_stream_tell_func */ openmpt_stream_tell_func tell; } openmpt_stream_callbacks; /*! \brief Logging function * * \param message UTF-8 encoded log message. * \param user User context that was passed to openmpt_module_create2(), openmpt_module_create_from_memory2() or openmpt_could_open_probability2(). */ typedef void (*openmpt_log_func)( const char * message, void * user ); /*! \brief Default logging function * * Default logging function that logs anything to stderr. */ LIBOPENMPT_API void openmpt_log_func_default( const char * message, void * user ); /*! \brief Silent logging function * * Silent logging function that throws any log message away. */ LIBOPENMPT_API void openmpt_log_func_silent( const char * message, void * user ); /*! No error. \since 0.3.0 */ #define OPENMPT_ERROR_OK 0 /*! Lowest value libopenmpt will use for any of its own error codes. \since 0.3.0 */ #define OPENMPT_ERROR_BASE 256 /*! Unknown internal error. \since 0.3.0 */ #define OPENMPT_ERROR_UNKNOWN ( OPENMPT_ERROR_BASE + 1 ) /*! Unknown internal C++ exception. \since 0.3.0 */ #define OPENMPT_ERROR_EXCEPTION ( OPENMPT_ERROR_BASE + 11 ) /*! Out of memory. \since 0.3.0 */ #define OPENMPT_ERROR_OUT_OF_MEMORY ( OPENMPT_ERROR_BASE + 21 ) /*! Runtime error. \since 0.3.0 */ #define OPENMPT_ERROR_RUNTIME ( OPENMPT_ERROR_BASE + 30 ) /*! Range error. \since 0.3.0 */ #define OPENMPT_ERROR_RANGE ( OPENMPT_ERROR_BASE + 31 ) /*! Arithmetic overflow. \since 0.3.0 */ #define OPENMPT_ERROR_OVERFLOW ( OPENMPT_ERROR_BASE + 32 ) /*! Arithmetic underflow. \since 0.3.0 */ #define OPENMPT_ERROR_UNDERFLOW ( OPENMPT_ERROR_BASE + 33 ) /*! Logic error. \since 0.3.0 */ #define OPENMPT_ERROR_LOGIC ( OPENMPT_ERROR_BASE + 40 ) /*! Value domain error. \since 0.3.0 */ #define OPENMPT_ERROR_DOMAIN ( OPENMPT_ERROR_BASE + 41 ) /*! Maximum supported size exceeded. \since 0.3.0 */ #define OPENMPT_ERROR_LENGTH ( OPENMPT_ERROR_BASE + 42 ) /*! Argument out of range. \since 0.3.0 */ #define OPENMPT_ERROR_OUT_OF_RANGE ( OPENMPT_ERROR_BASE + 43 ) /*! Invalid argument. \since 0.3.0 */ #define OPENMPT_ERROR_INVALID_ARGUMENT ( OPENMPT_ERROR_BASE + 44 ) /*! General libopenmpt error. \since 0.3.0 */ #define OPENMPT_ERROR_GENERAL ( OPENMPT_ERROR_BASE + 101 ) /*! openmpt_module * is invalid. \since 0.3.0 */ #define OPENMPT_ERROR_INVALID_MODULE_POINTER ( OPENMPT_ERROR_BASE + 102 ) /*! NULL pointer argument. \since 0.3.0 */ #define OPENMPT_ERROR_ARGUMENT_NULL_POINTER ( OPENMPT_ERROR_BASE + 103 ) /*! \brief Check whether the error is transient * * Checks whether an error code represents a transient error which may not occur again in a later try if for example memory has been freed up after an out-of-memory error. * \param error Error code. * \retval 0 Error is not transient. * \retval 1 Error is transient. * \sa OPENMPT_ERROR_OUT_OF_MEMORY * \since 0.3.0 */ LIBOPENMPT_API int openmpt_error_is_transient( int error ); /*! \brief Convert error code to text * * Converts an error code into a text string describing the error. * \param error Error code. * \return Allocated string describing the error. * \retval NULL Not enough memory to allocate the string. * \since 0.3.0 */ LIBOPENMPT_API const char * openmpt_error_string( int error ); /*! Do not log or store the error. \since 0.3.0 */ #define OPENMPT_ERROR_FUNC_RESULT_NONE 0 /*! Log the error. \since 0.3.0 */ #define OPENMPT_ERROR_FUNC_RESULT_LOG ( 1 << 0 ) /*! Store the error. \since 0.3.0 */ #define OPENMPT_ERROR_FUNC_RESULT_STORE ( 1 << 1 ) /*! Log and store the error. \since 0.3.0 */ #define OPENMPT_ERROR_FUNC_RESULT_DEFAULT ( OPENMPT_ERROR_FUNC_RESULT_LOG | OPENMPT_ERROR_FUNC_RESULT_STORE ) /*! \brief Error function * * \param error Error code. * \param user User context that was passed to openmpt_module_create2(), openmpt_module_create_from_memory2() or openmpt_could_open_probability2(). * \return Mask of OPENMPT_ERROR_FUNC_RESULT_LOG and OPENMPT_ERROR_FUNC_RESULT_STORE. * \retval OPENMPT_ERROR_FUNC_RESULT_NONE Do not log or store the error. * \retval OPENMPT_ERROR_FUNC_RESULT_LOG Log the error. * \retval OPENMPT_ERROR_FUNC_RESULT_STORE Store the error. * \retval OPENMPT_ERROR_FUNC_RESULT_DEFAULT Log and store the error. * \sa OPENMPT_ERROR_FUNC_RESULT_NONE * \sa OPENMPT_ERROR_FUNC_RESULT_LOG * \sa OPENMPT_ERROR_FUNC_RESULT_STORE * \sa OPENMPT_ERROR_FUNC_RESULT_DEFAULT * \sa openmpt_error_func_default * \sa openmpt_error_func_log * \sa openmpt_error_func_store * \sa openmpt_error_func_ignore * \sa openmpt_error_func_errno * \since 0.3.0 */ typedef int (*openmpt_error_func)( int error, void * user ); /*! \brief Default error function * * Causes all errors to be logged and stored. * \param error Error code. * \param user Ignored. * \retval OPENMPT_ERROR_FUNC_RESULT_DEFAULT Always. * \since 0.3.0 */ LIBOPENMPT_API int openmpt_error_func_default( int error, void * user ); /*! \brief Log error function * * Causes all errors to be logged. * \param error Error code. * \param user Ignored. * \retval OPENMPT_ERROR_FUNC_RESULT_LOG Always. * \since 0.3.0 */ LIBOPENMPT_API int openmpt_error_func_log( int error, void * user ); /*! \brief Store error function * * Causes all errors to be stored. * \param error Error code. * \param user Ignored. * \retval OPENMPT_ERROR_FUNC_RESULT_STORE Always. * \since 0.3.0 */ LIBOPENMPT_API int openmpt_error_func_store( int error, void * user ); /*! \brief Ignore error function * * Causes all errors to be neither logged nor stored. * \param error Error code. * \param user Ignored. * \retval OPENMPT_ERROR_FUNC_RESULT_NONE Always. * \since 0.3.0 */ LIBOPENMPT_API int openmpt_error_func_ignore( int error, void * user ); /*! \brief Errno error function * * Causes all errors to be stored in the pointer passed in as user. * \param error Error code. * \param user Pointer to an int as generated by openmpt_error_func_errno_userdata. * \retval OPENMPT_ERROR_FUNC_RESULT_NONE user is not NULL. * \retval OPENMPT_ERROR_FUNC_RESULT_DEFAULT user is NULL. * \since 0.3.0 */ LIBOPENMPT_API int openmpt_error_func_errno( int error, void * user ); /*! \brief User pointer for openmpt_error_func_errno * * Provides a suitable user pointer argument for openmpt_error_func_errno. * \param error Pointer to an integer value to be used as output by openmpt_error_func_errno. * \retval (void*)error. * \since 0.3.0 */ LIBOPENMPT_API void * openmpt_error_func_errno_userdata( int * error ); /*! \brief Roughly scan the input stream to find out whether libopenmpt might be able to open it * * \param stream_callbacks Input stream callback operations. * \param stream Input stream to scan. * \param effort Effort to make when validating stream. Effort 0.0 does not even look at stream at all and effort 1.0 completely loads the file from stream. A lower effort requires less data to be loaded but only gives a rough estimate answer. Use an effort of 0.25 to only verify the header data of the module file. * \param logfunc Logging function where warning and errors are written. May be NULL. * \param user Logging function user context. Used to pass any user-defined data associated with this module to the logging function. * \return Probability between 0.0 and 1.0. * \remarks openmpt_could_open_probability() can return any value between 0.0 and 1.0. Only 0.0 and 1.0 are definitive answers, all values in between are just estimates. In general, any return value >0.0 means that you should try loading the file, and any value below 1.0 means that loading may fail. If you want a threshold above which you can be reasonably sure that libopenmpt will be able to load the file, use >=0.5. If you see the need for a threshold below which you could reasonably outright reject a file, use <0.25 (Note: Such a threshold for rejecting on the lower end is not recommended, but may be required for better integration into some other framework's probe scoring.). * \remarks openmpt_could_open_probability() expects the complete file data to be eventually available to it, even if it is asked to just parse the header. Verification will be unreliable (both false positives and false negatives), if you pretend that the file is just some few bytes of initial data threshold in size. In order to really just access the first bytes of a file, check in your callback functions whether data or seeking is requested beyond your initial data threshold, and in that case, return an error. openmpt_could_open_probability() will treat this as any other I/O error and return 0.0. You must not expect the correct result in this case. You instead must remember that it asked for more data than you currently want to provide to it and treat this situation as if openmpt_could_open_probability() returned 0.5. * \sa \ref libopenmpt_c_fileio * \sa openmpt_stream_callbacks * \deprecated Please use openmpt_module_could_open_probability2(). * \since 0.3.0 */ LIBOPENMPT_API LIBOPENMPT_DEPRECATED double openmpt_could_open_probability( openmpt_stream_callbacks stream_callbacks, void * stream, double effort, openmpt_log_func logfunc, void * user ); /*! \brief Roughly scan the input stream to find out whether libopenmpt might be able to open it * * \param stream_callbacks Input stream callback operations. * \param stream Input stream to scan. * \param effort Effort to make when validating stream. Effort 0.0 does not even look at stream at all and effort 1.0 completely loads the file from stream. A lower effort requires less data to be loaded but only gives a rough estimate answer. Use an effort of 0.25 to only verify the header data of the module file. * \param logfunc Logging function where warning and errors are written. May be NULL. * \param user Logging function user context. Used to pass any user-defined data associated with this module to the logging function. * \return Probability between 0.0 and 1.0. * \remarks openmpt_could_open_probability() can return any value between 0.0 and 1.0. Only 0.0 and 1.0 are definitive answers, all values in between are just estimates. In general, any return value >0.0 means that you should try loading the file, and any value below 1.0 means that loading may fail. If you want a threshold above which you can be reasonably sure that libopenmpt will be able to load the file, use >=0.5. If you see the need for a threshold below which you could reasonably outright reject a file, use <0.25 (Note: Such a threshold for rejecting on the lower end is not recommended, but may be required for better integration into some other framework's probe scoring.). * \remarks openmpt_could_open_probability() expects the complete file data to be eventually available to it, even if it is asked to just parse the header. Verification will be unreliable (both false positives and false negatives), if you pretend that the file is just some few bytes of initial data threshold in size. In order to really just access the first bytes of a file, check in your callback functions whether data or seeking is requested beyond your initial data threshold, and in that case, return an error. openmpt_could_open_probability() will treat this as any other I/O error and return 0.0. You must not expect the correct result in this case. You instead must remember that it asked for more data than you currently want to provide to it and treat this situation as if openmpt_could_open_probability() returned 0.5. * \sa \ref libopenmpt_c_fileio * \sa openmpt_stream_callbacks * \deprecated Please use openmpt_module_could_open_probability2(). */ LIBOPENMPT_API LIBOPENMPT_DEPRECATED double openmpt_could_open_propability( openmpt_stream_callbacks stream_callbacks, void * stream, double effort, openmpt_log_func logfunc, void * user ); /*! \brief Roughly scan the input stream to find out whether libopenmpt might be able to open it * * \param stream_callbacks Input stream callback operations. * \param stream Input stream to scan. * \param effort Effort to make when validating stream. Effort 0.0 does not even look at stream at all and effort 1.0 completely loads the file from stream. A lower effort requires less data to be loaded but only gives a rough estimate answer. Use an effort of 0.25 to only verify the header data of the module file. * \param logfunc Logging function where warning and errors are written. May be NULL. * \param loguser Logging function user context. Used to pass any user-defined data associated with this module to the logging function. * \param errfunc Error function to define error behaviour. May be NULL. * \param erruser Error function user context. Used to pass any user-defined data associated with this module to the logging function. * \param error Pointer to an integer where an error may get stored. May be NULL. * \param error_message Pointer to a string pointer where an error message may get stored. May be NULL. * \return Probability between 0.0 and 1.0. * \remarks openmpt_probe_file_header() or openmpt_probe_file_header_without_filesize() provide a simpler and faster interface that fits almost all use cases better. It is recommended to use openmpt_probe_file_header() or openmpt_probe_file_header_without_filesize() instead of openmpt_could_open_probability(). * \remarks openmpt_could_open_probability2() can return any value between 0.0 and 1.0. Only 0.0 and 1.0 are definitive answers, all values in between are just estimates. In general, any return value >0.0 means that you should try loading the file, and any value below 1.0 means that loading may fail. If you want a threshold above which you can be reasonably sure that libopenmpt will be able to load the file, use >=0.5. If you see the need for a threshold below which you could reasonably outright reject a file, use <0.25 (Note: Such a threshold for rejecting on the lower end is not recommended, but may be required for better integration into some other framework's probe scoring.). * \remarks openmpt_could_open_probability2() expects the complete file data to be eventually available to it, even if it is asked to just parse the header. Verification will be unreliable (both false positives and false negatives), if you pretend that the file is just some few bytes of initial data threshold in size. In order to really just access the first bytes of a file, check in your callback functions whether data or seeking is requested beyond your initial data threshold, and in that case, return an error. openmpt_could_open_probability2() will treat this as any other I/O error and return 0.0. You must not expect the correct result in this case. You instead must remember that it asked for more data than you currently want to provide to it and treat this situation as if openmpt_could_open_probability2() returned 0.5. \include libopenmpt_example_c_probe.c * \sa \ref libopenmpt_c_fileio * \sa openmpt_stream_callbacks * \sa openmpt_probe_file_header * \sa openmpt_probe_file_header_without_filesize * \since 0.3.0 */ LIBOPENMPT_API double openmpt_could_open_probability2( openmpt_stream_callbacks stream_callbacks, void * stream, double effort, openmpt_log_func logfunc, void * loguser, openmpt_error_func errfunc, void * erruser, int * error, const char * * error_message ); /*! \brief Get recommended header size for successfull format probing * * \sa openmpt_probe_file_header() * \sa openmpt_probe_file_header_without_filesize() * \since 0.3.0 */ LIBOPENMPT_API size_t openmpt_probe_file_header_get_recommended_size(void); /*! Probe for module formats in openmpt_probe_file_header() or openmpt_probe_file_header_without_filesize(). \since 0.3.0 */ #define OPENMPT_PROBE_FILE_HEADER_FLAGS_MODULES 0x1ul /*! Probe for module-specific container formats in openmpt_probe_file_header() or openmpt_probe_file_header_without_filesize(). \since 0.3.0 */ #define OPENMPT_PROBE_FILE_HEADER_FLAGS_CONTAINERS 0x2ul /*! Probe for the default set of formats in openmpt_probe_file_header() or openmpt_probe_file_header_without_filesize(). \since 0.3.0 */ #define OPENMPT_PROBE_FILE_HEADER_FLAGS_DEFAULT ( OPENMPT_PROBE_FILE_HEADER_FLAGS_MODULES | OPENMPT_PROBE_FILE_HEADER_FLAGS_CONTAINERS ) /*! Probe for no formats in openmpt_probe_file_header() or openmpt_probe_file_header_without_filesize(). \since 0.3.0 */ #define OPENMPT_PROBE_FILE_HEADER_FLAGS_NONE 0x0ul /*! Possible return values fo openmpt_probe_file_header() and openmpt_probe_file_header_without_filesize(). \since 0.3.0 */ #define OPENMPT_PROBE_FILE_HEADER_RESULT_SUCCESS 1 /*! Possible return values fo openmpt_probe_file_header() and openmpt_probe_file_header_without_filesize(). \since 0.3.0 */ #define OPENMPT_PROBE_FILE_HEADER_RESULT_FAILURE 0 /*! Possible return values fo openmpt_probe_file_header() and openmpt_probe_file_header_without_filesize(). \since 0.3.0 */ #define OPENMPT_PROBE_FILE_HEADER_RESULT_WANTMOREDATA (-1) /*! Possible return values fo openmpt_probe_file_header() and openmpt_probe_file_header_without_filesize(). \since 0.3.0 */ #define OPENMPT_PROBE_FILE_HEADER_RESULT_ERROR (-255) /*! \brief Probe the provided bytes from the beginning of a file for supported file format headers to find out whether libopenmpt might be able to open it * * \param flags Ored mask of OPENMPT_PROBE_FILE_HEADER_FLAGS_MODULES and OPENMPT_PROBE_FILE_HEADER_FLAGS_CONTAINERS, or OPENMPT_PROBE_FILE_HEADER_FLAGS_DEFAULT. * \param data Beginning of the file data. * \param size Size of the beginning of the file data. * \param filesize Full size of the file data on disk. * \param logfunc Logging function where warning and errors are written. May be NULL. * \param loguser Logging function user context. Used to pass any user-defined data associated with this module to the logging function. * \param errfunc Error function to define error behaviour. May be NULL. * \param erruser Error function user context. Used to pass any user-defined data associated with this module to the logging function. * \param error Pointer to an integer where an error may get stored. May be NULL. * \param error_message Pointer to a string pointer where an error message may get stored. May be NULL. * \remarks It is recommended to provide openmpt_probe_file_header_get_recommended_size() bytes of data for data and size. If the file is smaller, only provide the filesize amount and set size and filesize to the file's size. * \remarks openmpt_could_open_probability2() provides a more elaborate interface that might be required for special use cases. It is recommended to use openmpt_probe_file_header() though, if possible. * \retval OPENMPT_PROBE_FILE_HEADER_RESULT_SUCCESS The file will most likely be supported by libopenmpt. * \retval OPENMPT_PROBE_FILE_HEADER_RESULT_FAILURE The file is not supported by libopenmpt. * \retval OPENMPT_PROBE_FILE_HEADER_RESULT_WANTMOREDATA An answer could not be determined with the amount of data provided. * \retval OPENMPT_PROBE_FILE_HEADER_RESULT_ERROR An internal error occurred. * \sa openmpt_probe_file_header_get_recommended_size() * \sa openmpt_probe_file_header_without_filesize() * \sa openmpt_probe_file_header_from_stream() * \sa openmpt_could_open_probability2() * \since 0.3.0 */ LIBOPENMPT_API int openmpt_probe_file_header( uint64_t flags, const void * data, size_t size, uint64_t filesize, openmpt_log_func logfunc, void * loguser, openmpt_error_func errfunc, void * erruser, int * error, const char * * error_message ); /*! \brief Probe the provided bytes from the beginning of a file for supported file format headers to find out whether libopenmpt might be able to open it * * \param flags Ored mask of OPENMPT_PROBE_FILE_HEADER_FLAGS_MODULES and OPENMPT_PROBE_FILE_HEADER_FLAGS_CONTAINERS, or OPENMPT_PROBE_FILE_HEADER_FLAGS_DEFAULT. * \param data Beginning of the file data. * \param size Size of the beginning of the file data. * \param logfunc Logging function where warning and errors are written. May be NULL. * \param loguser Logging function user context. Used to pass any user-defined data associated with this module to the logging function. * \param errfunc Error function to define error behaviour. May be NULL. * \param erruser Error function user context. Used to pass any user-defined data associated with this module to the logging function. * \param error Pointer to an integer where an error may get stored. May be NULL. * \param error_message Pointer to a string pointer where an error message may get stored. May be NULL. * \remarks It is recommended to use openmpt_probe_file_header() and provide the acutal file's size as a parameter if at all possible. libopenmpt can provide more accurate answers if the filesize is known. * \remarks It is recommended to provide openmpt_probe_file_header_get_recommended_size() bytes of data for data and size. If the file is smaller, only provide the filesize amount and set size to the file's size. * \remarks openmpt_could_open_probability2() provides a more elaborate interface that might be required for special use cases. It is recommended to use openmpt_probe_file_header() though, if possible. * \retval OPENMPT_PROBE_FILE_HEADER_RESULT_SUCCESS The file will most likely be supported by libopenmpt. * \retval OPENMPT_PROBE_FILE_HEADER_RESULT_FAILURE The file is not supported by libopenmpt. * \retval OPENMPT_PROBE_FILE_HEADER_RESULT_WANTMOREDATA An answer could not be determined with the amount of data provided. * \retval OPENMPT_PROBE_FILE_HEADER_RESULT_ERROR An internal error occurred. * \sa openmpt_probe_file_header_get_recommended_size() * \sa openmpt_probe_file_header() * \sa openmpt_probe_file_header_from_stream() * \sa openmpt_could_open_probability2() * \since 0.3.0 */ LIBOPENMPT_API int openmpt_probe_file_header_without_filesize( uint64_t flags, const void * data, size_t size, openmpt_log_func logfunc, void * loguser, openmpt_error_func errfunc, void * erruser, int * error, const char * * error_message ); /*! \brief Probe the provided bytes from the beginning of a file for supported file format headers to find out whether libopenmpt might be able to open it * * \param flags Ored mask of OPENMPT_PROBE_FILE_HEADER_FLAGS_MODULES and OPENMPT_PROBE_FILE_HEADER_FLAGS_CONTAINERS, or OPENMPT_PROBE_FILE_HEADER_FLAGS_DEFAULT. * \param stream_callbacks Input stream callback operations. * \param stream Input stream to scan. * \param logfunc Logging function where warning and errors are written. May be NULL. * \param loguser Logging function user context. Used to pass any user-defined data associated with this module to the logging function. * \param errfunc Error function to define error behaviour. May be NULL. * \param erruser Error function user context. Used to pass any user-defined data associated with this module to the logging function. * \param error Pointer to an integer where an error may get stored. May be NULL. * \param error_message Pointer to a string pointer where an error message may get stored. May be NULL. * \remarks The stream is left in an unspecified state when this function returns. * \remarks It is recommended to provide openmpt_probe_file_header_get_recommended_size() bytes of data for data and size. If the file is smaller, only provide the filesize amount and set size and filesize to the file's size. * \remarks openmpt_could_open_probability2() provides a more elaborate interface that might be required for special use cases. It is recommended to use openmpt_probe_file_header() though, if possible. * \retval OPENMPT_PROBE_FILE_HEADER_RESULT_SUCCESS The file will most likely be supported by libopenmpt. * \retval OPENMPT_PROBE_FILE_HEADER_RESULT_FAILURE The file is not supported by libopenmpt. * \retval OPENMPT_PROBE_FILE_HEADER_RESULT_WANTMOREDATA An answer could not be determined with the amount of data provided. * \retval OPENMPT_PROBE_FILE_HEADER_RESULT_ERROR An internal error occurred. * \sa openmpt_probe_file_header_get_recommended_size() * \sa openmpt_probe_file_header() * \sa openmpt_probe_file_header_without_filesize() * \sa openmpt_could_open_probability2() * \since 0.3.0 */ LIBOPENMPT_API int openmpt_probe_file_header_from_stream( uint64_t flags, openmpt_stream_callbacks stream_callbacks, void * stream, openmpt_log_func logfunc, void * loguser, openmpt_error_func errfunc, void * erruser, int * error, const char * * error_message ); /*! \brief Opaque type representing a libopenmpt module */ typedef struct openmpt_module openmpt_module; typedef struct openmpt_module_initial_ctl { const char * ctl; const char * value; } openmpt_module_initial_ctl; /*! \brief Construct an openmpt_module * * \param stream_callbacks Input stream callback operations. * \param stream Input stream to load the module from. * \param logfunc Logging function where warning and errors are written. The logging function may be called throughout the lifetime of openmpt_module. May be NULL. * \param loguser User-defined data associated with this module. This value will be passed to the logging callback function (logfunc) * \param ctls A map of initial ctl values. See openmpt_module_get_ctls() * \return A pointer to the constructed openmpt_module, or NULL on failure. * \remarks The input data can be discarded after an openmpt_module has been constructed successfully. * \sa openmpt_stream_callbacks * \sa \ref libopenmpt_c_fileio * \deprecated Please use openmpt_module_create2(). */ LIBOPENMPT_API LIBOPENMPT_DEPRECATED openmpt_module * openmpt_module_create( openmpt_stream_callbacks stream_callbacks, void * stream, openmpt_log_func logfunc, void * loguser, const openmpt_module_initial_ctl * ctls ); /*! \brief Construct an openmpt_module * * \param stream_callbacks Input stream callback operations. * \param stream Input stream to load the module from. * \param logfunc Logging function where warning and errors are written. The logging function may be called throughout the lifetime of openmpt_module. May be NULL. * \param loguser User-defined data associated with this module. This value will be passed to the logging callback function (logfunc) * \param errfunc Error function to define error behaviour. May be NULL. * \param erruser Error function user context. Used to pass any user-defined data associated with this module to the logging function. * \param error Pointer to an integer where an error may get stored. May be NULL. * \param error_message Pointer to a string pointer where an error message may get stored. May be NULL. * \param ctls A map of initial ctl values. See openmpt_module_get_ctls() * \return A pointer to the constructed openmpt_module, or NULL on failure. * \remarks The input data can be discarded after an openmpt_module has been constructed successfully. * \sa openmpt_stream_callbacks * \sa \ref libopenmpt_c_fileio * \since 0.3.0 */ LIBOPENMPT_API openmpt_module * openmpt_module_create2( openmpt_stream_callbacks stream_callbacks, void * stream, openmpt_log_func logfunc, void * loguser, openmpt_error_func errfunc, void * erruser, int * error, const char * * error_message, const openmpt_module_initial_ctl * ctls ); /*! \brief Construct an openmpt_module * * \param filedata Data to load the module from. * \param filesize Amount of data available. * \param logfunc Logging function where warning and errors are written. The logging function may be called throughout the lifetime of openmpt_module. * \param loguser User-defined data associated with this module. This value will be passed to the logging callback function (logfunc) * \param ctls A map of initial ctl values. See openmpt_module_get_ctls() * \return A pointer to the constructed openmpt_module, or NULL on failure. * \remarks The input data can be discarded after an openmpt_module has been constructed successfully. * \sa \ref libopenmpt_c_fileio * \deprecated Please use openmpt_module_create_from_memory2(). */ LIBOPENMPT_API LIBOPENMPT_DEPRECATED openmpt_module * openmpt_module_create_from_memory( const void * filedata, size_t filesize, openmpt_log_func logfunc, void * loguser, const openmpt_module_initial_ctl * ctls ); /*! \brief Construct an openmpt_module * * \param filedata Data to load the module from. * \param filesize Amount of data available. * \param logfunc Logging function where warning and errors are written. The logging function may be called throughout the lifetime of openmpt_module. * \param loguser User-defined data associated with this module. This value will be passed to the logging callback function (logfunc) * \param errfunc Error function to define error behaviour. May be NULL. * \param erruser Error function user context. Used to pass any user-defined data associated with this module to the logging function. * \param error Pointer to an integer where an error may get stored. May be NULL. * \param error_message Pointer to a string pointer where an error message may get stored. May be NULL. * \param ctls A map of initial ctl values. See openmpt_module_get_ctls() * \return A pointer to the constructed openmpt_module, or NULL on failure. * \remarks The input data can be discarded after an openmpt_module has been constructed successfully. * \sa \ref libopenmpt_c_fileio * \since 0.3.0 */ LIBOPENMPT_API openmpt_module * openmpt_module_create_from_memory2( const void * filedata, size_t filesize, openmpt_log_func logfunc, void * loguser, openmpt_error_func errfunc, void * erruser, int * error, const char * * error_message, const openmpt_module_initial_ctl * ctls ); /*! \brief Unload a previously created openmpt_module from memory. * * \param mod The module to unload. */ LIBOPENMPT_API void openmpt_module_destroy( openmpt_module * mod ); /*! \brief Set logging function. * * Set the logging function of an already constructed openmpt_module. * \param mod The module handle to work on. * \param logfunc Logging function where warning and errors are written. The logging function may be called throughout the lifetime of openmpt_module. * \param loguser User-defined data associated with this module. This value will be passed to the logging callback function (logfunc) * \since 0.3.0 */ LIBOPENMPT_API void openmpt_module_set_log_func( openmpt_module * mod, openmpt_log_func logfunc, void * loguser ); /*! \brief Set error function. * * Set the error function of an already constructed openmpt_module. * \param mod The module handle to work on. * \param errfunc Error function to define error behaviour. May be NULL. * \param erruser Error function user context. * \since 0.3.0 */ LIBOPENMPT_API void openmpt_module_set_error_func( openmpt_module * mod, openmpt_error_func errfunc, void * erruser ); /*! \brief Get last error. * * Return the error currently stored in an openmpt_module. The stored error is not cleared. * \param mod The module handle to work on. * \return The error currently stored. * \sa openmpt_module_error_get_last_message * \sa openmpt_module_error_set_last * \sa openmpt_module_error_clear * \since 0.3.0 */ LIBOPENMPT_API int openmpt_module_error_get_last( openmpt_module * mod ); /*! \brief Get last error message. * * Return the error message currently stored in an openmpt_module. The stored error is not cleared. * \param mod The module handle to work on. * \return The error message currently stored. * \sa openmpt_module_error_set_last * \sa openmpt_module_error_clear * \since 0.3.0 */ LIBOPENMPT_API const char * openmpt_module_error_get_last_message( openmpt_module * mod ); /*! \brief Set last error. * * Set the error currently stored in an openmpt_module. * \param mod The module handle to work on. * \param error Error to be stored. * \sa openmpt_module_error_get_last * \sa openmpt_module_error_clear * \since 0.3.0 */ LIBOPENMPT_API void openmpt_module_error_set_last( openmpt_module * mod, int error ); /*! \brief Clear last error. * * Set the error currently stored in an openmpt_module to OPPENMPT_ERROR_OK. * \param mod The module handle to work on. * \sa openmpt_module_error_get_last * \sa openmpt_module_error_set_last * \since 0.3.0 */ LIBOPENMPT_API void openmpt_module_error_clear( openmpt_module * mod ); /** * \defgroup openmpt_module_render_param Render param indices * * \brief Parameter index to use with openmpt_module_get_render_param() and openmpt_module_set_render_param() * @{ */ /*! \brief Master Gain * * The related value represents a relative gain in milliBel.\n * The default value is 0.\n * The supported value range is unlimited.\n */ #define OPENMPT_MODULE_RENDER_MASTERGAIN_MILLIBEL 1 /*! \brief Stereo Separation * * The related value represents the stereo separation generated by the libopenmpt mixer in percent.\n * The default value is 100.\n * The supported value range is [0,200].\n */ #define OPENMPT_MODULE_RENDER_STEREOSEPARATION_PERCENT 2 /*! \brief Interpolation Filter * * The related value represents the interpolation filter length used by the libopenmpt mixer.\n * The default value is 0, which indicates a recommended default value.\n * The supported value range is [0,inf). Values greater than the implementation limit are clamped to the maximum supported value.\n * Currently supported values: * - 0: internal default * - 1: no interpolation (zero order hold) * - 2: linear interpolation * - 4: cubic interpolation * - 8: windowed sinc with 8 taps */ #define OPENMPT_MODULE_RENDER_INTERPOLATIONFILTER_LENGTH 3 /*! \brief Volume Ramping Strength * * The related value represents the amount of volume ramping done by the libopenmpt mixer.\n * The default value is -1, which indicates a recommended default value.\n * The meaningful value range is [-1..10].\n * A value of 0 completely disables volume ramping. This might cause clicks in sound output.\n * Higher values imply slower/softer volume ramps. */ #define OPENMPT_MODULE_RENDER_VOLUMERAMPING_STRENGTH 4 /** @}*/ /** * \defgroup openmpt_module_command_index Pattern cell indices * * \brief Parameter index to use with openmpt_module_get_pattern_row_channel_command(), openmpt_module_format_pattern_row_channel_command() and openmpt_module_highlight_pattern_row_channel_command() * @{ */ #define OPENMPT_MODULE_COMMAND_NOTE 0 #define OPENMPT_MODULE_COMMAND_INSTRUMENT 1 #define OPENMPT_MODULE_COMMAND_VOLUMEEFFECT 2 #define OPENMPT_MODULE_COMMAND_EFFECT 3 #define OPENMPT_MODULE_COMMAND_VOLUME 4 #define OPENMPT_MODULE_COMMAND_PARAMETER 5 /** @}*/ /*! \brief Select a sub-song from a multi-song module * * \param mod The module handle to work on. * \param subsong Index of the sub-song. -1 plays all sub-songs consecutively. * \return 1 on success, 0 on failure. * \sa openmpt_module_get_num_subsongs, openmpt_module_get_selected_subsong, openmpt_module_get_subsong_name * \remarks Whether subsong -1 (all subsongs consecutively), subsong 0 or some other subsong is selected by default, is an implementation detail and subject to change. If you do not want to care about subsongs, it is recommended to just not call openmpt_module_select_subsong() at all. */ LIBOPENMPT_API int openmpt_module_select_subsong( openmpt_module * mod, int32_t subsong ); /*! \brief Get currently selected sub-song from a multi-song module * * \param mod The module handle to work on. * \return Currently selected sub-song. -1 for all subsongs consecutively, 0 or greater for the current sub-song index. * \sa openmpt_module_get_num_subsongs, openmpt_module_select_subsong, openmpt_module_get_subsong_name * \since 0.3.0 */ LIBOPENMPT_API int32_t openmpt_module_get_selected_subsong( openmpt_module * mod ); /*! \brief Set Repeat Count * * \param mod The module handle to work on. * \param repeat_count Repeat Count * - -1: repeat forever * - 0: play once, repeat zero times (the default) * - n>0: play once and repeat n times after that * \return 1 on success, 0 on failure. * \sa openmpt_module_get_repeat_count */ LIBOPENMPT_API int openmpt_module_set_repeat_count( openmpt_module * mod, int32_t repeat_count ); /*! \brief Get Repeat Count * * \param mod The module handle to work on. * \return Repeat Count * - -1: repeat forever * - 0: play once, repeat zero times (the default) * - n>0: play once and repeat n times after that * \sa openmpt_module_set_repeat_count */ LIBOPENMPT_API int32_t openmpt_module_get_repeat_count( openmpt_module * mod ); /*! \brief approximate song duration * * \param mod The module handle to work on. * \return Approximate duration of current sub-song in seconds. */ LIBOPENMPT_API double openmpt_module_get_duration_seconds( openmpt_module * mod ); /*! \brief Set approximate current song position * * \param mod The module handle to work on. * \param seconds Seconds to seek to. If seconds is out of range, the position gets set to song start or end respectively. * \return Approximate new song position in seconds. * \sa openmpt_module_get_position_seconds */ LIBOPENMPT_API double openmpt_module_set_position_seconds( openmpt_module * mod, double seconds ); /*! \brief Get current song position * * \param mod The module handle to work on. * \return Current song position in seconds. * \sa openmpt_module_set_position_seconds */ LIBOPENMPT_API double openmpt_module_get_position_seconds( openmpt_module * mod ); /*! \brief Set approximate current song position * * If order or row are out of range, to position is not modified and the current position is returned. * \param mod The module handle to work on. * \param order Pattern order number to seek to. * \param row Pattern row number to seek to. * \return Approximate new song position in seconds. * \sa openmpt_module_set_position_seconds * \sa openmpt_module_get_position_seconds */ LIBOPENMPT_API double openmpt_module_set_position_order_row( openmpt_module * mod, int32_t order, int32_t row ); /*! \brief Get render parameter * * \param mod The module handle to work on. * \param param Parameter to query. See \ref openmpt_module_render_param * \param value Pointer to the variable that receives the current value of the parameter. * \return 1 on success, 0 on failure (invalid param or value is NULL). * \sa OPENMPT_MODULE_RENDER_MASTERGAIN_MILLIBEL * \sa OPENMPT_MODULE_RENDER_STEREOSEPARATION_PERCENT * \sa OPENMPT_MODULE_RENDER_INTERPOLATIONFILTER_LENGTH * \sa OPENMPT_MODULE_RENDER_VOLUMERAMPING_STRENGTH * \sa openmpt_module_set_render_param */ LIBOPENMPT_API int openmpt_module_get_render_param( openmpt_module * mod, int param, int32_t * value ); /*! \brief Set render parameter * * \param mod The module handle to work on. * \param param Parameter to set. See \ref openmpt_module_render_param * \param value The value to set param to. * \return 1 on success, 0 on failure (invalid param). * \sa OPENMPT_MODULE_RENDER_MASTERGAIN_MILLIBEL * \sa OPENMPT_MODULE_RENDER_STEREOSEPARATION_PERCENT * \sa OPENMPT_MODULE_RENDER_INTERPOLATIONFILTER_LENGTH * \sa OPENMPT_MODULE_RENDER_VOLUMERAMPING_STRENGTH * \sa openmpt_module_get_render_param */ LIBOPENMPT_API int openmpt_module_set_render_param( openmpt_module * mod, int param, int32_t value ); /*@{*/ /*! \brief Render audio data * * \param mod The module handle to work on. * \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. * \param count Number of audio frames to render per channel. * \param mono Pointer to a buffer of at least count elements that receives the mono/center output. * \return The number of frames actually rendered. * \retval 0 The end of song has been reached. * \remarks The output buffers are only written to up to the returned number of elements. * \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. * \remarks It is recommended to use the floating point API because of the greater dynamic range and no implied clipping. * \sa \ref libopenmpt_c_outputformat */ LIBOPENMPT_API size_t openmpt_module_read_mono( openmpt_module * mod, int32_t samplerate, size_t count, int16_t * mono ); /*! \brief Render audio data * * \param mod The module handle to work on. * \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. * \param count Number of audio frames to render per channel. * \param left Pointer to a buffer of at least count elements that receives the left output. * \param right Pointer to a buffer of at least count elements that receives the right output. * \return The number of frames actually rendered. * \retval 0 The end of song has been reached. * \remarks The output buffers are only written to up to the returned number of elements. * \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. * \remarks It is recommended to use the floating point API because of the greater dynamic range and no implied clipping. * \sa \ref libopenmpt_c_outputformat */ LIBOPENMPT_API size_t openmpt_module_read_stereo( openmpt_module * mod, int32_t samplerate, size_t count, int16_t * left, int16_t * right ); /*! \brief Render audio data * * \param mod The module handle to work on. * \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. * \param count Number of audio frames to render per channel. * \param left Pointer to a buffer of at least count elements that receives the left output. * \param right Pointer to a buffer of at least count elements that receives the right output. * \param rear_left Pointer to a buffer of at least count elements that receives the rear left output. * \param rear_right Pointer to a buffer of at least count elements that receives the rear right output. * \return The number of frames actually rendered. * \retval 0 The end of song has been reached. * \remarks The output buffers are only written to up to the returned number of elements. * \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. * \remarks It is recommended to use the floating point API because of the greater dynamic range and no implied clipping. * \sa \ref libopenmpt_c_outputformat */ LIBOPENMPT_API size_t openmpt_module_read_quad( openmpt_module * mod, int32_t samplerate, size_t count, int16_t * left, int16_t * right, int16_t * rear_left, int16_t * rear_right ); /*! \brief Render audio data * * \param mod The module handle to work on. * \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. * \param count Number of audio frames to render per channel. * \param mono Pointer to a buffer of at least count elements that receives the mono/center output. * \return The number of frames actually rendered. * \retval 0 The end of song has been reached. * \remarks The output buffers are only written to up to the returned number of elements. * \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. * \remarks Floating point samples are in the [-1.0..1.0] nominal range. They are not clipped to that range though and thus might overshoot. * \sa \ref libopenmpt_c_outputformat */ LIBOPENMPT_API size_t openmpt_module_read_float_mono( openmpt_module * mod, int32_t samplerate, size_t count, float * mono ); /*! \brief Render audio data * * \param mod The module handle to work on. * \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. * \param count Number of audio frames to render per channel. * \param left Pointer to a buffer of at least count elements that receives the left output. * \param right Pointer to a buffer of at least count elements that receives the right output. * \return The number of frames actually rendered. * \retval 0 The end of song has been reached. * \remarks The output buffers are only written to up to the returned number of elements. * \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. * \remarks Floating point samples are in the [-1.0..1.0] nominal range. They are not clipped to that range though and thus might overshoot. * \sa \ref libopenmpt_c_outputformat */ LIBOPENMPT_API size_t openmpt_module_read_float_stereo( openmpt_module * mod, int32_t samplerate, size_t count, float * left, float * right ); /*! \brief Render audio data * * \param mod The module handle to work on. * \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. * \param count Number of audio frames to render per channel. * \param left Pointer to a buffer of at least count elements that receives the left output. * \param right Pointer to a buffer of at least count elements that receives the right output. * \param rear_left Pointer to a buffer of at least count elements that receives the rear left output. * \param rear_right Pointer to a buffer of at least count elements that receives the rear right output. * \return The number of frames actually rendered. * \retval 0 The end of song has been reached. * \remarks The output buffers are only written to up to the returned number of elements. * \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. * \remarks Floating point samples are in the [-1.0..1.0] nominal range. They are not clipped to that range though and thus might overshoot. * \sa \ref libopenmpt_c_outputformat */ LIBOPENMPT_API size_t openmpt_module_read_float_quad( openmpt_module * mod, int32_t samplerate, size_t count, float * left, float * right, float * rear_left, float * rear_right ); /*! \brief Render audio data * * \param mod The module handle to work on. * \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. * \param count Number of audio frames to render per channel. * \param interleaved_stereo Pointer to a buffer of at least count*2 elements that receives the interleaved stereo output in the order (L,R). * \return The number of frames actually rendered. * \retval 0 The end of song has been reached. * \remarks The output buffers are only written to up to the returned number of elements. * \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. * \remarks It is recommended to use the floating point API because of the greater dynamic range and no implied clipping. * \sa \ref libopenmpt_c_outputformat */ LIBOPENMPT_API size_t openmpt_module_read_interleaved_stereo( openmpt_module * mod, int32_t samplerate, size_t count, int16_t * interleaved_stereo ); /*! \brief Render audio data * * \param mod The module handle to work on. * \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. * \param count Number of audio frames to render per channel. * \param interleaved_quad Pointer to a buffer of at least count*4 elements that receives the interleaved suad surround output in the order (L,R,RL,RR). * \return The number of frames actually rendered. * \retval 0 The end of song has been reached. * \remarks The output buffers are only written to up to the returned number of elements. * \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. * \remarks It is recommended to use the floating point API because of the greater dynamic range and no implied clipping. * \sa \ref libopenmpt_c_outputformat */ LIBOPENMPT_API size_t openmpt_module_read_interleaved_quad( openmpt_module * mod, int32_t samplerate, size_t count, int16_t * interleaved_quad ); /*! \brief Render audio data * * \param mod The module handle to work on. * \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. * \param count Number of audio frames to render per channel. * \param interleaved_stereo Pointer to a buffer of at least count*2 elements that receives the interleaved stereo output in the order (L,R). * \return The number of frames actually rendered. * \retval 0 The end of song has been reached. * \remarks The output buffers are only written to up to the returned number of elements. * \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. * \remarks Floating point samples are in the [-1.0..1.0] nominal range. They are not clipped to that range though and thus might overshoot. * \sa \ref libopenmpt_c_outputformat */ LIBOPENMPT_API size_t openmpt_module_read_interleaved_float_stereo( openmpt_module * mod, int32_t samplerate, size_t count, float * interleaved_stereo ); /*! \brief Render audio data * * \param mod The module handle to work on. * \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. * \param count Number of audio frames to render per channel. * \param interleaved_quad Pointer to a buffer of at least count*4 elements that receives the interleaved suad surround output in the order (L,R,RL,RR). * \return The number of frames actually rendered. * \retval 0 The end of song has been reached. * \remarks The output buffers are only written to up to the returned number of elements. * \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. * \remarks Floating point samples are in the [-1.0..1.0] nominal range. They are not clipped to that range though and thus might overshoot. * \sa \ref libopenmpt_c_outputformat */ LIBOPENMPT_API size_t openmpt_module_read_interleaved_float_quad( openmpt_module * mod, int32_t samplerate, size_t count, float * interleaved_quad ); /*@}*/ /*! \brief Get the list of supported metadata item keys * * \param mod The module handle to work on. * \return Metadata item keys supported by openmpt_module_get_metadata, as a semicolon-separated list. * \sa openmpt_module_get_metadata */ LIBOPENMPT_API const char * openmpt_module_get_metadata_keys( openmpt_module * mod ); /*! \brief Get a metadata item value * * \param mod The module handle to work on. * \param key Metadata item key to query. Use openmpt_module_get_metadata_keys to check for available keys. * Possible keys are: * - type: Module format extension (e.g. it) * - type_long: Tracker name associated with the module format (e.g. Impulse Tracker) * - container: Container format the module file is embedded in, if any (e.g. umx) * - container_long: Full container name if the module is embedded in a container (e.g. Unreal Music) * - tracker: Tracker that was (most likely) used to save the module file, if known * - artist: Author of the module * - title: Module title * - date: Date the module was last saved, in ISO-8601 format. * - message: Song message. If the song message is empty or the module format does not support song messages, a list of instrument and sample names is returned instead. * - message_raw: Song message. If the song message is empty or the module format does not support song messages, an empty string is returned. * - warnings: A list of warnings that were generated while loading the module. * \return The associated value for key. * \sa openmpt_module_get_metadata_keys */ LIBOPENMPT_API const char * openmpt_module_get_metadata( openmpt_module * mod, const char * key ); /*! \brief Get the current speed * * \param mod The module handle to work on. * \return The current speed in ticks per row. */ LIBOPENMPT_API int32_t openmpt_module_get_current_speed( openmpt_module * mod ); /*! \brief Get the current tempo * * \param mod The module handle to work on. * \return The current tempo in tracker units. The exact meaning of this value depends on the tempo mode being used. */ LIBOPENMPT_API int32_t openmpt_module_get_current_tempo( openmpt_module * mod ); /*! \brief Get the current order * * \param mod The module handle to work on. * \return The current order at which the module is being played back. */ LIBOPENMPT_API int32_t openmpt_module_get_current_order( openmpt_module * mod ); /*! \brief Get the current pattern * * \param mod The module handle to work on. * \return The current pattern that is being played. */ LIBOPENMPT_API int32_t openmpt_module_get_current_pattern( openmpt_module * mod ); /*! \brief Get the current row * * \param mod The module handle to work on. * \return The current row at which the current pattern is being played. */ LIBOPENMPT_API int32_t openmpt_module_get_current_row( openmpt_module * mod ); /*! \brief Get the current amount of playing channels. * * \param mod The module handle to work on. * \return The amount of sample channels that are currently being rendered. */ LIBOPENMPT_API int32_t openmpt_module_get_current_playing_channels( openmpt_module * mod ); /*! \brief Get an approximate indication of the channel volume. * * \param mod The module handle to work on. * \param channel The channel whose volume should be retrieved. * \return The approximate channel volume. * \remarks The returned value is solely based on the note velocity and does not take the actual waveform of the playing sample into account. */ LIBOPENMPT_API float openmpt_module_get_current_channel_vu_mono( openmpt_module * mod, int32_t channel ); /*! \brief Get an approximate indication of the channel volume on the front-left speaker. * * \param mod The module handle to work on. * \param channel The channel whose volume should be retrieved. * \return The approximate channel volume. * \remarks The returned value is solely based on the note velocity and does not take the actual waveform of the playing sample into account. */ LIBOPENMPT_API float openmpt_module_get_current_channel_vu_left( openmpt_module * mod, int32_t channel ); /*! \brief Get an approximate indication of the channel volume on the front-right speaker. * * \param mod The module handle to work on. * \param channel The channel whose volume should be retrieved. * \return The approximate channel volume. * \remarks The returned value is solely based on the note velocity and does not take the actual waveform of the playing sample into account. */ LIBOPENMPT_API float openmpt_module_get_current_channel_vu_right( openmpt_module * mod, int32_t channel ); /*! \brief Get an approximate indication of the channel volume on the rear-left speaker. * * \param mod The module handle to work on. * \param channel The channel whose volume should be retrieved. * \return The approximate channel volume. * \remarks The returned value is solely based on the note velocity and does not take the actual waveform of the playing sample into account. */ LIBOPENMPT_API float openmpt_module_get_current_channel_vu_rear_left( openmpt_module * mod, int32_t channel ); /*! \brief Get an approximate indication of the channel volume on the rear-right speaker. * * \param mod The module handle to work on. * \param channel The channel whose volume should be retrieved. * \return The approximate channel volume. * \remarks The returned value is solely based on the note velocity and does not take the actual waveform of the playing sample into account. */ LIBOPENMPT_API float openmpt_module_get_current_channel_vu_rear_right( openmpt_module * mod, int32_t channel ); /*! \brief Get the number of sub-songs * * \param mod The module handle to work on. * \return The number of sub-songs in the module. This includes any "hidden" songs (songs that share the same sequence, but start at different order indices) and "normal" sub-songs or "sequences" (if the format supports them). * \sa openmpt_module_get_subsong_name, openmpt_module_select_subsong, openmpt_module_get_selected_subsong */ LIBOPENMPT_API int32_t openmpt_module_get_num_subsongs( openmpt_module * mod ); /*! \brief Get the number of pattern channels * * \param mod The module handle to work on. * \return The number of pattern channels in the module. Not all channels do necessarily contain data. * \remarks The number of pattern channels is completely independent of the number of output channels. libopenmpt can render modules in mono, stereo or quad surround, but the choice of which of the three modes to use must not be made based on the return value of this function, which may be any positive integer amount. Only use this function for informational purposes. */ LIBOPENMPT_API int32_t openmpt_module_get_num_channels( openmpt_module * mod ); /*! \brief Get the number of orders * * \param mod The module handle to work on. * \return The number of orders in the current sequence of the module. */ LIBOPENMPT_API int32_t openmpt_module_get_num_orders( openmpt_module * mod ); /*! \brief Get the number of patterns * * \param mod The module handle to work on. * \return The number of distinct patterns in the module. */ LIBOPENMPT_API int32_t openmpt_module_get_num_patterns( openmpt_module * mod ); /*! \brief Get the number of instruments * * \param mod The module handle to work on. * \return The number of instrument slots in the module. Instruments are a layer on top of samples, and are not supported by all module formats. */ LIBOPENMPT_API int32_t openmpt_module_get_num_instruments( openmpt_module * mod ); /*! \brief Get the number of samples * * \param mod The module handle to work on. * \return The number of sample slots in the module. */ LIBOPENMPT_API int32_t openmpt_module_get_num_samples( openmpt_module * mod ); /*! \brief Get a sub-song name * * \param mod The module handle to work on. * \param index The sub-song whose name should be retrieved * \return The sub-song name. * \sa openmpt_module_get_num_subsongs, openmpt_module_select_subsong, openmpt_module_get_selected_subsong */ LIBOPENMPT_API const char * openmpt_module_get_subsong_name( openmpt_module * mod, int32_t index ); /*! \brief Get a channel name * * \param mod The module handle to work on. * \param index The channel whose name should be retrieved * \return The channel name. * \sa openmpt_module_get_num_channels */ LIBOPENMPT_API const char * openmpt_module_get_channel_name( openmpt_module * mod, int32_t index ); /*! \brief Get an order name * * \param mod The module handle to work on. * \param index The order whose name should be retrieved * \return The order name. * \sa openmpt_module_get_num_orders */ LIBOPENMPT_API const char * openmpt_module_get_order_name( openmpt_module * mod, int32_t index ); /*! \brief Get a pattern name * * \param mod The module handle to work on. * \param index The pattern whose name should be retrieved * \return The pattern name. * \sa openmpt_module_get_num_patterns */ LIBOPENMPT_API const char * openmpt_module_get_pattern_name( openmpt_module * mod, int32_t index ); /*! \brief Get an instrument name * * \param mod The module handle to work on. * \param index The instrument whose name should be retrieved * \return The instrument name. * \sa openmpt_module_get_num_instruments */ LIBOPENMPT_API const char * openmpt_module_get_instrument_name( openmpt_module * mod, int32_t index ); /*! \brief Get a sample name * * \param mod The module handle to work on. * \param index The sample whose name should be retrieved * \return The sample name. * \sa openmpt_module_get_num_samples */ LIBOPENMPT_API const char * openmpt_module_get_sample_name( openmpt_module * mod, int32_t index ); /*! \brief Get pattern at order position * * \param mod The module handle to work on. * \param order The order item whose pattern index should be retrieved. * \return The pattern index found at the given order position of the current sequence. */ LIBOPENMPT_API int32_t openmpt_module_get_order_pattern( openmpt_module * mod, int32_t order ); /*! \brief Get the number of rows in a pattern * * \param mod The module handle to work on. * \param pattern The pattern whose row count should be retrieved. * \return The number of rows in the given pattern. If the pattern does not exist, 0 is returned. */ LIBOPENMPT_API int32_t openmpt_module_get_pattern_num_rows( openmpt_module * mod, int32_t pattern ); /*! \brief Get raw pattern content * * \param mod The module handle to work on. * \param pattern The pattern whose data should be retrieved. * \param row The row from which the data should be retrieved. * \param channel The channel from which the data should be retrieved. * \param command The cell index at which the data should be retrieved. See \ref openmpt_module_command_index * \return The internal, raw pattern data at the given pattern position. */ LIBOPENMPT_API uint8_t openmpt_module_get_pattern_row_channel_command( openmpt_module * mod, int32_t pattern, int32_t row, int32_t channel, int command ); /*! \brief Get formatted (human-readable) pattern content * * \param mod The module handle to work on. * \param pattern The pattern whose data should be retrieved. * \param row The row from which the data should be retrieved. * \param channel The channel from which the data should be retrieved. * \param command The cell index at which the data should be retrieved. * \return The formatted pattern data at the given pattern position. See \ref openmpt_module_command_index * \sa openmpt_module_highlight_pattern_row_channel_command */ LIBOPENMPT_API const char * openmpt_module_format_pattern_row_channel_command( openmpt_module * mod, int32_t pattern, int32_t row, int32_t channel, int command ); /*! \brief Get highlighting information for formatted pattern content * * \param mod The module handle to work on. * \param pattern The pattern whose data should be retrieved. * \param row The row from which the data should be retrieved. * \param channel The channel from which the data should be retrieved. * \param command The cell index at which the data should be retrieved. See \ref openmpt_module_command_index * \return The highlighting string for the formatted pattern data as retrieved by openmpt_module_get_pattern_row_channel_command at the given pattern position. * \remarks The returned string will map each character position of the string returned by openmpt_module_get_pattern_row_channel_command to a highlighting instruction. * Possible highlighting characters are: * - " " : empty/space * - "." : empty/dot * - "n" : generic note * - "m" : special note * - "i" : generic instrument * - "u" : generic volume column effect * - "v" : generic volume column parameter * - "e" : generic effect column effect * - "f" : generic effect column parameter * \sa openmpt_module_get_pattern_row_channel_command */ LIBOPENMPT_API const char * openmpt_module_highlight_pattern_row_channel_command( openmpt_module * mod, int32_t pattern, int32_t row, int32_t channel, int command ); /*! \brief Get formatted (human-readable) pattern content * * \param mod The module handle to work on. * \param pattern The pattern whose data should be retrieved. * \param row The row from which the data should be retrieved. * \param channel The channel from which the data should be retrieved. * \param width The maximum number of characters the string should contain. 0 means no limit. * \param pad If true, the string will be resized to the exact length provided in the width parameter. * \return The formatted pattern data at the given pattern position. * \sa openmpt_module_highlight_pattern_row_channel */ LIBOPENMPT_API const char * openmpt_module_format_pattern_row_channel( openmpt_module * mod, int32_t pattern, int32_t row, int32_t channel, size_t width, int pad ); /*! \brief Get highlighting information for formatted pattern content * * \param mod The module handle to work on. * \param pattern The pattern whose data should be retrieved. * \param row The row from which the data should be retrieved. * \param channel The channel from which the data should be retrieved. * \param width The maximum number of characters the string should contain. 0 means no limit. * \param pad If true, the string will be resized to the exact length provided in the width parameter. * \return The highlighting string for the formatted pattern data as retrieved by openmpt_module_format_pattern_row_channel at the given pattern position. * \sa openmpt_module_format_pattern_row_channel */ LIBOPENMPT_API const char * openmpt_module_highlight_pattern_row_channel( openmpt_module * mod, int32_t pattern, int32_t row, int32_t channel, size_t width, int pad ); /*! \brief Retrieve supported ctl keys * * \param mod The module handle to work on. * \return A semicolon-separated list containing all supported ctl keys. * \remarks Currently supported ctl values are: * - load.skip_samples: Set to "1" to avoid loading samples into memory * - load.skip_patterns: Set to "1" to avoid loading patterns into memory * - load.skip_plugins: Set to "1" to avoid loading plugins * - load.skip_subsongs_init: Set to "1" to avoid pre-initializing sub-songs. Skipping results in faster module loading but slower seeking. * - seek.sync_samples: Set to "1" to sync sample playback when using openmpt_module_set_position_seconds or openmpt_module_set_position_order_row. * - subsong: The current subsong. Setting it has identical semantics as openmpt_module_select_subsong(), getting it returns the currently selected subsong. * - play.tempo_factor: Set a floating point tempo factor. "1.0" is the default tempo. * - play.pitch_factor: Set a floating point pitch factor. "1.0" is the default pitch. * - render.resampler.emulate_amiga: Set to "1" to enable the Amiga resampler for Amiga modules. This emulates the sound characteristics of the Paula chip and overrides the selected interpolation filter. Non-Amiga module formats are not affected by this setting. * - dither: Set the dither algorithm that is used for the 16 bit versions of openmpt_module_read. Supported values are: * - 0: No dithering. * - 1: Default mode. Chosen by OpenMPT code, might change. * - 2: Rectangular, 0.5 bit depth, no noise shaping (original ModPlug Tracker). * - 3: Rectangular, 1 bit depth, simple 1st order noise shaping */ LIBOPENMPT_API const char * openmpt_module_get_ctls( openmpt_module * mod ); /*! \brief Get current ctl value * * \param mod The module handle to work on. * \param ctl The ctl key whose value should be retrieved. * \return The associated ctl value, or NULL on failure. * \sa openmpt_module_get_ctls */ LIBOPENMPT_API const char * openmpt_module_ctl_get( openmpt_module * mod, const char * ctl ); /*! \brief Set ctl value * * \param mod The module handle to work on. * \param ctl The ctl key whose value should be set. * \param value The value that should be set. * \return 1 if successful, 0 in case the value is not sensible (e.g. negative tempo factor) or the ctl is not recognized. * \sa openmpt_module_get_ctls */ LIBOPENMPT_API int openmpt_module_ctl_set( openmpt_module * mod, const char * ctl, const char * value ); /* remember to add new functions to both C and C++ interfaces and to increase OPENMPT_API_VERSION_MINOR */ #ifdef __cplusplus } #endif /*! @} */ #endif /* LIBOPENMPT_H */ libopenmpt-0.3.6+release.autotools/libopenmpt/libopenmpt_stream_callbacks_buffer.h0000644000372100037210000001070512773704603025670 00000000000000/* * libopenmpt_stream_callbacks_buffer.h * ------------------------------------ * Purpose: libopenmpt public c interface * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #ifndef LIBOPENMPT_STREAM_CALLBACKS_BUFFER_H #define LIBOPENMPT_STREAM_CALLBACKS_BUFFER_H #include "libopenmpt.h" /* The use of this header requires: #include #if defined( LIBOPENMPT_STREAM_CALLBACKS_BUFFER ) #include #else #error "libopenmpt too old." #endif */ #include #include #include #ifdef __cplusplus extern "C" { #endif typedef struct openmpt_stream_buffer { const void * file_data; /* or prefix data IFF prefix_size < file_size */ int64_t file_size; int64_t file_pos; int64_t prefix_size; int overflow; } openmpt_stream_buffer; static size_t openmpt_stream_buffer_read_func( void * stream, void * dst, size_t bytes ) { openmpt_stream_buffer * s = (openmpt_stream_buffer*)stream; int64_t offset = 0; int64_t begpos = 0; int64_t endpos = 0; size_t valid_bytes = 0; if ( !s ) { return 0; } offset = bytes; begpos = s->file_pos; endpos = s->file_pos; valid_bytes = 0; endpos = (uint64_t)endpos + (uint64_t)offset; if ( ( offset > 0 ) && !( (uint64_t)endpos > (uint64_t)begpos ) ) { /* integer wrapped */ return 0; } if ( bytes == 0 ) { return 0; } if ( begpos >= s->file_size ) { return 0; } if ( endpos > s->file_size ) { /* clip to eof */ bytes = bytes - (size_t)( endpos - s->file_size ); endpos = endpos - ( endpos - s->file_size ); } memset( dst, 0, bytes ); if ( begpos >= s->prefix_size ) { s->overflow = 1; valid_bytes = 0; } else if ( endpos > s->prefix_size ) { s->overflow = 1; valid_bytes = bytes - (size_t)( endpos - s->prefix_size ); } else { valid_bytes = bytes; } memcpy( dst, (const char*)s->file_data + s->file_pos, valid_bytes ); s->file_pos = s->file_pos + bytes; return bytes; } static int openmpt_stream_buffer_seek_func( void * stream, int64_t offset, int whence ) { openmpt_stream_buffer * s = (openmpt_stream_buffer*)stream; int result = -1; if ( !s ) { return -1; } switch ( whence ) { case OPENMPT_STREAM_SEEK_SET: if ( offset < 0 ) { return -1; } if ( offset > s->file_size ) { return -1; } s->file_pos = offset; result = 0; break; case OPENMPT_STREAM_SEEK_CUR: do { int64_t oldpos = s->file_pos; int64_t pos = s->file_pos; pos = (uint64_t)pos + (uint64_t)offset; if ( ( offset > 0 ) && !( (uint64_t)pos > (uint64_t)oldpos ) ) { /* integer wrapped */ return -1; } if ( ( offset < 0 ) && !( (uint64_t)pos < (uint64_t)oldpos ) ) { /* integer wrapped */ return -1; } s->file_pos = pos; } while(0); result = 0; break; case OPENMPT_STREAM_SEEK_END: if ( offset > 0 ) { return -1; } do { int64_t oldpos = s->file_pos; int64_t pos = s->file_pos; pos = s->file_size; pos = (uint64_t)pos + (uint64_t)offset; if ( ( offset < 0 ) && !( (uint64_t)pos < (uint64_t)oldpos ) ) { /* integer wrapped */ return -1; } s->file_pos = pos; } while(0); result = 0; break; } return result; } static int64_t openmpt_stream_buffer_tell_func( void * stream ) { openmpt_stream_buffer * s = (openmpt_stream_buffer*)stream; if ( !s ) { return -1; } return s->file_pos; } static void openmpt_stream_buffer_init( openmpt_stream_buffer * buffer, const void * file_data, int64_t file_size ) { memset( buffer, 0, sizeof( openmpt_stream_buffer ) ); buffer->file_data = file_data; buffer->file_size = file_size; buffer->file_pos = 0; buffer->prefix_size = file_size; buffer->overflow = 0; } #define openmpt_stream_buffer_init_prefix_only( buffer_, prefix_data_, prefix_size_, file_size_ ) do { \ openmpt_stream_buffer_init( (buffer_), (prefix_data_), (file_size_) ); \ (buffer_)->prefix_size = (prefix_size_); \ } while(0) #define openmpt_stream_buffer_overflowed( buffer_ ) ( (buffer_)->overflow ) static openmpt_stream_callbacks openmpt_stream_get_buffer_callbacks(void) { openmpt_stream_callbacks retval; memset( &retval, 0, sizeof( openmpt_stream_callbacks ) ); retval.read = openmpt_stream_buffer_read_func; retval.seek = openmpt_stream_buffer_seek_func; retval.tell = openmpt_stream_buffer_tell_func; return retval; } #ifdef __cplusplus } #endif #endif /* LIBOPENMPT_STREAM_CALLBACKS_BUFFER_H */ libopenmpt-0.3.6+release.autotools/libopenmpt/libopenmpt_version.h0000644000372100037210000000614513235361343022527 00000000000000/* * libopenmpt_version.h * -------------------- * Purpose: libopenmpt public interface version * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #ifndef LIBOPENMPT_VERSION_H #define LIBOPENMPT_VERSION_H /*! \addtogroup libopenmpt @{ */ /*! \brief libopenmpt major version number */ #define OPENMPT_API_VERSION_MAJOR 0 /*! \brief libopenmpt minor version number */ #define OPENMPT_API_VERSION_MINOR 3 /*! \brief libopenmpt patch version number */ #define OPENMPT_API_VERSION_PATCH 6 /*! \brief libopenmpt pre-release tag */ #define OPENMPT_API_VERSION_PREREL "" /*! \brief libopenmpt pre-release flag */ #define OPENMPT_API_VERSION_IS_PREREL 0 /*! \brief libopenmpt version number as a single integer value * \since 0.3 * \remarks Use the following shim if you need to support earlier libopenmpt versions: * \code * #include * #if !defined(OPENMPT_API_VERSION_MAKE) * #define OPENMPT_API_VERSION_MAKE(major, minor, patch) (((major)<<24)|((minor)<<16)|((patch)<<0)) * #endif * \endcode */ #define OPENMPT_API_VERSION_MAKE(major, minor, patch) (((major)<<24)|((minor)<<16)|((patch)<<0)) /*! \brief libopenmpt API version number */ #define OPENMPT_API_VERSION OPENMPT_API_VERSION_MAKE(OPENMPT_API_VERSION_MAJOR, OPENMPT_API_VERSION_MINOR, OPENMPT_API_VERSION_PATCH) /*! \brief Check whether the libopenmpt API is at least the provided version * \since 0.3 * \remarks Use the following shim if you need to support earlier libopenmpt versions: * \code * #include * #if !defined(OPENMPT_API_VERSION_AT_LEAST) * #define OPENMPT_API_VERSION_AT_LEAST(major, minor, patch) (OPENMPT_API_VERSION >= OPENMPT_API_VERSION_MAKE((major), (minor), (patch))) * #endif * \endcode */ #define OPENMPT_API_VERSION_AT_LEAST(major, minor, patch) (OPENMPT_API_VERSION >= OPENMPT_API_VERSION_MAKE((major), (minor), (patch))) /*! \brief Check whether the libopenmpt API is before the provided version * \since 0.3 * \remarks Use the following shim if you need to support earlier libopenmpt versions: * \code * #include * #if !defined(OPENMPT_API_VERSION_BEFORE) * #define OPENMPT_API_VERSION_BEFORE(major, minor, patch) (OPENMPT_API_VERSION < OPENMPT_API_VERSION_MAKE((major), (minor), (patch))) * #endif * \endcode */ #define OPENMPT_API_VERSION_BEFORE(major, minor, patch) (OPENMPT_API_VERSION < OPENMPT_API_VERSION_MAKE((major), (minor), (patch))) #define OPENMPT_API_VERSION_HELPER_STRINGIZE(x) #x #define OPENMPT_API_VERSION_STRINGIZE(x) OPENMPT_API_VERSION_HELPER_STRINGIZE(x) #define OPENMPT_API_VERSION_STRING OPENMPT_API_VERSION_STRINGIZE(OPENMPT_API_VERSION_MAJOR) "." OPENMPT_API_VERSION_STRINGIZE(OPENMPT_API_VERSION_MINOR) "." OPENMPT_API_VERSION_STRINGIZE(OPENMPT_API_VERSION_PATCH) OPENMPT_API_VERSION_PREREL /*! @} */ #endif /* LIBOPENMPT_VERSION_H */ libopenmpt-0.3.6+release.autotools/libopenmpt/libopenmpt.pc.in0000644000372100037210000000047112740237634021543 00000000000000 prefix=@prefix@ exec_prefix=@exec_prefix@ includedir=@includedir@ libdir=@libdir@ Name: libopenmpt Description: Tracker module player based on OpenMPT Version: @VERSION@ Requires.private: @LIBOPENMPT_REQUIRES_PRIVATE@ Libs: -L${libdir} -lopenmpt Libs.private: @LIBOPENMPT_LIBS_PRIVATE@ Cflags: -I${includedir} libopenmpt-0.3.6+release.autotools/libopenmpt/libopenmpt.hpp0000644000372100037210000016017413231373725021330 00000000000000/* * libopenmpt.hpp * -------------- * Purpose: libopenmpt public c++ interface * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #ifndef LIBOPENMPT_HPP #define LIBOPENMPT_HPP #include "libopenmpt_config.h" #include #include #include #include #include #include #include /*! * \page libopenmpt_cpp_overview C++ API * * \section libopenmpt_cpp_error Error Handling * * libopenmpt C++ uses C++ exception handling for errror reporting. * * Unless otherwise noted, any libopenmpt function may throw exceptions and * all exceptions thrown by libopenmpt itself are derived from * openmpt::exception. * In addition, any libopenmpt function may also throw any exception specified * by the C++ language and C++ standard library. These are all derived from * std::exception. * * \section libopenmpt_cpp_strings Strings * * - All strings returned from libopenmpt are encoded in UTF-8. * - All strings passed to libopenmpt should also be encoded in UTF-8. * Behaviour in case of invalid UTF-8 is unspecified. * - libopenmpt does not enforce or expect any particular Unicode * normalization form. * * \section libopenmpt_cpp_fileio File I/O * * libopenmpt can use 3 different strategies for file I/O. * * - openmpt::module::module() with any kind of memory buffer as parameter will * load the module from the provided memory buffer, which will require loading * all data upfront by the library * caller. * - openmpt::module::module() with a seekable std::istream as parameter will * load the module via the stream interface. libopenmpt will not implement an * additional buffering layer in this case whih means the callbacks are assumed * to be performant even with small i/o sizes. * - openmpt::module::module() with an unseekable std::istream as parameter * will load the module via the stream interface. libopempt will make an * internal copy as it goes along, and sometimes have to pre-cache the whole * file in case it needs to know the complete file size. This strategy is * intended to be used if the file is located on a high latency network. * * | constructor | speed | memory consumption | * | ----------------: | :----: | :----------------: | * | memory buffer |

fast

|

medium

| * | seekable stream |

slow

|

low

| * | unseekable stream |

medium

|

high

| * * In all cases, the data or stream passed to the constructor is no longer * needed after the openmpt::module has been constructed and can be destroyed * by the caller. * * \section libopenmpt_cpp_outputformat Output Format * * libopenmpt supports a wide range of PCM output formats: * [8000..192000]/[mono|stereo|quad]/[f32|i16]. * * Unless you have some very specific requirements demanding a particular aspect * of the output format, you should always prefer 48000/stereo/f32 as the * libopenmpt PCM format. * * - Please prefer 48000Hz unless the user explicitly demands something else. * Practically all audio equipment and file formats use 48000Hz nowadays. * - Practically all module formats are made for stereo output. Mono will not * give you any measurable speed improvements and can trivially be obtained from * the stereo output anyway. Quad is not expected by almost all modules and even * if they do use surround effects, they expect the effects to be mixed to * stereo. * - Floating point output provides headroom instead of hard clipping if the * module is louder than 0dBFs, will give you a better signal-to-noise ratio * than int16 output, and avoid the need to apply an additional dithering to the * output by libopenmpt. Unless your platform has no floating point unit at all, * floating point will thus also be slightly faster. * * \section libopenmpt_cpp_threads libopenmpt in multi-threaded environments * * - libopenmpt is thread-aware. * - Individual libopenmpt objects are not thread-safe. * - libopenmpt itself does not spawn any user-visible threads but may spawn * threads for internal use. * - You must ensure to only ever access a particular libopenmpt object via * non-const member functions from a single thread at a time. * - You may access a particular libopenmpt objects concurrently from different * threads when using only const member functions from all threads. * - Consecutive accesses can happen from different threads. * - Different objects can be accessed concurrently from different threads. * * \section libopenmpt-cpp-windows Windows support * * Using the libopenmpt C++ API when libopenmpt is compiled as a DLL on Windows * requires `#define LIBOPENMPT_USE_DLL` (or some equivalent build system * configuration) before `#include ` in order to * correctly import the symbols from the DLL. * * \section libopenmpt-cpp-detailed Detailed documentation * * \ref libopenmpt_cpp * * \section libopenmpt_cpp_examples Example * * \include libopenmpt_example_cxx.cpp * */ /*! \defgroup libopenmpt_cpp libopenmpt C++ */ /*! \addtogroup libopenmpt_cpp @{ */ namespace openmpt { #if defined(_MSC_VER) #pragma warning(push) #pragma warning(disable:4275) #endif //! libopenmpt exception base class /*! Base class used for all exceptions that are thrown by libopenmpt itself. Libopenmpt may additionally throw any exception thrown by the standard library which are all derived from std::exception. \sa \ref libopenmpt_cpp_error */ class LIBOPENMPT_CXX_API exception : public std::exception { private: char * text; public: exception( const std::string & text ) noexcept; exception( const exception & other ) noexcept; exception( exception && other ) noexcept; exception & operator = ( const exception & other ) noexcept; exception & operator = ( exception && other ) noexcept; virtual ~exception() noexcept; virtual const char * what() const noexcept; }; // class exception #if defined(_MSC_VER) #pragma warning(pop) #endif //! Get the libopenmpt version number /*! Returns the libopenmpt version number. \return The value represents (major << 24 + minor << 16 + patch << 0). \remarks libopenmpt < 0.3.0-pre used the following scheme: (major << 24 + minor << 16 + revision). */ LIBOPENMPT_CXX_API std::uint32_t get_library_version(); //! Get the core version number /*! Return the OpenMPT core version number. \return The value represents (majormajor << 24 + major << 16 + minor << 8 + minorminor). */ LIBOPENMPT_CXX_API std::uint32_t get_core_version(); namespace string { //! Return a verbose library version string from openmpt::string::get(). \deprecated Please use \code "library_version" \endcode directly. LIBOPENMPT_DEPRECATED static const char library_version LIBOPENMPT_ATTR_DEPRECATED [] = "library_version"; //! Return a verbose library features string from openmpt::string::get(). \deprecated Please use \code "library_features" \endcode directly. LIBOPENMPT_DEPRECATED static const char library_features LIBOPENMPT_ATTR_DEPRECATED [] = "library_features"; //! Return a verbose OpenMPT core version string from openmpt::string::get(). \deprecated Please use \code "core_version" \endcode directly. LIBOPENMPT_DEPRECATED static const char core_version LIBOPENMPT_ATTR_DEPRECATED [] = "core_version"; //! Return information about the current build (e.g. the build date or compiler used) from openmpt::string::get(). \deprecated Please use \code "build" \endcode directly. LIBOPENMPT_DEPRECATED static const char build LIBOPENMPT_ATTR_DEPRECATED [] = "build"; //! Return all contributors from openmpt::string::get(). \deprecated Please use \code "credits" \endcode directly. LIBOPENMPT_DEPRECATED static const char credits LIBOPENMPT_ATTR_DEPRECATED [] = "credits"; //! Return contact information about libopenmpt from openmpt::string::get(). \deprecated Please use \code "contact" \endcode directly. LIBOPENMPT_DEPRECATED static const char contact LIBOPENMPT_ATTR_DEPRECATED [] = "contact"; //! Return the libopenmpt license from openmpt::string::get(). \deprecated Please use \code "license" \endcode directly. LIBOPENMPT_DEPRECATED static const char license LIBOPENMPT_ATTR_DEPRECATED [] = "license"; //! Get library related metadata. /*! \param key Key to query. Possible keys are: - "library_version": verbose library version string - "library_version_major": libopenmpt major version number - "library_version_minor": libopenmpt minor version number - "library_version_patch": libopenmpt patch version number - "library_version_prerel": libopenmpt pre-release version string - "library_version_is_release": "1" if the version is an officially released version - "library_features": verbose library features string - "core_version": verbose OpenMPT core version string - "source_url": original source code URL - "source_date": original source code date - "source_revision": original source code revision - "source_is_modified": "1" if the original source has been modified - "source_has_mixed_revisions": "1" if the original source has been compiled from different various revision - "source_is_package": "1" if the original source has been obtained from a source pacakge instead of source code version control - "build": information about the current build (e.g. the build date or compiler used) - "build_compiler": information about the compiler used to build libopenmpt - "credits": all contributors - "contact": contact information about libopenmpt - "license": the libopenmpt license - "url": libopenmpt website URL - "support_forum_url": libopenmpt support and discussions forum URL - "bugtracker_url": libopenmpt bug and issue tracker URL \return A (possibly multi-line) string containing the queried information. If no information is available, the string is empty. */ LIBOPENMPT_CXX_API std::string get( const std::string & key ); } // namespace string //! Get a list of supported file extensions /*! \return The list of extensions supported by this libopenmpt build. The extensions are returned lower-case without a leading dot. */ LIBOPENMPT_CXX_API std::vector get_supported_extensions(); //! Query whether a file extension is supported /*! \param extension file extension to query without a leading dot. The case is ignored. \return true if the extension is supported by libopenmpt, false otherwise. */ LIBOPENMPT_CXX_API bool is_extension_supported( const std::string & extension ); //! Roughly scan the input stream to find out whether libopenmpt might be able to open it /*! \param stream Input stream to scan. \param effort Effort to make when validating stream. Effort 0.0 does not even look at stream at all and effort 1.0 completely loads the file from stream. A lower effort requires less data to be loaded but only gives a rough estimate answer. Use an effort of 0.25 to only verify the header data of the module file. \param log Log where warning and errors are written. \return Probability between 0.0 and 1.0. \remarks openmpt::probe_file_header() provides a simpler and faster interface that fits almost all use cases better. It is recommended to use openmpt::probe_file_header() instead of openmpt::could_open_probability(). \remarks openmpt::could_open_probability() can return any value between 0.0 and 1.0. Only 0.0 and 1.0 are definitive answers, all values in between are just estimates. In general, any return value >0.0 means that you should try loading the file, and any value below 1.0 means that loading may fail. If you want a threshold above which you can be reasonably sure that libopenmpt will be able to load the file, use >=0.5. If you see the need for a threshold below which you could reasonably outright reject a file, use <0.25 (Note: Such a threshold for rejecting on the lower end is not recommended, but may be required for better integration into some other framework's probe scoring.). \remarks openmpt::could_open_probability() expects the complete file data to be eventually available to it, even if it is asked to just parse the header. Verification will be unreliable (both false positives and false negatives), if you pretend that the file is just some few bytes of initial data threshold in size. In order to really just access the first bytes of a file, check in your std::istream implementation whether data or seeking is requested beyond your initial data threshold, and in that case, return an error. openmpt::could_open_probability() will treat this as any other I/O error and return 0.0. You must not expect the correct result in this case. You instead must remember that it asked for more data than you currently want to provide to it and treat this situation as if openmpt::could_open_probability() returned 0.5. \sa \ref libopenmpt_c_fileio \sa openmpt::probe_file_header() \since 0.3.0 */ LIBOPENMPT_CXX_API double could_open_probability( std::istream & stream, double effort = 1.0, std::ostream & log = std::clog ); //! Roughly scan the input stream to find out whether libopenmpt might be able to open it /*! \deprecated Please use openmpt::module::could_open_probability(). */ LIBOPENMPT_ATTR_DEPRECATED LIBOPENMPT_CXX_API LIBOPENMPT_DEPRECATED double could_open_propability( std::istream & stream, double effort = 1.0, std::ostream & log = std::clog ); //! Get recommended header size for successfull format probing /*! \sa openmpt::probe_file_header() \since 0.3.0 */ LIBOPENMPT_CXX_API std::size_t probe_file_header_get_recommended_size(); //! Probe for module formats in openmpt::probe_file_header(). \since 0.3.0 static const std::uint64_t probe_file_header_flags_modules = 0x1ul; //! Probe for module-specific container formats in openmpt::probe_file_header(). \since 0.3.0 static const std::uint64_t probe_file_header_flags_containers = 0x2ul; //! Probe for the default set of formats in openmpt::probe_file_header(). \since 0.3.0 static const std::uint64_t probe_file_header_flags_default = probe_file_header_flags_modules | probe_file_header_flags_containers; //! Probe for no formats in openmpt::probe_file_header(). \since 0.3.0 static const std::uint64_t probe_file_header_flags_none = 0x0ul; //! Possible return values for openmpt::probe_file_header(). \since 0.3.0 enum probe_file_header_result { probe_file_header_result_success = 1, probe_file_header_result_failure = 0, probe_file_header_result_wantmoredata = -1 }; //! Probe the provided bytes from the beginning of a file for supported file format headers to find out whether libopenmpt might be able to open it /*! \param flags Ored mask of openmpt::probe_file_header_flags_modules and openmpt::probe_file_header_flags_containers, or openmpt::probe_file_header_flags_default. \param data Beginning of the file data. \param size Size of the beginning of the file data. \param filesize Full size of the file data on disk. \remarks It is recommended to provide openmpt::probe_file_header_get_recommended_size() bytes of data for data and size. If the file is smaller, only provide the filesize amount and set size and filesize to the file's size. \remarks openmpt::could_open_probability() provides a more elaborate interface that might be required for special use cases. It is recommended to use openmpt::probe_file_header() though, if possible. \retval probe_file_header_result_success The file will most likely be supported by libopenmpt. \retval probe_file_header_result_failure The file is not supported by libopenmpt. \retval probe_file_header_result_wantmoredata An answer could not be determined with the amount of data provided. \sa openmpt::probe_file_header_get_recommended_size() \sa openmpt::could_open_probability() \since 0.3.0 */ LIBOPENMPT_CXX_API int probe_file_header( std::uint64_t flags, const std::uint8_t * data, std::size_t size, std::uint64_t filesize ); //! Probe the provided bytes from the beginning of a file for supported file format headers to find out whether libopenmpt might be able to open it /*! \param flags Ored mask of openmpt::probe_file_header_flags_modules and openmpt::probe_file_header_flags_containers, or openmpt::probe_file_header_flags_default. \param data Beginning of the file data. \param size Size of the beginning of the file data. \remarks It is recommended to use the overload of this function that also takes the filesize as parameter if at all possile. libopenmpt can provide more accurate answers if the filesize is known. \remarks It is recommended to provide openmpt::probe_file_header_get_recommended_size() bytes of data for data and size. If the file is smaller, only provide the filesize amount and set size to the file's size. \remarks openmpt::could_open_probability() provides a more elaborate interface that might be required for special use cases. It is recommended to use openmpt::probe_file_header() though, if possible. \retval probe_file_header_result_success The file will most likely be supported by libopenmpt. \retval probe_file_header_result_failure The file is not supported by libopenmpt. \retval probe_file_header_result_wantmoredata An answer could not be determined with the amount of data provided. \sa openmpt::probe_file_header_get_recommended_size() \sa openmpt::could_open_probability() \since 0.3.0 */ LIBOPENMPT_CXX_API int probe_file_header( std::uint64_t flags, const std::uint8_t * data, std::size_t size ); //! Probe the provided bytes from the beginning of a file for supported file format headers to find out whether libopenmpt might be able to open it /*! \param flags Ored mask of openmpt::probe_file_header_flags_modules and openmpt::probe_file_header_flags_containers, or openmpt::probe_file_header_flags_default. \param stream Input stream to scan. \remarks stream is left in an unspecified state when this function returns. \remarks openmpt::could_open_probability() provides a more elaborate interface that might be required for special use cases. It is recommended to use openmpt::probe_file_header() though, if possible. \retval probe_file_header_result_success The file will most likely be supported by libopenmpt. \retval probe_file_header_result_failure The file is not supported by libopenmpt. \retval probe_file_header_result_wantmoredata An answer could not be determined with the amount of data provided. \sa openmpt::probe_file_header_get_recommended_size() \sa openmpt::could_open_probability() \since 0.3.0 */ LIBOPENMPT_CXX_API int probe_file_header( std::uint64_t flags, std::istream & stream ); class module_impl; class module_ext; namespace detail { typedef std::map< std::string, std::string > initial_ctls_map; } // namespace detail class LIBOPENMPT_CXX_API module { friend class module_ext; public: //! Parameter index to use with openmpt::module::get_render_param and openmpt::module::set_render_param enum render_param { //! Master Gain /*! The related value represents a relative gain in milliBel.\n The default value is 0.\n The supported value range is unlimited.\n */ RENDER_MASTERGAIN_MILLIBEL = 1, //! Stereo Separation /*! The related value represents the stereo separation generated by the libopenmpt mixer in percent.\n The default value is 100.\n The supported value range is [0,200].\n */ RENDER_STEREOSEPARATION_PERCENT = 2, //! Interpolation Filter /*! The related value represents the interpolation filter length used by the libopenmpt mixer.\n The default value is 0, which indicates a recommended default value.\n The supported value range is [0,inf). Values greater than the implementation limit are clamped to the maximum supported value.\n Currently supported values: - 0: internal default - 1: no interpolation (zero order hold) - 2: linear interpolation - 4: cubic interpolation - 8: windowed sinc with 8 taps */ RENDER_INTERPOLATIONFILTER_LENGTH = 3, //! Volume Ramping Strength /*! The related value represents the amount of volume ramping done by the libopenmpt mixer.\n The default value is -1, which indicates a recommended default value.\n The meaningful value range is [-1..10].\n A value of 0 completely disables volume ramping. This might cause clicks in sound output.\n Higher values imply slower/softer volume ramps. */ RENDER_VOLUMERAMPING_STRENGTH = 4 }; //! Parameter index to use with openmpt::module::get_pattern_row_channel_command, openmpt::module::format_pattern_row_channel_command and openmpt::module::highlight_pattern_row_channel_command enum command_index { command_note = 0, command_instrument = 1, command_volumeffect = 2, command_effect = 3, command_volume = 4, command_parameter = 5 }; private: module_impl * impl; private: // non-copyable module( const module & ); void operator = ( const module & ); private: // for module_ext module(); void set_impl( module_impl * i ); public: //! Construct an openmpt::module /*! \param stream Input stream from which the module is loaded. After the constructor has finished successfully, the input position of stream is set to the byte after the last byte that has been read. If the constructor fails, the state of the input position of stream is undefined. \param log Log where any warnings or errors are printed to. The lifetime of the reference has to be as long as the lifetime of the module instance. \param ctls A map of initial ctl values, see openmpt::module::get_ctls. \throws openmpt::exception Throws an exception derived from openmpt::exception in case the provided file cannot be opened. \remarks The input data can be discarded after an openmpt::module has been constructed successfully. \sa \ref libopenmpt_cpp_fileio */ module( std::istream & stream, std::ostream & log = std::clog, const std::map< std::string, std::string > & ctls = detail::initial_ctls_map() ); /*! \param data Data to load the module from. \param log Log where any warnings or errors are printed to. The lifetime of the reference has to be as long as the lifetime of the module instance. \param ctls A map of initial ctl values, see openmpt::module::get_ctls. \throws openmpt::exception Throws an exception derived from openmpt::exception in case the provided file cannot be opened. \remarks The input data can be discarded after an openmpt::module has been constructed successfully. \sa \ref libopenmpt_cpp_fileio */ module( const std::vector & data, std::ostream & log = std::clog, const std::map< std::string, std::string > & ctls = detail::initial_ctls_map() ); /*! \param beg Begin of data to load the module from. \param end End of data to load the module from. \param log Log where any warnings or errors are printed to. The lifetime of the reference has to be as long as the lifetime of the module instance. \param ctls A map of initial ctl values, see openmpt::module::get_ctls. \throws openmpt::exception Throws an exception derived from openmpt::exception in case the provided file cannot be opened. \remarks The input data can be discarded after an openmpt::module has been constructed successfully. \sa \ref libopenmpt_cpp_fileio */ module( const std::uint8_t * beg, const std::uint8_t * end, std::ostream & log = std::clog, const std::map< std::string, std::string > & ctls = detail::initial_ctls_map() ); /*! \param data Data to load the module from. \param size Amount of data available. \param log Log where any warnings or errors are printed to. The lifetime of the reference has to be as long as the lifetime of the module instance. \param ctls A map of initial ctl values, see openmpt::module::get_ctls. \throws openmpt::exception Throws an exception derived from openmpt::exception in case the provided file cannot be opened. \remarks The input data can be discarded after an openmpt::module has been constructed successfully. \sa \ref libopenmpt_cpp_fileio */ module( const std::uint8_t * data, std::size_t size, std::ostream & log = std::clog, const std::map< std::string, std::string > & ctls = detail::initial_ctls_map() ); /*! \param data Data to load the module from. \param log Log where any warnings or errors are printed to. The lifetime of the reference has to be as long as the lifetime of the module instance. \param ctls A map of initial ctl values, see openmpt::module::get_ctls. \throws openmpt::exception Throws an exception derived from openmpt::exception in case the provided file cannot be opened. \remarks The input data can be discarded after an openmpt::module has been constructed successfully. \sa \ref libopenmpt_cpp_fileio */ module( const std::vector & data, std::ostream & log = std::clog, const std::map< std::string, std::string > & ctls = detail::initial_ctls_map() ); /*! \param beg Begin of data to load the module from. \param end End of data to load the module from. \param log Log where any warnings or errors are printed to. The lifetime of the reference has to be as long as the lifetime of the module instance. \param ctls A map of initial ctl values, see openmpt::module::get_ctls. \throws openmpt::exception Throws an exception derived from openmpt::exception in case the provided file cannot be opened. \remarks The input data can be discarded after an openmpt::module has been constructed successfully. \sa \ref libopenmpt_cpp_fileio */ module( const char * beg, const char * end, std::ostream & log = std::clog, const std::map< std::string, std::string > & ctls = detail::initial_ctls_map() ); /*! \param data Data to load the module from. \param size Amount of data available. \param log Log where any warnings or errors are printed to. The lifetime of the reference has to be as long as the lifetime of the module instance. \param ctls A map of initial ctl values, see openmpt::module::get_ctls. \throws openmpt::exception Throws an exception derived from openmpt::exception in case the provided file cannot be opened. \remarks The input data can be discarded after an openmpt::module has been constructed successfully. \sa \ref libopenmpt_cpp_fileio */ module( const char * data, std::size_t size, std::ostream & log = std::clog, const std::map< std::string, std::string > & ctls = detail::initial_ctls_map() ); /*! \param data Data to load the module from. \param size Amount of data available. \param log Log where any warnings or errors are printed to. The lifetime of the reference has to be as long as the lifetime of the module instance. \param ctls A map of initial ctl values, see openmpt::module::get_ctls. \throws openmpt::exception Throws an exception derived from openmpt::exception in case the provided file cannot be opened. \remarks The input data can be discarded after an openmpt::module has been constructed successfully. \sa \ref libopenmpt_cpp_fileio */ module( const void * data, std::size_t size, std::ostream & log = std::clog, const std::map< std::string, std::string > & ctls = detail::initial_ctls_map() ); virtual ~module(); public: //! Select a sub-song from a multi-song module /*! \param subsong Index of the sub-song. -1 plays all sub-songs consecutively. \throws openmpt::exception Throws an exception derived from openmpt::exception if sub-song is not in range [-1,openmpt::module::get_num_subsongs()[ \sa openmpt::module::get_num_subsongs, openmpt::module::get_selected_subsong, openmpt::module::get_subsong_names \remarks Whether subsong -1 (all subsongs consecutively), subsong 0 or some other subsong is selected by default, is an implementation detail and subject to change. If you do not want to care about subsongs, it is recommended to just not call openmpt::module::select_subsong() at all. */ void select_subsong( std::int32_t subsong ); //! Get currently selected sub-song from a multi-song module /*! \return Currently selected sub-song. -1 for all subsongs consecutively, 0 or greater for the current sub-song index. \sa openmpt::module::get_num_subsongs, openmpt::module::select_subsong, openmpt::module::get_subsong_names \since 0.3.0 */ std::int32_t get_selected_subsong() const; //! Set Repeat Count /*! \param repeat_count Repeat Count - -1: repeat forever - 0: play once, repeat zero times (the default) - n>0: play once and repeat n times after that \sa openmpt::module::get_repeat_count */ void set_repeat_count( std::int32_t repeat_count ); //! Get Repeat Count /*! \return Repeat Count - -1: repeat forever - 0: play once, repeat zero times (the default) - n>0: play once and repeat n times after that \sa openmpt::module::set_repeat_count */ std::int32_t get_repeat_count() const; //! Get approximate song duration /*! \return Approximate duration of current sub-song in seconds. */ double get_duration_seconds() const; //! Set approximate current song position /*! \param seconds Seconds to seek to. If seconds is out of range, the position gets set to song start or end respectively. \return Approximate new song position in seconds. \sa openmpt::module::get_position_seconds */ double set_position_seconds( double seconds ); //! Get current song position /*! \return Current song position in seconds. \sa openmpt::module::set_position_seconds */ double get_position_seconds() const; //! Set approximate current song position /*! If order or row are out of range, to position is not modified and the current position is returned. \param order Pattern order number to seek to. \param row Pattern row number to seek to. \return Approximate new song position in seconds. \sa openmpt::module::set_position_seconds \sa openmpt::module::get_position_seconds */ double set_position_order_row( std::int32_t order, std::int32_t row ); //! Get render parameter /*! \param param Parameter to query. See openmpt::module::render_param. \return The current value of the parameter. \throws openmpt::exception Throws an exception derived from openmpt::exception if param is invalid. \sa openmpt::module::render_param \sa openmpt::module::set_render_param */ std::int32_t get_render_param( int param ) const; //! Set render parameter /*! \param param Parameter to set. See openmpt::module::render_param. \param value The value to set param to. \throws openmpt::exception Throws an exception derived from openmpt::exception if param is invalid or value is out of range. \sa openmpt::module::render_param \sa openmpt::module::get_render_param */ void set_render_param( int param, std::int32_t value ); /*@{*/ //! Render audio data /*! \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. \param count Number of audio frames to render per channel. \param mono Pointer to a buffer of at least count elements that receives the mono/center output. \return The number of frames actually rendered. \retval 0 The end of song has been reached. \remarks The output buffers are only written to up to the returned number of elements. \remarks You can freely switch between any of the "read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. \remarks It is recommended to use the floating point API because of the greater dynamic range and no implied clipping. \sa \ref libopenmpt_cpp_outputformat */ std::size_t read( std::int32_t samplerate, std::size_t count, std::int16_t * mono ); //! Render audio data /*! \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. \param count Number of audio frames to render per channel. \param left Pointer to a buffer of at least count elements that receives the left output. \param right Pointer to a buffer of at least count elements that receives the right output. \return The number of frames actually rendered. \retval 0 The end of song has been reached. \remarks The output buffers are only written to up to the returned number of elements. \remarks You can freely switch between any of the "read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. \remarks It is recommended to use the floating point API because of the greater dynamic range and no implied clipping. \sa \ref libopenmpt_cpp_outputformat */ std::size_t read( std::int32_t samplerate, std::size_t count, std::int16_t * left, std::int16_t * right ); //! Render audio data /*! \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. \param count Number of audio frames to render per channel. \param left Pointer to a buffer of at least count elements that receives the left output. \param right Pointer to a buffer of at least count elements that receives the right output. \param rear_left Pointer to a buffer of at least count elements that receives the rear left output. \param rear_right Pointer to a buffer of at least count elements that receives the rear right output. \return The number of frames actually rendered. \retval 0 The end of song has been reached. \remarks The output buffers are only written to up to the returned number of elements. \remarks You can freely switch between any of the "read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. \remarks It is recommended to use the floating point API because of the greater dynamic range and no implied clipping. \sa \ref libopenmpt_cpp_outputformat */ std::size_t read( std::int32_t samplerate, std::size_t count, std::int16_t * left, std::int16_t * right, std::int16_t * rear_left, std::int16_t * rear_right ); //! Render audio data /*! \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. \param count Number of audio frames to render per channel. \param mono Pointer to a buffer of at least count elements that receives the mono/center output. \return The number of frames actually rendered. \retval 0 The end of song has been reached. \remarks The output buffers are only written to up to the returned number of elements. \remarks You can freely switch between any of the "read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. \remarks Floating point samples are in the [-1.0..1.0] nominal range. They are not clipped to that range though and thus might overshoot. \sa \ref libopenmpt_cpp_outputformat */ std::size_t read( std::int32_t samplerate, std::size_t count, float * mono ); //! Render audio data /*! \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. \param count Number of audio frames to render per channel. \param left Pointer to a buffer of at least count elements that receives the left output. \param right Pointer to a buffer of at least count elements that receives the right output. \return The number of frames actually rendered. \retval 0 The end of song has been reached. \remarks The output buffers are only written to up to the returned number of elements. \remarks You can freely switch between any of the "read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. \remarks Floating point samples are in the [-1.0..1.0] nominal range. They are not clipped to that range though and thus might overshoot. \sa \ref libopenmpt_cpp_outputformat */ std::size_t read( std::int32_t samplerate, std::size_t count, float * left, float * right ); //! Render audio data /*! \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. \param count Number of audio frames to render per channel. \param left Pointer to a buffer of at least count elements that receives the left output. \param right Pointer to a buffer of at least count elements that receives the right output. \param rear_left Pointer to a buffer of at least count elements that receives the rear left output. \param rear_right Pointer to a buffer of at least count elements that receives the rear right output. \return The number of frames actually rendered. \retval 0 The end of song has been reached. \remarks The output buffers are only written to up to the returned number of elements. \remarks You can freely switch between any of the "read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. \remarks Floating point samples are in the [-1.0..1.0] nominal range. They are not clipped to that range though and thus might overshoot. \sa \ref libopenmpt_cpp_outputformat */ std::size_t read( std::int32_t samplerate, std::size_t count, float * left, float * right, float * rear_left, float * rear_right ); //! Render audio data /*! \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. \param count Number of audio frames to render per channel. \param interleaved_stereo Pointer to a buffer of at least count*2 elements that receives the interleaved stereo output in the order (L,R). \return The number of frames actually rendered. \retval 0 The end of song has been reached. \remarks The output buffers are only written to up to the returned number of elements. \remarks You can freely switch between any of the "read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. \remarks It is recommended to use the floating point API because of the greater dynamic range and no implied clipping. \sa \ref libopenmpt_cpp_outputformat */ std::size_t read_interleaved_stereo( std::int32_t samplerate, std::size_t count, std::int16_t * interleaved_stereo ); //! Render audio data /*! \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. \param count Number of audio frames to render per channel. \param interleaved_quad Pointer to a buffer of at least count*4 elements that receives the interleaved suad surround output in the order (L,R,RL,RR). \return The number of frames actually rendered. \retval 0 The end of song has been reached. \remarks The output buffers are only written to up to the returned number of elements. \remarks You can freely switch between any of the "read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. \remarks It is recommended to use the floating point API because of the greater dynamic range and no implied clipping. \sa \ref libopenmpt_cpp_outputformat */ std::size_t read_interleaved_quad( std::int32_t samplerate, std::size_t count, std::int16_t * interleaved_quad ); //! Render audio data /*! \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. \param count Number of audio frames to render per channel. \param interleaved_stereo Pointer to a buffer of at least count*2 elements that receives the interleaved stereo output in the order (L,R). \return The number of frames actually rendered. \retval 0 The end of song has been reached. \remarks The output buffers are only written to up to the returned number of elements. \remarks You can freely switch between any of the "read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. \remarks Floating point samples are in the [-1.0..1.0] nominal range. They are not clipped to that range though and thus might overshoot. \sa \ref libopenmpt_cpp_outputformat */ std::size_t read_interleaved_stereo( std::int32_t samplerate, std::size_t count, float * interleaved_stereo ); //! Render audio data /*! \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. \param count Number of audio frames to render per channel. \param interleaved_quad Pointer to a buffer of at least count*4 elements that receives the interleaved suad surround output in the order (L,R,RL,RR). \return The number of frames actually rendered. \retval 0 The end of song has been reached. \remarks The output buffers are only written to up to the returned number of elements. \remarks You can freely switch between any of the "read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. \remarks Floating point samples are in the [-1.0..1.0] nominal range. They are not clipped to that range though and thus might overshoot. \sa \ref libopenmpt_cpp_outputformat */ std::size_t read_interleaved_quad( std::int32_t samplerate, std::size_t count, float * interleaved_quad ); /*@}*/ //! Get the list of supported metadata item keys /*! \return Metadata item keys supported by openmpt::module::get_metadata \sa openmpt::module::get_metadata */ std::vector get_metadata_keys() const; //! Get a metadata item value /*! \param key Metadata item key to query. Use openmpt::module::get_metadata_keys to check for available keys. Possible keys are: - type: Module format extension (e.g. it) - type_long: Tracker name associated with the module format (e.g. Impulse Tracker) - container: Container format the module file is embedded in, if any (e.g. umx) - container_long: Full container name if the module is embedded in a container (e.g. Unreal Music) - tracker: Tracker that was (most likely) used to save the module file, if known - artist: Author of the module - title: Module title - date: Date the module was last saved, in ISO-8601 format. - message: Song message. If the song message is empty or the module format does not support song messages, a list of instrument and sample names is returned instead. - message_raw: Song message. If the song message is empty or the module format does not support song messages, an empty string is returned. - warnings: A list of warnings that were generated while loading the module. \return The associated value for key. \sa openmpt::module::get_metadata_keys */ std::string get_metadata( const std::string & key ) const; //! Get the current speed /*! \return The current speed in ticks per row. */ std::int32_t get_current_speed() const; //! Get the current tempo /*! \return The current tempo in tracker units. The exact meaning of this value depends on the tempo mode being used. */ std::int32_t get_current_tempo() const; //! Get the current order /*! \return The current order at which the module is being played back. */ std::int32_t get_current_order() const; //! Get the current pattern /*! \return The current pattern that is being played. */ std::int32_t get_current_pattern() const; //! Get the current row /*! \return The current row at which the current pattern is being played. */ std::int32_t get_current_row() const; //! Get the current amount of playing channels. /*! \return The amount of sample channels that are currently being rendered. */ std::int32_t get_current_playing_channels() const; //! Get an approximate indication of the channel volume. /*! \param channel The channel whose volume should be retrieved. \return The approximate channel volume. \remarks The returned value is solely based on the note velocity and does not take the actual waveform of the playing sample into account. */ float get_current_channel_vu_mono( std::int32_t channel ) const; //! Get an approximate indication of the channel volume on the front-left speaker. /*! \param channel The channel whose volume should be retrieved. \return The approximate channel volume. \remarks The returned value is solely based on the note velocity and does not take the actual waveform of the playing sample into account. */ float get_current_channel_vu_left( std::int32_t channel ) const; //! Get an approximate indication of the channel volume on the front-right speaker. /*! \param channel The channel whose volume should be retrieved. \return The approximate channel volume. \remarks The returned value is solely based on the note velocity and does not take the actual waveform of the playing sample into account. */ float get_current_channel_vu_right( std::int32_t channel ) const; //! Get an approximate indication of the channel volume on the rear-left speaker. /*! \param channel The channel whose volume should be retrieved. \return The approximate channel volume. \remarks The returned value is solely based on the note velocity and does not take the actual waveform of the playing sample into account. */ float get_current_channel_vu_rear_left( std::int32_t channel ) const; //! Get an approximate indication of the channel volume on the rear-right speaker. /*! \param channel The channel whose volume should be retrieved. \return The approximate channel volume. \remarks The returned value is solely based on the note velocity and does not take the actual waveform of the playing sample into account. */ float get_current_channel_vu_rear_right( std::int32_t channel ) const; //! Get the number of sub-songs /*! \return The number of sub-songs in the module. This includes any "hidden" songs (songs that share the same sequence, but start at different order indices) and "normal" sub-songs or "sequences" (if the format supports them). \sa openmpt::module::get_subsong_names, openmpt::module::select_subsong, openmpt::module::get_selected_subsong */ std::int32_t get_num_subsongs() const; //! Get the number of pattern channels /*! \return The number of pattern channels in the module. Not all channels do necessarily contain data. \remarks The number of pattern channels is completely independent of the number of output channels. libopenmpt can render modules in mono, stereo or quad surround, but the choice of which of the three modes to use must not be made based on the return value of this function, which may be any positive integer amount. Only use this function for informational purposes. */ std::int32_t get_num_channels() const; //! Get the number of orders /*! \return The number of orders in the current sequence of the module. */ std::int32_t get_num_orders() const; //! Get the number of patterns /*! \return The number of distinct patterns in the module. */ std::int32_t get_num_patterns() const; //! Get the number of instruments /*! \return The number of instrument slots in the module. Instruments are a layer on top of samples, and are not supported by all module formats. */ std::int32_t get_num_instruments() const; //! Get the number of samples /*! \return The number of sample slots in the module. */ std::int32_t get_num_samples() const; //! Get a list of sub-song names /*! \return All sub-song names. \sa openmpt::module::get_num_subsongs, openmpt::module::select_subsong, openmpt::module::get_selected_subsong */ std::vector get_subsong_names() const; //! Get a list of channel names /*! \return All channel names. \sa openmpt::module::get_num_channels */ std::vector get_channel_names() const; //! Get a list of order names /*! \return All order names. \sa openmpt::module::get_num_orders */ std::vector get_order_names() const; //! Get a list of pattern names /*! \return All pattern names. \sa openmpt::module::get_num_patterns */ std::vector get_pattern_names() const; //! Get a list of instrument names /*! \return All instrument names. \sa openmpt::module::get_num_instruments */ std::vector get_instrument_names() const; //! Get a list of sample names /*! \return All sample names. \sa openmpt::module::get_num_samples */ std::vector get_sample_names() const; //! Get pattern at order position /*! \param order The order item whose pattern index should be retrieved. \return The pattern index found at the given order position of the current sequence. */ std::int32_t get_order_pattern( std::int32_t order ) const; //! Get the number of rows in a pattern /*! \param pattern The pattern whose row count should be retrieved. \return The number of rows in the given pattern. If the pattern does not exist, 0 is returned. */ std::int32_t get_pattern_num_rows( std::int32_t pattern ) const; //! Get raw pattern content /*! \param pattern The pattern whose data should be retrieved. \param row The row from which the data should be retrieved. \param channel The channel from which the data should be retrieved. \param command The cell index at which the data should be retrieved. See openmpt::module::command_index \return The internal, raw pattern data at the given pattern position. */ std::uint8_t get_pattern_row_channel_command( std::int32_t pattern, std::int32_t row, std::int32_t channel, int command ) const; //! Get formatted (human-readable) pattern content /*! \param pattern The pattern whose data should be retrieved. \param row The row from which the data should be retrieved. \param channel The channel from which the data should be retrieved. \param command The cell index at which the data should be retrieved. \return The formatted pattern data at the given pattern position. See openmpt::module::command_index \sa openmpt::module::highlight_pattern_row_channel_command */ std::string format_pattern_row_channel_command( std::int32_t pattern, std::int32_t row, std::int32_t channel, int command ) const; //! Get highlighting information for formatted pattern content /*! \param pattern The pattern whose data should be retrieved. \param row The row from which the data should be retrieved. \param channel The channel from which the data should be retrieved. \param command The cell index at which the data should be retrieved. See openmpt::module::command_index \return The highlighting string for the formatted pattern data as retrieved by openmpt::module::get_pattern_row_channel_command at the given pattern position. \remarks The returned string will map each character position of the string returned by openmpt::module::get_pattern_row_channel_command to a highlighting instruction. Possible highlighting characters are: - " " : empty/space - "." : empty/dot - "n" : generic note - "m" : special note - "i" : generic instrument - "u" : generic volume column effect - "v" : generic volume column parameter - "e" : generic effect column effect - "f" : generic effect column parameter \sa openmpt::module::get_pattern_row_channel_command */ std::string highlight_pattern_row_channel_command( std::int32_t pattern, std::int32_t row, std::int32_t channel, int command ) const; //! Get formatted (human-readable) pattern content /*! \param pattern The pattern whose data should be retrieved. \param row The row from which the data should be retrieved. \param channel The channel from which the data should be retrieved. \param width The maximum number of characters the string should contain. 0 means no limit. \param pad If true, the string will be resized to the exact length provided in the width parameter. \return The formatted pattern data at the given pattern position. \sa openmpt::module::highlight_pattern_row_channel */ std::string format_pattern_row_channel( std::int32_t pattern, std::int32_t row, std::int32_t channel, std::size_t width = 0, bool pad = true ) const; //! Get highlighting information for formatted pattern content /*! \param pattern The pattern whose data should be retrieved. \param row The row from which the data should be retrieved. \param channel The channel from which the data should be retrieved. \param width The maximum number of characters the string should contain. 0 means no limit. \param pad If true, the string will be resized to the exact length provided in the width parameter. \return The highlighting string for the formatted pattern data as retrieved by openmpt::module::format_pattern_row_channel at the given pattern position. \sa openmpt::module::format_pattern_row_channel */ std::string highlight_pattern_row_channel( std::int32_t pattern, std::int32_t row, std::int32_t channel, std::size_t width = 0, bool pad = true ) const; //! Retrieve supported ctl keys /*! \return A vector containing all supported ctl keys. \remarks Currently supported ctl values are: - load.skip_samples: Set to "1" to avoid loading samples into memory - load.skip_patterns: Set to "1" to avoid loading patterns into memory - load.skip_plugins: Set to "1" to avoid loading plugins - load.skip_subsongs_init: Set to "1" to avoid pre-initializing sub-songs. Skipping results in faster module loading but slower seeking. - seek.sync_samples: Set to "1" to sync sample playback when using openmpt::module::set_position_seconds or openmpt::module::set_position_order_row. - subsong: The current subsong. Setting it has identical semantics as openmpt::module::select_subsong(), getting it returns the currently selected subsong. - play.tempo_factor: Set a floating point tempo factor. "1.0" is the default tempo. - play.pitch_factor: Set a floating point pitch factor. "1.0" is the default pitch. - render.resampler.emulate_amiga: Set to "1" to enable the Amiga resampler for Amiga modules. This emulates the sound characteristics of the Paula chip and overrides the selected interpolation filter. Non-Amiga module formats are not affected by this setting. - dither: Set the dither algorithm that is used for the 16 bit versions of openmpt::module::read. Supported values are: - 0: No dithering. - 1: Default mode. Chosen by OpenMPT code, might change. - 2: Rectangular, 0.5 bit depth, no noise shaping (original ModPlug Tracker). - 3: Rectangular, 1 bit depth, simple 1st order noise shaping An exclamation mark ("!") or a question mark ("?") can be appended to any ctl key in order to influence the behaviour in case of an unknown ctl key. "!" causes an exception to be thrown; "?" causes the ctl to be silently ignored. In case neither is appended to the key name, unknown init_ctls are ignored by default and other ctls throw an exception by default. */ std::vector get_ctls() const; //! Get current ctl value /*! \param ctl The ctl key whose value should be retrieved. \return The associated ctl value. \sa openmpt::module::get_ctls */ std::string ctl_get( const std::string & ctl ) const; //! Set ctl value /*! \param ctl The ctl key whose value should be set. \param value The value that should be set. \throws openmpt::exception Throws an exception derived from openmpt::exception in case the value is not sensible (e.g. negative tempo factor) or under the circumstances outlined in openmpt::module::get_ctls. \sa openmpt::module::get_ctls */ void ctl_set( const std::string & ctl, const std::string & value ); // remember to add new functions to both C and C++ interfaces and to increase OPENMPT_API_VERSION_MINOR }; // class module } // namespace openmpt /*! @} */ #endif // LIBOPENMPT_HPP libopenmpt-0.3.6+release.autotools/libopenmpt/libopenmpt_stream_callbacks_file.h0000644000372100037210000000467512723023742025340 00000000000000/* * libopenmpt_stream_callbacks_file.h * ---------------------------------- * Purpose: libopenmpt public c interface * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #ifndef LIBOPENMPT_STREAM_CALLBACKS_FILE_H #define LIBOPENMPT_STREAM_CALLBACKS_FILE_H #include "libopenmpt.h" #include #include #include #include #ifdef _MSC_VER #include /* off_t */ #endif #ifdef __cplusplus extern "C" { #endif /* This stuff has to be in a header file because of possibly different MSVC CRTs which cause problems for FILE * crossing CRT boundaries. */ static size_t openmpt_stream_file_read_func( void * stream, void * dst, size_t bytes ) { FILE * f = 0; size_t retval = 0; f = (FILE*)stream; if ( !f ) { return 0; } retval = fread( dst, 1, bytes, f ); if ( retval <= 0 ) { return 0; } return retval; } static int openmpt_stream_file_seek_func( void * stream, int64_t offset, int whence ) { FILE * f = 0; int fwhence = 0; f = (FILE*)stream; if ( !f ) { return -1; } switch ( whence ) { #if defined(SEEK_SET) case OPENMPT_STREAM_SEEK_SET: fwhence = SEEK_SET; break; #endif #if defined(SEEK_CUR) case OPENMPT_STREAM_SEEK_CUR: fwhence = SEEK_CUR; break; #endif #if defined(SEEK_END) case OPENMPT_STREAM_SEEK_END: fwhence = SEEK_END; break; #endif default: return -1; break; } #if defined(_MSC_VER) return _fseeki64( f, offset, fwhence ) ? -1 : 0; #elif defined(_POSIX_SOURCE) && (_POSIX_SOURCE == 1) return fseeko( f, offset, fwhence ) ? -1 : 0; #else return fseek( f, offset, fwhence ) ? -1 : 0; #endif } static int64_t openmpt_stream_file_tell_func( void * stream ) { FILE * f = 0; int64_t retval = 0; f = (FILE*)stream; if ( !f ) { return -1; } #if defined(_MSC_VER) retval = _ftelli64( f ); #elif defined(_POSIX_SOURCE) && (_POSIX_SOURCE == 1) retval = ftello( f ); #else retval = ftell( f ); #endif if ( retval < 0 ) { return -1; } return retval; } static openmpt_stream_callbacks openmpt_stream_get_file_callbacks(void) { openmpt_stream_callbacks retval; memset( &retval, 0, sizeof( openmpt_stream_callbacks ) ); retval.read = openmpt_stream_file_read_func; retval.seek = openmpt_stream_file_seek_func; retval.tell = openmpt_stream_file_tell_func; return retval; } #ifdef __cplusplus } #endif #endif /* LIBOPENMPT_STREAM_CALLBACKS_FILE_H */ libopenmpt-0.3.6+release.autotools/libopenmpt/dox/0000755000372100037210000000000013235362226017305 500000000000000libopenmpt-0.3.6+release.autotools/libopenmpt/dox/index.dox0000644000372100037210000000232113233130322021032 00000000000000 /*! * \mainpage Contents * * libopenmpt is a cross-platform C++ and C library to decode tracked music files (modules) into a raw PCM audio stream. * * libopenmpt is based on the player code of the Open ModPlug Tracker project (OpenMPT, https://openmpt.org/) * * \section toc Contents * - \ref quickstart "Quick Start" * - \ref md_README "README" * - \ref dependencies "Dependencies" * - \ref packaging "Packaging" * - \ref tests "Tests" * - \ref changelog "Changelog" * - \ref todo "TODO" * \subsection toc_apis APIs * - libopenmpt * - \ref libopenmpt "Common Details" * - libopenmpt C++ * - \ref libopenmpt_cpp_overview "Overview" * - \ref libopenmpt_cpp "Details" * - libopenmpt C * - \ref libopenmpt_c_overview "Overview" * - \ref libopenmpt_c "Details" * - libopenmpt_ext C++ * - \ref libopenmpt_ext_cpp_overview "Overview" * - \ref libopenmpt_ext_cpp "Details" * - libopenmpt_ext C * - \ref libopenmpt_ext_c_overview "Overview" * - \ref libopenmpt_ext_c "Details" * * \section toc_website Website * https://lib.openmpt.org/ * * \section toc_license License * \include LICENSE * */ libopenmpt-0.3.6+release.autotools/libopenmpt/dox/quickstart.md0000644000372100037210000000463113077073155021751 00000000000000 Quick Start {#quickstart} =========== ### Autotools-based 1. Grab a `libopenmpt-VERSION.autotools.tar.gz` tarball. 2. Get dependencies: - **gcc >= 4.8** or **clang >= 3.4** - **pkg-config >= 0.24** - **zlib** - **libogg**, **libvorbis**, **libvorbisfile** - **libmpg123 >= 1.13.0** - **doxygen >= 1.8** - **libpulse**, **libpulse-simple** (required only by openmpt123) - **portaudio-v19** (required only by openmpt123) - **libFLAC** (required only by openmpt123) - **libsndfile** (required only by openmpt123) 3. *Optional*: - **libSDL >= 1.2.x** (required only by openmpt123) 4. Run: ./configure make make check sudo make install ### Windows 1. Get dependencies: - **Microsoft Visual Studio >= 2015** 2. *Optionally* get dependencies: - **Winamp SDK** - **XMPlay SDK** 3. Checkout `https://source.openmpt.org/svn/openmpt/trunk/OpenMPT/` . 4. Open `build\vs2015\openmpt123.sln` or `build\vs2015\libopenmpt.sln` or `build\vs2015\xmp-openmpt.sln` or `build\vs2015\in_openmpt.sln` or `build\vs2015\foo_openmpt.sln` in *Microsoft Visual Studio 2015*. 5. Select appropriate configuration and build. Binaries are generated in `bin\` 6. Drag a module onto `openmpt123.exe` or copy the player plugin DLLs (`in_openmpt.dll`, `xmp-openmpt.dll` or `foo_openmpt.dll`) into the respective player directory. ### Unix-like 1. Get dependencies: - **GNU make** - **gcc >= 4.8** or **clang >= 3.4** - **pkg-config** - **zlib** - **libogg**, **libvorbis**, **libvorbisfile** - **libmpg123 >= 1.13.0** - **libpulse**, **libpulse-simple** (required only by openmpt123) - **portaudio-v19** (required only by openmpt123) - **libFLAC** (required only by openmpt123) - **libsndfile** (required only by openmpt123) 2. *Optional*: - **libSDL >= 1.2.x** (required only by openmpt123) - **doxygen >= 1.8** - **help2man** 3. Run: svn checkout https://source.openmpt.org/svn/openmpt/trunk/OpenMPT/ openmpt-trunk cd openmpt-trunk make clean make make doc make check sudo make install # installs into /usr/local by default sudo make install-doc # installs into /usr/local by default sudo ldconfig # required on some systems (i.e. Linux) openmpt123 $SOMEMODULE libopenmpt-0.3.6+release.autotools/libopenmpt/dox/tests.md0000644000372100037210000000155513135616236020721 00000000000000 Tests {#tests} ===== libopenmpt provides some basic unit tests that check the platform for general sanity and do some basic internal functionality testing. The test suite requires a special libopenmpt build that includes file saving functionality which is not included in normal builds. This is handled by all provided build systems automatically. ### Running Tests #### On Unix-like systems Compile with make $YOURMAKEOPTIONS clean make $YOURMAKEOPTIONS and run make $YOURMAKEOPTIONS check As the build system retains no state between make invocations, you have to provide your make options on every make invocation. #### Autotools-based build system ./configure make check #### On Windows Using Visual Studio 20??, compile build\vs20??\libopenmpt_test.sln and run bin\$ARCH\libopenmpt_test.exe from the root of the source tree. libopenmpt-0.3.6+release.autotools/libopenmpt/dox/changelog.md0000644000372100037210000010270213235361343021477 00000000000000 Changelog {#changelog} ========= For fully detailed change log, please see the source repository directly. This is just a high-level summary. ### libopenmpt 0.3.6 (2018-02-03) * [**Sec**] Possible out-of-bounds memory read with malformed STP files. (r9576) * [**Bug**] Small memory leak with malformed STP files. * STM: Accurate emulation of Scream Tracker 2 tempo mode. * STM: Better support for early format revisions (no such files have been found in the wild, though). * Fine volume slides are now supported when seeking with seek.sync_samples=1 enabled. ### libopenmpt 0.3.5 (2018-01-28) * [**New**] Support MOD files from the Inconexia demo by Iguana. * [**Bug**] xmp-openmpt: Saved settings were not applied instantly. * XM E60 loop bug was not considered in song length calucation. * Tighten M15 and MOD file rejection heuristics. * J2B: Ignore frequency limits from file header. Fixes Medivo.j2b, broken since libopenmpt-0.2.6401-beta17. * STM: Last character of sample name was missing. * ParamEq plugin center frequency was not limited correctly. * libopenmpt_ext C API was not included in the documentation. ### libopenmpt 0.3.4 (2017-12-17) * IT: Fix broken volume envelopes with negative values as found in breakdwn.it by Elysis. ### libopenmpt 0.3.3 (2017-11-19) * [**New**] foo_openmpt: foo_openmpt now also works on Windows XP. * [**Bug**] All VS2015 and VS2017 project files targetting Windows XP did not set compiler option `/Zc:threadSafeInit-` which caused at least the player plugins `in_openmpt` and `xmp-openmpt` to fail to load. ### libopenmpt 0.3.2 (2017-11-04) * [**New**] Autotools `configure` and plain `Makefile` now honor the variable `CXXSTDLIB_PCLIBSPRIVATE` which serves the sole purpose of listing the standard library (or libraries) required for static linking. The contents of this variable will be put in `libopenmpt.pc` `Libs.private` and used for nothing else. See \ref libopenmpt_c_staticlinking . * [**Change**] Windows bin and dev release packages now use zip archives instead of 7z archives as it had originally been intended for the 0.3.0 release. * [**Change**] openmpt123: The following combinations of options are now deprecated because they made no real sense in the first place: `--render --output`, `--ui --output-type`, `--batch --output-type` * [**Bug**] libopenmpt did not build on Android NDK 15c (and possibly other versions between 12b and 15c as well). * IT: In Compatible Gxx mode, allow sample changes next to a tone portamento effect if a previous sample has already stopped playing. * MOD: Slides and delayed notes are executed on every repetition of a row with row delay (fixes "ode to protracker"). ### libopenmpt 0.3.1 (2017-09-28) * [**Bug**] Windows: libopenmpt resource did not compile for release versions. ### libopenmpt 0.3.0 (2017-09-27, not released) * [**New**] New error handling functionality in the C API, which in particular allows distinguishing potentially transient out-of-memory errors from parse errors during module loading. * [**New**] New API `openmpt::module::get_selected_subsong()` (C++) and `openmpt_module_get_selected_subsong()` (C). * [**New**] Faster file header probing API `openmpt::probe_file_header()` and `openmpt::probe_file_header_get_recommended_size` (C++), and `openmpt_probe_file_header()`, `openmpt_probe_file_header_without_filesize()`, `openmpt_probe_file_header_from_stream()` and `openmpt_probe_file_header_get_recommended_size()` (C). * [**New**] New API `openmpt::could_open_probability()` (C++) and `openmpt_could_open_probability()` (C). This fixes a spelling error in the old 0.2 API. * [**New**] openmpt123: openmpt123 can now open M3U, M3U8, M3UEXT, M3U8EXT and PLSv2 playlists via the `--playlist` option. * [**New**] openmpt123: openmpt123 now supports very fast file header probing via the `--probe` option. * [**New**] Libopenmpt now supports building for Windows 10 Universal (Windows Store 8.2) APIs with MSVC, and also for the older Windows Runtime APIs with MinGW-w64. * [**New**] New API header `libopenmpt_ext.h` which implements the libopenmpt extension APIs also for the C interface. * [**New**] The Reverb effect (S99 in S3M/IT/MPTM, and X99 in XM) is now implemented in libopenmpt. * [**New**] For Amiga modules, a new resampler based on the Amiga's sound characteristics has been added. It can be activated by passing the `render.resampler.emulate_amiga` ctl with a value of `1`. Non-Amiga modules are not affected by this, and setting the ctl overrides the resampler choice specified by `OPENMPT_MODULE_RENDER_INTERPOLATIONFILTER_LENGTH` or `openmpt::module::RENDER_INTERPOLATIONFILTER_LENGTH`. Support for the MOD command E0x (Set LED Filter) is also available when the Amiga resampler is enabled. * [**Change**] libopenmpt versioning changed and follows the more conventional major.minor.patch as well as the recommendations of the [SemVer](http://semver.org/) scheme now. In addition to the SemVer requirements, pre-1.0.0 versions will also honor API and ABI stability in libopenmpt (i.e. libopenmpt ignores SemVer Clause 4). * [**Change**] The output directories of the MSVC build system were changed to `bin/vs2015-shared/x86-64-win7/` (and similar) layout which allows building in the same tree with different compiler versions without overwriting other outputs. * [**Change**] The emscripten build now exports libopenmpt as 'libopenmpt' instead of the default 'Module'. * [**Change**] Android: The build system changed. The various Android.mk files have been merged into a single one which can be controlled using command line options. * [**Change**] The `Makefile` build system now passes `std=c++11` to the compiler by default. Older compilers may still work if you pass `STDCXX=c++0x` to the `make` invocation. * [**Change**] The `Makefile` option `ANCIENT=1` is gone. * [**Change**] The optional dependencies on `libltdl` or `libdl` are gone. They are no longer needed for any functionality. * [**Regression**] Compiling client code using the C++ API now requires a compiler running in C++11 mode. * [**Regression**] Support for GCC 4.1, 4.2, 4.3, 4.4, 4.5, 4.6, 4.7 has been removed. * [**Regression**] Support for Clang 3.0, 3.1, 3.2, 3.3 has been removed. * [**Regression**] Support for Emscripten versions older than 1.31.0 has been removed. * [**Regression**] Support for Android NDK versions older than 11 has been removed. * [**Regression**] Visual Studio 2008, 2010, 2012, 2013 support has been removed. * [**Regression**] Dynamic run-time loading of libmpg123 is no longer supported. Libmpg123 must be linked at link-time now. * [**Regression**] xmp-openmpt: xmp-openmpt now requires XMPlay 3.8 or later and compiling xmp-openmpt requires an appropriate XMPlay SDK with `XMPIN_FACE` >= `4`. * [**Regression**] Support for libmpg123 older than 1.13.0 has been removed. * [**Regression**] Un4seen unmo3 support has been removed. * [**Bug**] C++ API: `openmpt::exception` did not define copy and move constructors or copy and move assignment operators in libopenmpt 0.2. The compiler-generated ones were not adequate though. libopenmpt 0.3 adds the appropriate special member functions. This adds the respective symbol names to the exported ABI, which, depending on the compiler, might or might not have been there in libopenmpt 0.2. The possibly resulting possible ODR violation only affects cases that did crash in the libopenmpt 0.2 API anyway due to memory double-free, and does not cause any further problems in practice for all known platforms and compilers. * [**Bug**] The C API could crash instead of failing gracefully in out-of-memory situations. * [**Bug**] The test suite could fail on MacOSX or FreeBSD in non-fatal ways when no locale was active. * [**Bug**] `libopenmpt_stream_callbacks_fd.h` and `libopenmpt_stream_callbacks_file.h` were missing in Windows development packages. * [**Bug**] libopenmpt on Windows did not properly guard against current working directory DLL injection attacks. * [**Bug**] localtime() was used to determine the version of Schism Tracker used to save IT and S3M files. This function is not guaranteed to be thread-safe by the standard and is now no longer used. * [**Bug**] Possible crashes with malformed IT, ITP, AMS, MDL, MED, MPTM, PSM and Startrekker files. * [**Bug**] Possible hangs with malformed DBM, MPTM and PSM files. * [**Bug**] Possible hangs with malformed files containing cyclic plugin routings. * [**Bug**] Excessive loading times with malformed ITP / truncated AMS files. * [**Bug**] Plugins did not work correctly when changing the sample rate between two render calls. * [**Bug**] Possible NULL-pointer dereference read during obscure out-of-memory situations while handling exceptions in the C API. * [**Bug**] libmodplug: `libmodplug.pc` was wrong. * [**Bug**] Cross-compiling libopenmpt with autotools for Windows now properly sets `-municode` and `-mconsole` as well as all required Windows system libraries. * [**Bug**] foo_openmpt: Interpolation filter and volume ramping settings were confused in previous versions. This version resets both to the defaults. * [**Bug**] libmodplug: The CSoundFile::Read function in the emulated libmodplug C++ API returned the wrong value, causing qmmp (and possibly other software) to crash. * Support for SoundTracker Pro II (STP) and Digital Tracker (DTM) modules. * Increased accuracy of the sample position and sample rate to drift less when playing very long samples. * Various playback improvements for IT and XM files. * Channel frequency could wrap around after some excessive portamento / down in some formats since libopenmpt 0.2-beta17. * Playback improvements for S3M files made with Impulse Tracker and Schism Tracker. * ParamEq plugin emulation didn't do anything at full gain (+15dB). * All standard DMO effects are now also emulated on non-Windows and non-MSVC systems. * Added `libopenmpt_stream_callbacks_buffer.h` which adds `openmpt_stream_callbacks` support for in-memory buffers, possibly even only using a truncated prefix view into a bigger file which is useful for probing. * Avoid enabling some ProTracker-specific quirks for MOD files most likely created with ScreamTracker 3. * Tremolo effect only had half the intended strength in MOD files. * Pattern loops ending on the last row a pattern were not executed correctly in S3M files. * Work-around for reading MIDI macros and plugin settings in some malformed IT files written by old UNMO3 versions. * Improve tracker detection in IT format. * Playback fixes for 8-channel MED files * Do not set note volume to 0 on out-of-range offset in XM files. * Better import of some slide commands in SFX files. * Sample 15 in "Crew Generation" by Necros requires short loops at the beginning of the sample to not be ignored. Since we need to ignore them in some (non-ProTracker) modules, we heuristically disable the old loop sanitization behaviour based on the module channel count. * Both normal and percentage offset in PLM files were handled as percentage offset. * MT2 files with instruments that had both sample and plugin assignments were not read correctly. * Some valid FAR files were rejected erroneously. * Support for VBlank timing flag and comment field in PT36 files. * Improved accuracy of vibrato command in DIGI / DBM files. * STM: Add support for "WUZAMOD!" magic bytes and allow some slightly malformed STM files to load which were previously rejected. * Detect whether "hidden" patterns in the order list of SoundTracker modules should be taken into account or not. * Tighten heuristics for rejecting invalid 669, M15, MOD and ICE files and loosen them in other places to allow some valid MOD files to load. * Improvements to seeking: Channel panning was not always updated from instruments / samples when seeking, and out-of-range global volume was not applied correctly in some formats. * seek.sync_samples=1 did not apply PTM reverse offset effect and the volume slide part of combined volume slide + vibrato commands. * If the order list was longer than 256 items and there was a pattern break effect without a position jump on the last pattern of the sequence, it did not jump to the correct restart order. * `Makefile` has now explicit support for FreeBSD with no special option or configuration required. * openmpt123: Improved section layout in man page. * libmodplug: Added all missing C++ API symbols that are accessible via the public libmodplug header file. * Autotools build system now has options `--disable-openmpt123`, `--disable-tests` and `--disable-examples` which may be desireable when cross-compiling. * Windows binary packages now ship with libmpg123 included. ### libopenmpt 0.2-beta20 (2016-08-07) * [**Bug**] PSM loader was broken on big-endian platforms since forever. * [**Bug**] `load.skip_samples` ctl did not work for PSM16 modules. * There is a new `subsong` ctl, which can return the currently selected subsong. * More accurate ProTracker arpeggio wrap-around emulation. * More accurate sample tuning in PSM16 files. * Samples in DSM files were sometimes detuned and some pattern commands were not imported correctly. * More accurate import of MDL 7-bit panning command. * Only import pattern commands supported by the UltraTracker version that was used to save ULT files. Add support for command 5-C (end loop). * DMF sample loop lengths were off by one. * Unis 669 pan slide effect was too deep. * Several valid (but slightly corrupted possibly due to disk failures or data transfer errors) SoundTracker files were no longer loading since libopenmpt 0.2-beta18. ### libopenmpt 0.2-beta19 (2016-07-23) * [**Change**] libopenmpt now uses C++14 `[[deprecated]]` attribute instead of compiler-specific solutions when appropriate. * [**Change**] libopenmpt C++ header now uses C++11 `noexcept` instead of C++98 `throw()` exception specification when supported. `throw()` is deprecated since C++11. This does not change API or ABI as they are equivalent. Use `LIBOPENMPT_ASSUME_CPLUSPLUS_NOEXCEPT` to override the default. * [**Change**] The preprocessor macro `LIBOPENMPT_ANCIENT_COMPILER_STDINT` is gone. Please use `LIBOPENMPT_ASSUME_CPLUSPLUS_CSTDINT instead`. Additionally, the typedefs moved from illegal namespace ::std into somewhat less dangerous namespace ::openmpt::std. You can test `#ifdef LIBOPENMPT_QUIRK_NO_CSTDINT` client-side to check whether `libopenmpt.hpp` used the non-standard types. (Note: Of all supported compilers, this change only affects the 3 compilers with only limited support: MSVC 2008, GCC 4.1, GCC 4.2.) * [**Bug**] xmp-openmpt: Crash when viewing sample texts. * The public libopenmpt C++ header has auto-detection logic for the used C++ standard now. In case your client code compiler misreports the standard version or you want to override it for other reasons, `#define LIBOPENMPT_ASSUME_CPLUSPLUS` to the value of the standard version you desire to be used. There is also a macro for each individual aspect, like `LIBOPENMPT_ASSUME_CPLUSPLUS_CSTDINT`, `LIBOPENMPT_ASSUME_CPLUSPLUS_DEPRECATED`, `LIBOPENMPT_ASSUME_CPLUSPLUS_NOEXCEPT` which take precedence over the general macro. * Portamento with sample swap behaviour was wrong for ProTracker MODs. * Rewritten loader and various playback fixes for MDL files. * libopenmpt 0.2-beta18 broke import of many pattern commands in DBM, DMF and ULT files. * ADPCM samples in MOD files were broken since libopenmpt 0.2-beta17. ### libopenmpt 0.2-beta18 (2016-07-11) * [**Change**] openmpt123: Add PulseAudio output support. Autotools and `Makefile` build systems now depend on `libpulse` and `libpulse-simple` by default. Disable with `--without-pulseaudio` or `NO_PULSEAUDIO=1` respectively. When enabled, PulseAudio will be the default output driver, * [**Change**] xmp-openmpt: Settings are now stored in xmplay.ini like with every other plugin. * [**Regression**] openmpt123: Support for FLAC < 1.3.0 has been removed. FLAC before 1.3.0 is broken beyond repair as it provides `assert.h` in the include path. * [**Bug**] Generated pkg-config file libopenmpt.pc by both `Makefile` and Autotools build systems was totally broken. * [**Bug**] libopenmpt no longer uses the non-thread-safe global std::rand() function. * [**Bug**] Sample loops in GDM modules did not work when using Emscripten. * [**Bug**] XM and MO3 loaders could crash due to unaligned memory accesses. * [**Bug**] Fixed incorrect handling of custom MPTM tunings on big endian platforms. * [**Bug**] Fixed various problems found with clang 3.8 static analyzer, address sanitizer and undefined behaviour sanitizer. * [**Bug**] File header probing functionality was broken for most formats. * [**Bug**] With non-seekable streams, the entire file was almost always cached even if it was not of any supported module type. * Seeking in allsubsongs-mode now works correctly. * openmpt123: Added subsong support. * Various playback fixes for 669, IT, MT2 and MTM files. * Some MOD files with more than 128 patterns (e.g. NIETNU.MOD) were not loaded correctly. * A new example `libopenmpt_example_c_probe` has been added which demonstrates the usage and flexibility of openmpt_could_open_propability() in the C API under various constraints. ### libopenmpt 0.2-beta17 (2016-05-21) * [**Change**] The Makefile and Autotools build systems now require to explicitly specify `NO_LTDL=1` or `--without-ltdl` respectively if no support for dynamic loading of third party libraries via libtool libltdl is desired. * [**Change**] In the Makefile build system option `USE_MO3` and the Autotools build system option `--enable-mo3` are gone. Dynamic loading of un4seen unmo3 is now always enabled when dynamic loading is possible and built-in MO3 support is not possible because either a MP3 or a Vorbis decoder is missing. * [**Change**] The MSVC build system changed. The `libopenmptDLL` project is gone. Use the new `ReleaseShared` configuration of the `libopenmpt` project instead. libopenmpt now links against zlib by default. A separate project with smaller footprint linking against miniz is still available as `libopenmpt-small`. * [**Change**] The constants used to query library information from `openmpt_get_string()` and `openmpt::string::get()` (i.e. OPENMPT_STRING_FOO and openmpt::string::FOO) have been deprecated because having syntactic constants for theses keys makes extending the API in a backwards and forwards compatible way harder than it should be. Please just use the string literals directly. * [**Change**] Deprecated API identifiers will now cause deprecation warnings with MSVC, GCC and clang. `#define LIBOPENMPT_NO_DEPRECATE` to disable the warnings. * [**Change**] openmpt123: `--[no-]shuffle` option has been renamed to `--[no-]randomize`. A new `--[no-]shuffle` option has been added which shuffles randomly through the playlist as opposed to randomizing the playlist upfront. * [**Change**] Support for Un4seen unmo3 has generally been deprecated in favour of the new internal mo3 decoder. Un4seen unmo3 support will be removed on 2018-01-01. * [**Bug**] Memory consumption during loading has been reduced by about 1/3 in case a seekable input stream is provided (either via C API callback open functions or via C++ API iostream constructors). * [**Bug**] Some samples in AMS modules were detuned when using Emscripten. * [**Bug**] Possible crash with excessive portamento down in some formats. * [**Bug**] Possible crashes with malformed AMF, AMS, DBM, IT, MDL, MED, MPTM, MT2, PSM and MMCMP-, XPK- and PP20-compressed files. * [**Bug**] `openmpt::module::format_pattern_row_channel` with `width == 0` was returning an empty string instead of an string with unconstrained length. * Support for ProTracker 3.6 IFF-style modules and SoundFX / MultiMedia Sound (SFX / MMS) modules. * libopenmpt now has support for DMO plugins on Windows when built with MSVC. Additionally, the DMO Compression, Distortion, Echo, Gargle, ParamEQ and WavesReverb DSPs are emulated on on all other platforms. * libopenmpt now supports the DigiBooster Echo DSP. * To avoid any of the aforementioned plugins to be used, the load.skip_plugins ctl can be passed when loading a module. * libopenmpt got native MO3 support with MP3 decoding either via libmpg123 or MediaFoundation (on Windows 7 and up) and Vorbis decoding via libogg, libvorbis, libvorbisfile or stb_vorbis. * libopenmpt MSVC builds with Visual Studio 2010 or later on Windows 7 or later now use an internal MO3 decoder with libogg, libvorbis, libvorbisfile, and libmpg123 or minimp3 or MediaFoundation suppport by default. Visual Studio 2008 builds still use unmo3.dll by default but also support the built-in decoder in which case libmpg123 is required. * libopenmpt with Makefile or Autotools build system can now also use glibc/libdl instead of libtool/libltdl for dynamic loading of third-party libraries. Options `NO_DL=1` and `--without-dl` have been added respectively. * The `Makefile` build system got 4 new options NO_MPG123, NO_OGG, NO_VORBIS, NO_VORBISFILE. The default is to use the new dependencies automatically. * The `Autotools` build system got 4 new options --without-mpg123, --without-ogg, --without-vorbis, --without-vorbisfile. The default is to use the new dependencies automatically. * Makefile and Android builds got support for using minimp3 instead of libmpg123. For Android, use `Android-minimp3-stbvorbis.mk`, for Makefile use `USE_MINIMP3=1`. You have to download [minimp3](http://keyj.emphy.de/minimp3/) yourself and put its contents into `include/minimp3/`. * `"source_url"`, `"source_date"` and `"build_compiler"` keys have been added to `openmpt_string_get()` and `openmpt::string::get()`. * openmpt123: Add new `--[no-]restart]` option which restarts the playlist when finished. * Improved Ultimate SoundTracker version detection heuristics. * Playing a sample at a sample rate close to the mix rate could lead to small clicks when using vibrato. * More fine-grained internal legacy module compatibility settings to correctly play back modules made with older versions of OpenMPT and a few other trackers. * The tail of compressed MDL samples was slightly off. * Some probably hex-edited XM files (e.g. cybernostra weekend.xm) were not loaded correctly. * Countless other playback fixes for MOD, XM, S3M, IT and MT2 files. ### libopenmpt 0.2-beta16 (2015-11-22) * [**Change**] The Autotools build system does strict checking of all dependencies now. Instead of best effort auto-magic detection of all potentially optional dependencies, the default set of dependencies is now enforced unless each individual dependency gets explicitely disabled via `--without-foo` or `--disable-foo` `./configure` switches. Run `./configure --help` for the full list of options. * [**Bug**] Some MOD files were erroneously detected as 669 files. * [**Bug**] Some malformed AMF files could result in very long loading times. * [**Bug**] Fixed crashes in IMF and MT2 loaders. * [**Bug**] MTM files generated by UNMO3 were not loaded properly. * Improved MTM playback. * `make CONFIG=haiku` for Haiku has been added. * Language bindings for FreeBASIC have been added (see `libopenmpt/bindings/`). ### libopenmpt 0.2-beta15 (2015-10-31) * [**Change**] openmpt123: SDL2 is now supported and preferred to SDL1 if available with the `Makefile` build system. * [**Bug**] Emscripten support for older emscripten versions broke in -beta14. These are now supported again when using `make CONFIG=emscripten-old`. * [**Bug**] Fixed crashes in MED loader. * Playback improvements and loader fixes for MOD, MT2 and MED. ### libopenmpt 0.2-beta14 (2015-09-13) * [**Change**] The C++ API example now uses the PortAudio C++ bindings instead of the C API. * [**Change**] Default compiler options for Emscripten have been changed to more closely match the Emscripten recommendations. * [**Bug**] Client code compilation with C89 compilers was broken in beta13. * [**Bug**] Test suite failed on certain Emscripten/node.js combinations. * [**Bug**] Fixed various crashes or hangs in DMF, OKT, PLM, IT and MPTM loaders. * Implemented error handling in the libopenmpt API examples. * Various playback improvements and fixes for OKT, IT and MOD. ### libopenmpt 0.2-beta13 (2015-08-16) * [**Change**] The MSVC build system has been redone. Solutions are now located in `build/vsVERSION/`. * [**Bug**] get_current_channel_vu_left and get_current_channel_vu_right only return the volume of the front left and right channels now. get_current_channel_vu_rear_left and get_current_channel_vu_rear_right do now actually work and return non-zero values. * [**Bug**] Fix crashes and hangs in MED and MDL loaders and with some truncated compressed IT samples. * [**Bug**] Fix crash when playing extremely high-pitched samples. * Completed C and C++ documentation * Added new key for openmpt::module::get_metadata, "message_raw", which returns an empty string if there is no song message rather than a list of instrument names. * in_openmpt: Support for compiling with VS2008. * xmp-openmpt: Support for compiling with VS2008. * in_openmpt: Add a more readable file information window. ### libopenmpt 0.2-beta12 (2015-04-19) * Playback fix when row delay effect is used together with offset command. * A couple of fixes for the seek.sync_samples=1 case. * IT compatibility fix for IT note delay. * ProTracker MOD playback compatibility improvement. ### libopenmpt 0.2-beta11 (2015-04-18) * [**Change**] openmpt_stream_seek_func() now gets called with OPENMPT_STREAM_SEEK_SET, OPENMPT_STREAM_SEEK_CUR and OPENMPT_STREAM_SEEK_END whence parameter instead of SEEK_SET, SEEK_CUR and SEEK_END. These are defined to 0, 1 and 2 respectively which corresponds to the definition in all common C libraries. If your C library uses different constants, this theoretically breaks binary compatibility. The old libopenmpt code, however, never actually called the seek function, thus, there will be no problem in practice. * [**Change**] openmpt123: When both SDL1.2 and PortAudio are available, SDL is now the preferred backend because SDL is more widespread and better tested on all kinds of different platforms, and in general, SDL is just more reliable. * [**Bug**] libopenmpt now also compiles with GCC 4.3. * libopenmpt now supports PLM (Disorder Tracker 2) files. * Various playback improvements and fixes for IT, S3M, XM, MOD, PTM and 669 files. ### libopenmpt 0.2-beta10 (2015-02-17) * [**Change**] Makefile configuration filenames changed from `build/make/Makefile.config.*` to `build/make/config-*.mk`. * [**Change**] libopenmpt for Android now supports unmo3 from un4seen. See `build/android_ndk/README.AndroidNDK.txt` for details. * [**Bug**] Fix out-of-bounds read in mixer code for ProTracker-compatible MOD files which was introduced back in r4223 / beta6. * Vibrato effect was too weak in beta8 and beta9 in IT linear slide mode. * Very small fine portamento was wrong in beta8 and beta9 in IT linear slide mode. * Tiny IT playback compatibility improvements. * STM playback improvements. ### libopenmpt 0.2-beta9 (2014-12-21) * [**Bug**] libopenmpt_ext.hpp was missing from the Windows binary zip files. ### libopenmpt 0.2-beta8 (2014-12-21) * [**Change**] foo_openmpt: Settings are now accessible via foobar2000 advanced settings. * [**Change**] Autotools based build now supports libunmo3. Specify --enable-unmo3. * [**Change**] Support for dynamic loading of libunmo3 on MacOS X. * [**Change**] libopenmpt now uses libltld (from libtool) for dynamic loading of libunmo3 on all non-Windows platforms. * [**Change**] Support for older compilers: * GCC 4.1.x to 4.3.x (use `make ANCIENT=1`) * Microsoft Visual Studio 2008 (with latest Service Pack) (see `build/vs2008`) * [**Change**] libopenmpt_ext.hpp is now distributed by default. The API is still considered experimental and not guaranteed to stay API or ABI compatible. * [**Change**] xmp-openmpt / in_openmpt: No more libopenmpt_settings.dll. The settings dialog now uses a statically linked copy of MFC. * [**Bug**] The -autotools tarballs were not working at all. * Vastly improved MT2 loader. * Improved S3M playback compatibility. * Added openmpt::ext::interactive, an extension which adds a whole bunch of new functionality to change playback in some way or another. * Added possibility to sync sample playback when using openmpt::module::set_position_* by setting the ctl value seek.sync_samples=1 * Support for "hidden" subsongs has been added. They are accessible through the same interface as ordinary subsongs, i.e. use openmpt::module::select_subsong to switch between any kind of subsongs. * All subsongs can now be played consecutively by passing -1 as the subsong index in openmpt::module::select_subsong. * Added documentation for a couple of more functions. ### libopenmpt 0.2-beta7 (2014-09-07) * [**Change**] libopenmpt now has an GNU Autotools based build system (in addition to all previously supported ways of building libopenmpt). Autotools support is packaged separately as tarballs ending in `-autotools.tar.gz`. * [**Bug**] The distributed windows .zip file did not include pugixml. * [**Regression**] openmpt123: Support for writing WavPack (.wv) files has been removed. Reasoning: 1. WavPack support was incomplete and did not include support for writing WavPack metadata at all. 2. openmpt123 already supports libSndFile which can be used to write uncompressed lossless WAV files which can then be encoded to whatever format the user desires with other tools. ### libopenmpt 0.2-beta6 (2014-09-06) * [**Change**] openmpt123: SDL is now also used by default if availble, in addition to PortAudio. * [**Change**] Support for emscripten is no longer experimental. * [**Change**] libopenmpt itself can now also be compiled with VS2008. * [**Bug**] Fix all known crashes on platforms that do not support unaligned memory access. * [**Bug**] openmpt123: Effect column was always missing in pattern display. ### libopenmpt 0.2-beta5 (2014-06-15) * [**Change**] Add unmo3 support for non-Windows builds. * [**Change**] Namespace all internal functions in order to allow statically linking against libopenmpt without risking duplicate symbols. * [**Change**] Iconv is now completely optional and only used on Linux systems by default. * [**Change**] Added libopenmpt_example_c_stdout.c, an example without requiring PortAudio. * [**Change**] Add experimental support for building libopenmpt with emscripten. * [**Bug**] Fix ping-pong loop behaviour which broke in 0.2-beta3. * [**Bug**] Fix crashes when accessing invalid patterns through libopenmpt API. * [**Bug**] Makefile: Support building with missing optional dependencies without them being stated explicitely. * [**Bug**] openmpt123: Crash when quitting while playback is stopped. * [**Bug**] openmpt123: Crash when writing output to a file in interactive UI mode. * [**Bug**] openmpt123: Wrong FLAC output filename in --render mode. * Various smaller playback accuracy improvements. ### libopenmpt 0.2-beta4 (2014-02-25) * [**Bug**] Makefile: Dependency tracking for the test suite did not work. ### libopenmpt 0.2-beta3 (2014-02-21) * [**Change**] The test suite is now built by default with Makefile based builds. Use `TEST=0` to skip building the tests. `make check` runs the test suite. * [**Bug**] Crash in MOD and XM loaders on architectures not supporting unaligned memory access. * [**Bug**] MMCMP, PP20 and XPK unpackers should now work on non-x86 hardware and implement proper bounds checking. * [**Bug**] openmpt_module_get_num_samples() returned the wrong value. * [**Bug**] in_openmpt: DSP plugins did not work properly. * [**Bug**] in_openmpt/xmp-openmpt: Setting name for stereo separation was misspelled. This version will revert your stereo separation settings to default. * [**Bug**] Crash when loading some corrupted modules with stereo samples. * Support building on Android NDK. * Avoid clicks in sample loops when using interpolation. * IT filters are now done in integer instead of floating point. This improves performance, especially on architectures with no or a slow FPU. * MOD pattern break handling fixes. * Various XM playback improvements. * Improved and switchable dithering when using 16bit integer API. ### libopenmpt 0.2-beta2 (2014-01-12) * [**Bug**] MT2 loader crash. * [**Bug**] Saving settings in in_openmpt and xmp-openmpt did not work. * [**Bug**] Load libopenmpt_settings.dll also from below Plugins directory in Winamp. * DBM playback improvements. ### libopenmpt 0.2-beta1 (2013-12-31) * First release. libopenmpt-0.3.6+release.autotools/libopenmpt/dox/dependencies.md0000644000372100037210000000731413150526300022171 00000000000000 Dependencies {#dependencies} ============ Dependencies ------------ ### libopenmpt * Supported compilers for building libopenmpt: * **Microsoft Visual Studio 2015** or higher * **GCC 4.8** or higher * **Clang 3.4** or higher * **MinGW-W64 4.8** or higher * **emscripten 1.31** or higher * any other **C++11 compliant** compiler (full standard compliant mode is known to work with GCC >= 5.1 and Clang >= 3.5) libopenmpt makes the following assumptions about the C++ implementation used for building: * `CHAR_BIT == 8` (enforced by static_assert) * `sizeof(char) == 1` (enforced by static_assert) * existence of `std::uintptr_t` (enforced by static_assert) * `sizeof(float) == 4` (enforced by static_assert) * `sizeof(double) == 8` (enforced by static_assert) * if `__BYTE_ORDER__` is provided by the compiler and `__STDC_IEC_559__ == 1`, the endianness of integers is the same as the endianness of floats (implicitly assumed) * `wchar_t` encoding is either UTF-16 or UTF-32 (implicitly assumed) * representation of basic source character set is ASCII (implicitly assumed) * representation of basic source character set is identical in char and `wchar_t` (implicitly assumed) libopenmpt does not rely on any specific implementation defined or undefined behaviour (if it does, that's a bug in libopenmpt). In particular: * `char` can be `signed` or `unsigned` * shifting signed values is implementation defined * `float` and `double` can be non-IEEE754 * Required compilers to use libopenmpt: * Any **C89** / **C99** / **C11** compatible compiler should work with the C API as long as a **C99** compatible **stdint.h** is available. * Any **C++11** / **C++14** / **C++17** compatible compiler should work with the C++ API. * **J2B** support requires an inflate (deflate decompression) implementation: * **zlib** * **miniz** can be used internally if no zlib is available. * Built-in **MO3** support requires: * **libmpg123 >= 1.13.0** * **libogg** * **libvorbis** * **libvorbisfile** * Alternatively, **Media Foundation** can be used on Windows 7 or later instead of libmpg123 to decode mp3 samples. It's also possible to use **minimp3**. * Instead of libogg, libvorbis and libvorbisfile, **stb_vorbis** can be used internally to decode Vorbis samples. * Building on Unix-like systems requires: * **GNU make** * **pkg-config** * The Autotools-based build system requires: * **pkg-config 0.24** or higher * **zlib** * **doxygen** ### openmpt123 * Supported compilers for building openmpt123: * **Microsoft Visual Studio 2015** or higher * **GCC 4.8** or higher * **Clang 3.4** or higher * **MinGW-W64 4.8** or higher * any **C++11 compliant** compiler * Live sound output requires one of: * **PulseAudio** * **SDL 2** * **SDL 1.2** * **PortAudio v19** * **Win32** Optional dependencies --------------------- ### libopenmpt * Character set conversion can use one of: * **Win32** * **iconv** * **C++11** codecvt_utf8 instead of the internal conversion tables and functions. * **doxygen 1.8** or higher is required to build the documentation. ### openmpt123 * Rendering to PCM files can use: * **FLAC 1.2** or higher * **libsndfile** * **Win32** for WAVE * raw PCM has no external dependencies * **help2man** is required to build the documentation. libopenmpt-0.3.6+release.autotools/libopenmpt/dox/todo.md0000644000372100037210000000022412640455722020515 00000000000000 TODO {#todo} ==== See the roadmap in the bug tracker at [https://bugs.openmpt.org/roadmap_page.php](https://bugs.openmpt.org/roadmap_page.php). libopenmpt-0.3.6+release.autotools/libopenmpt/dox/packaging.md0000644000372100037210000000350013234320412021457 00000000000000Packaging {#packaging} ========= Packaging --------- ### Packaging recommendations for distribution package maintainers * libopenmpt (since 0.3) uses SemVer 2.0.0 versioning. See [semver.org](https://semver.org/spec/v2.0.0.html). Clause 4 is ignored for libopenmpt, which means that libopenmpt will also provide API/ABI compatbility semantics for pre-1.0.0 versions as required by SemVer 2.0.0 only for post-1.0.0 versions. The SemVer versioning scheme is incompatible with Debian/Ubuntu package versions, however it can easily be processed to be compatible by replacing '-' (hyphen) with '~' (tilde). It is recommended that you use this exact transformation if required. * Use the autotools source package. * Use the default set of dependencies required by the autotools package. * Read \ref libopenmpt_c_staticlinking and thus possibly pass `CXXSTDLIB_PCLIBSPRIVATE` variable to `configure` if appropriate and/or desired. * Run the test suite in your build process. * Send any build system improvement patches upstream. * Do not include the libmodplug emulation layer in the default libopenmpt binary package. Either do not package it at all, or provide a separate package named libopenmpt-modplug or libmodplug-openmpt (or similar), which depends on libopenmpt, provides libmodplug, and conflicts with original libmodplug. * Split openmpt123 into its own binary package because it has more dependencies than libopenmpt itself. * Consider providing an additional openmpt123 package (in addition to the default openmpt123 package with all audio output drivers), built with fewer audio output drivers so it does not transitively depend on X11. Name that package and its executable openmpt123-nox (or whatever else may be common practice in your distribution). libopenmpt-0.3.6+release.autotools/libopenmpt/libopenmpt_impl.hpp0000644000372100037210000002440113157732541022343 00000000000000/* * libopenmpt_impl.hpp * ------------------- * Purpose: libopenmpt private interface * Notes : This is not a public header. Do NOT ship in distributions dev packages. * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #ifndef LIBOPENMPT_IMPL_HPP #define LIBOPENMPT_IMPL_HPP #include "libopenmpt_internal.h" #include "libopenmpt.hpp" #include #include #if defined(_MSC_VER) #pragma warning(push) #pragma warning(disable:4512) // assignment operator could not be generated #endif // forward declarations namespace OpenMPT { class FileReaderTraitsStdStream; typedef FileReaderTraitsStdStream FileReaderTraitsDefault; namespace detail { template class FileReader; } // namespace detail typedef detail::FileReader FileReader; class CSoundFile; class Dither; } // namespace OpenMPT namespace openmpt { namespace version { std::uint32_t get_library_version(); std::uint32_t get_core_version(); std::string get_string( const std::string & key ); } // namespace version class log_interface { protected: log_interface(); public: virtual ~log_interface(); virtual void log( const std::string & message ) const = 0; }; // class log_interface class std_ostream_log : public log_interface { private: std::ostream & destination; public: std_ostream_log( std::ostream & dst ); virtual ~std_ostream_log(); virtual void log( const std::string & message ) const; }; // class CSoundFileLog_std_ostream class log_forwarder; struct callback_stream_wrapper { void * stream; std::size_t (*read)( void * stream, void * dst, std::size_t bytes ); int (*seek)( void * stream, std::int64_t offset, int whence ); std::int64_t (*tell)( void * stream ); }; // struct callback_stream_wrapper class module_impl { protected: struct subsong_data { double duration; std::int32_t start_row; std::int32_t start_order; std::int32_t sequence; subsong_data( double duration, std::int32_t start_row, std::int32_t start_order, std::int32_t sequence ); }; // struct subsong_data typedef std::vector subsongs_type; static const std::int32_t all_subsongs = -1; std::unique_ptr m_Log; std::unique_ptr m_LogForwarder; std::int32_t m_current_subsong; double m_currentPositionSeconds; std::unique_ptr m_sndFile; bool m_loaded; std::unique_ptr m_Dither; subsongs_type m_subsongs; float m_Gain; bool m_ctl_load_skip_samples; bool m_ctl_load_skip_patterns; bool m_ctl_load_skip_plugins; bool m_ctl_load_skip_subsongs_init; bool m_ctl_seek_sync_samples; std::vector m_loaderMessages; public: void PushToCSoundFileLog( const std::string & text ) const; void PushToCSoundFileLog( int loglevel, const std::string & text ) const; protected: std::string mod_string_to_utf8( const std::string & encoded ) const; void apply_mixer_settings( std::int32_t samplerate, int channels ); void apply_libopenmpt_defaults(); subsongs_type get_subsongs() const; void init_subsongs( subsongs_type & subsongs ) const; bool has_subsongs_inited() const; void ctor( const std::map< std::string, std::string > & ctls ); void load( const OpenMPT::FileReader & file, const std::map< std::string, std::string > & ctls ); bool is_loaded() const; std::size_t read_wrapper( std::size_t count, std::int16_t * left, std::int16_t * right, std::int16_t * rear_left, std::int16_t * rear_right ); std::size_t read_wrapper( std::size_t count, float * left, float * right, float * rear_left, float * rear_right ); std::size_t read_interleaved_wrapper( std::size_t count, std::size_t channels, std::int16_t * interleaved ); std::size_t read_interleaved_wrapper( std::size_t count, std::size_t channels, float * interleaved ); std::pair< std::string, std::string > format_and_highlight_pattern_row_channel_command( std::int32_t p, std::int32_t r, std::int32_t c, int command ) const; std::pair< std::string, std::string > format_and_highlight_pattern_row_channel( std::int32_t p, std::int32_t r, std::int32_t c, std::size_t width, bool pad ) const; static double could_open_probability( const OpenMPT::FileReader & file, double effort, std::unique_ptr log ); public: static std::vector get_supported_extensions(); static bool is_extension_supported( const char * extension ); static bool is_extension_supported( const std::string & extension ); static double could_open_probability( callback_stream_wrapper stream, double effort, std::unique_ptr log ); static double could_open_probability( std::istream & stream, double effort, std::unique_ptr log ); static std::size_t probe_file_header_get_recommended_size(); static int probe_file_header( std::uint64_t flags, const std::uint8_t * data, std::size_t size, std::uint64_t filesize ); static int probe_file_header( std::uint64_t flags, const void * data, std::size_t size, std::uint64_t filesize ); static int probe_file_header( std::uint64_t flags, const std::uint8_t * data, std::size_t size ); static int probe_file_header( std::uint64_t flags, const void * data, std::size_t size ); static int probe_file_header( std::uint64_t flags, std::istream & stream ); static int probe_file_header( std::uint64_t flags, callback_stream_wrapper stream ); module_impl( callback_stream_wrapper stream, std::unique_ptr log, const std::map< std::string, std::string > & ctls ); module_impl( std::istream & stream, std::unique_ptr log, const std::map< std::string, std::string > & ctls ); module_impl( const std::vector & data, std::unique_ptr log, const std::map< std::string, std::string > & ctls ); module_impl( const std::vector & data, std::unique_ptr log, const std::map< std::string, std::string > & ctls ); module_impl( const std::uint8_t * data, std::size_t size, std::unique_ptr log, const std::map< std::string, std::string > & ctls ); module_impl( const char * data, std::size_t size, std::unique_ptr log, const std::map< std::string, std::string > & ctls ); module_impl( const void * data, std::size_t size, std::unique_ptr log, const std::map< std::string, std::string > & ctls ); ~module_impl(); public: void select_subsong( std::int32_t subsong ); std::int32_t get_selected_subsong() const; void set_repeat_count( std::int32_t repeat_count ); std::int32_t get_repeat_count() const; double get_duration_seconds() const; double set_position_seconds( double seconds ); double get_position_seconds() const; double set_position_order_row( std::int32_t order, std::int32_t row ); std::int32_t get_render_param( int param ) const; void set_render_param( int param, std::int32_t value ); std::size_t read( std::int32_t samplerate, std::size_t count, std::int16_t * mono ); std::size_t read( std::int32_t samplerate, std::size_t count, std::int16_t * left, std::int16_t * right ); std::size_t read( std::int32_t samplerate, std::size_t count, std::int16_t * left, std::int16_t * right, std::int16_t * rear_left, std::int16_t * rear_right ); std::size_t read( std::int32_t samplerate, std::size_t count, float * mono ); std::size_t read( std::int32_t samplerate, std::size_t count, float * left, float * right ); std::size_t read( std::int32_t samplerate, std::size_t count, float * left, float * right, float * rear_left, float * rear_right ); std::size_t read_interleaved_stereo( std::int32_t samplerate, std::size_t count, std::int16_t * interleaved_stereo ); std::size_t read_interleaved_quad( std::int32_t samplerate, std::size_t count, std::int16_t * interleaved_quad ); std::size_t read_interleaved_stereo( std::int32_t samplerate, std::size_t count, float * interleaved_stereo ); std::size_t read_interleaved_quad( std::int32_t samplerate, std::size_t count, float * interleaved_quad ); std::vector get_metadata_keys() const; std::string get_metadata( const std::string & key ) const; std::int32_t get_current_speed() const; std::int32_t get_current_tempo() const; std::int32_t get_current_order() const; std::int32_t get_current_pattern() const; std::int32_t get_current_row() const; std::int32_t get_current_playing_channels() const; float get_current_channel_vu_mono( std::int32_t channel ) const; float get_current_channel_vu_left( std::int32_t channel ) const; float get_current_channel_vu_right( std::int32_t channel ) const; float get_current_channel_vu_rear_left( std::int32_t channel ) const; float get_current_channel_vu_rear_right( std::int32_t channel ) const; std::int32_t get_num_subsongs() const; std::int32_t get_num_channels() const; std::int32_t get_num_orders() const; std::int32_t get_num_patterns() const; std::int32_t get_num_instruments() const; std::int32_t get_num_samples() const; std::vector get_subsong_names() const; std::vector get_channel_names() const; std::vector get_order_names() const; std::vector get_pattern_names() const; std::vector get_instrument_names() const; std::vector get_sample_names() const; std::int32_t get_order_pattern( std::int32_t o ) const; std::int32_t get_pattern_num_rows( std::int32_t p ) const; std::uint8_t get_pattern_row_channel_command( std::int32_t p, std::int32_t r, std::int32_t c, int cmd ) const; std::string format_pattern_row_channel_command( std::int32_t p, std::int32_t r, std::int32_t c, int cmd ) const; std::string highlight_pattern_row_channel_command( std::int32_t p, std::int32_t r, std::int32_t c, int cmd ) const; std::string format_pattern_row_channel( std::int32_t p, std::int32_t r, std::int32_t c, std::size_t width, bool pad ) const; std::string highlight_pattern_row_channel( std::int32_t p, std::int32_t r, std::int32_t c, std::size_t width, bool pad ) const; std::vector get_ctls() const; std::string ctl_get( std::string ctl, bool throw_if_unknown = true ) const; void ctl_set( std::string ctl, const std::string & value, bool throw_if_unknown = true ); }; // class module_impl namespace helper { template std::unique_ptr make_unique(Args&&... args) { return std::unique_ptr(new T(std::forward(args)...)); } } // namespace helper } // namespace openmpt #if defined(_MSC_VER) #pragma warning(pop) #endif #endif // LIBOPENMPT_IMPL_HPP libopenmpt-0.3.6+release.autotools/libopenmpt/libopenmpt_ext.hpp0000644000372100037210000003107313162373624022204 00000000000000/* * libopenmpt_ext.hpp * ------------------ * Purpose: libopenmpt public c++ interface for libopenmpt extensions * Notes : * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #ifndef LIBOPENMPT_EXT_HPP #define LIBOPENMPT_EXT_HPP #include "libopenmpt_config.h" #include "libopenmpt.hpp" /*! * \page libopenmpt_ext_cpp_overview libopenmpt_ext C++ API * * libopenmpt_ext is now included in all builds by default. * * \section libopenmpt-ext-cpp-detailed Detailed documentation * * \ref libopenmpt_ext_cpp * */ /*! \defgroup libopenmpt_ext_cpp libopenmpt_ext C++ */ /*! \addtogroup libopenmpt_ext_cpp @{ */ namespace openmpt { class module_ext_impl; class LIBOPENMPT_CXX_API module_ext : public module { private: module_ext_impl * ext_impl; private: // non-copyable module_ext( const module_ext & ); void operator = ( const module_ext & ); public: module_ext( std::istream & stream, std::ostream & log = std::clog, const std::map< std::string, std::string > & ctls = detail::initial_ctls_map() ); module_ext( const std::vector & data, std::ostream & log = std::clog, const std::map< std::string, std::string > & ctls = detail::initial_ctls_map() ); module_ext( const char * data, std::size_t size, std::ostream & log = std::clog, const std::map< std::string, std::string > & ctls = detail::initial_ctls_map() ); module_ext( const void * data, std::size_t size, std::ostream & log = std::clog, const std::map< std::string, std::string > & ctls = detail::initial_ctls_map() ); virtual ~module_ext(); public: //! Retrieve a libopenmpt extension. /*! Example: Retrieving the interactive extension to change the tempo of a module: \code{.cpp} openmpt::module_ext *mod = new openmpt::module_ext( stream ); #ifdef LIBOPENMPT_EXT_INTERFACE_INTERACTIVE openmpt::ext::interactive *interactive = static_cast( self->mod->get_interface( openmpt::ext::interactive_id ) ); if ( interactive ) { interactive->set_tempo_factor( 2.0 ); // play module at double speed } else { // interface not available } #else // interfae not available #endif \endcode \param interface_id The name of the extension interface to retrieve. \return The interface object. This may be a nullptr if the extension was not found. */ void * get_interface( const std::string & interface_id ); }; // class module_ext namespace ext { #define LIBOPENMPT_DECLARE_EXT_CXX_INTERFACE(name) \ static const char name ## _id [] = # name ; \ class name; \ /**/ #define LIBOPENMPT_EXT_CXX_INTERFACE(name) \ protected: \ name () {} \ virtual ~ name () {} \ public: \ /**/ #ifndef LIBOPENMPT_EXT_INTERFACE_PATTERN_VIS #define LIBOPENMPT_EXT_INTERFACE_PATTERN_VIS #endif LIBOPENMPT_DECLARE_EXT_CXX_INTERFACE(pattern_vis) class pattern_vis { LIBOPENMPT_EXT_CXX_INTERFACE(pattern_vis) //! Pattern command type enum effect_type { effect_unknown = 0, effect_general = 1, effect_global = 2, effect_volume = 3, effect_panning = 4, effect_pitch = 5 }; // enum effect_type //! Get pattern command type for pattern highlighting /*! \param pattern The pattern whose data should be retrieved. \param row The row from which the data should be retrieved. \param channel The channel from which the data should be retrieved. \return The command type in the effect column at the given pattern position (see openmpt::ext::pattern_vis::effect_type) \sa openmpt::ext::pattern_vis::get_pattern_row_channel_effect_type */ virtual effect_type get_pattern_row_channel_volume_effect_type( std::int32_t pattern, std::int32_t row, std::int32_t channel ) const = 0; //! Get pattern command type for pattern highlighting /*! \param pattern The pattern whose data should be retrieved. \param row The row from which the data should be retrieved. \param channel The channel from which the data should be retrieved. \return The command type in the volume column at the given pattern position (see openmpt::ext::pattern_vis::effect_type) \sa openmpt::ext::pattern_vis::get_pattern_row_channel_volume_effect_type */ virtual effect_type get_pattern_row_channel_effect_type( std::int32_t pattern, std::int32_t row, std::int32_t channel ) const = 0; }; // class pattern_vis #ifndef LIBOPENMPT_EXT_INTERFACE_INTERACTIVE #define LIBOPENMPT_EXT_INTERFACE_INTERACTIVE #endif LIBOPENMPT_DECLARE_EXT_CXX_INTERFACE(interactive) class interactive { LIBOPENMPT_EXT_CXX_INTERFACE(interactive) //! Set the current ticks per row (speed) /*! \param speed The new tick count in range [1, 65535]. \throws openmpt::exception Throws an exception derived from openmpt::exception if the speed is outside the specified range. \remarks The tick count may be reset by pattern commands at any time. \sa openmpt::module::get_current_speed */ virtual void set_current_speed( std::int32_t speed ) = 0; //! Set the current module tempo /*! \param tempo The new tempo in range [32, 512]. The exact meaning of the value depends on the tempo mode used by the module. \throws openmpt::exception Throws an exception derived from openmpt::exception if the tempo is outside the specified range. \remarks The tempo may be reset by pattern commands at any time. Use openmpt::ext:interactive::set_tempo_factor to apply a tempo factor that is independent of pattern commands. \sa openmpt::module::get_current_tempo */ virtual void set_current_tempo( std::int32_t tempo ) = 0; //! Set the current module tempo factor without affecting playback pitch /*! \param factor The new tempo factor in range ]0.0, 4.0] - 1.0 means unmodified tempo. \throws openmpt::exception Throws an exception derived from openmpt::exception if the factor is outside the specified range. \remarks Modifying the tempo without applying the same pitch factor using openmpt::ext::interactive::set_pitch_factor may cause rhythmic samples (e.g. drum loops) to go out of sync. \sa openmpt::ext::interactive::get_tempo_factor */ virtual void set_tempo_factor( double factor ) = 0; //! Gets the current module tempo factor /*! \return The current tempo factor. \sa openmpt::ext::interactive::set_tempo_factor */ virtual double get_tempo_factor( ) const = 0; //! Set the current module pitch factor without affecting playback speed /*! \param factor The new pitch factor in range ]0.0, 4.0] - 1.0 means unmodified pitch. \throws openmpt::exception Throws an exception derived from openmpt::exception if the factor is outside the specified range. \remarks Modifying the pitch without applying the the same tempo factor using openmpt::ext::interactive::set_tempo_factor may cause rhythmic samples (e.g. drum loops) to go out of sync. \remarks To shift the pich by `n` semitones, the parameter can be calculated as follows: `pow( 2.0, n / 12.0 )` \sa openmpt::ext::interactive::get_pitch_factor */ virtual void set_pitch_factor( double factor ) = 0; //! Gets the current module pitch factor /*! \return The current pitch factor. \sa openmpt::ext::interactive::set_pitch_factor */ virtual double get_pitch_factor( ) const = 0; //! Set the current global volume /*! \param volume The new global volume in range [0.0, 1.0] \throws openmpt::exception Throws an exception derived from openmpt::exception if the volume is outside the specified range. \remarks The global volume may be reset by pattern commands at any time. Use openmpt::module::set_render_param to apply a global overall volume factor that is independent of pattern commands. \sa openmpt::ext::interactive::get_global_volume */ virtual void set_global_volume( double volume ) = 0; //! Get the current global volume /*! \return The current global volume in range [0.0, 1.0] \sa openmpt::ext::interactive::set_global_volume */ virtual double get_global_volume( ) const = 0; //! Set the current channel volume for a channel /*! \param channel The channel whose volume should be set, in range [0, openmpt::module::get_num_channels()[ \param volume The new channel volume in range [0.0, 1.0] \throws openmpt::exception Throws an exception derived from openmpt::exception if the channel or volume is outside the specified range. \remarks The channel volume may be reset by pattern commands at any time. \sa openmpt::ext::interactive::get_channel_volume */ virtual void set_channel_volume( std::int32_t channel, double volume ) = 0; //! Get the current channel volume for a channel /*! \param channel The channel whose volume should be retrieved, in range [0, openmpt::module::get_num_channels()[ \return The current channel volume in range [0.0, 1.0] \throws openmpt::exception Throws an exception derived from openmpt::exception if the channel is outside the specified range. \sa openmpt::ext::interactive::set_channel_volume */ virtual double get_channel_volume( std::int32_t channel ) const = 0; //! Set the current mute status for a channel /*! \param channel The channel whose mute status should be set, in range [0, openmpt::module::get_num_channels()[ \param mute The new mute status. true is muted, false is unmuted. \throws openmpt::exception Throws an exception derived from openmpt::exception if the channel is outside the specified range. \sa openmpt::ext::interactive::get_channel_mute_status */ virtual void set_channel_mute_status( std::int32_t channel, bool mute ) = 0; //! Get the current mute status for a channel /*! \param channel The channel whose mute status should be retrieved, in range [0, openmpt::module::get_num_channels()[ \return The current channel mute status. true is muted, false is unmuted. \throws openmpt::exception Throws an exception derived from openmpt::exception if the channel is outside the specified range. \sa openmpt::ext::interactive::set_channel_mute_status */ virtual bool get_channel_mute_status( std::int32_t channel ) const = 0; //! Set the current mute status for an instrument /*! \param instrument The instrument whose mute status should be set, in range [0, openmpt::module::get_num_instruments()[ if openmpt::module::get_num_instruments is not 0, otherwise in [0, openmpt::module::get_num_samples()[ \param mute The new mute status. true is muted, false is unmuted. \throws openmpt::exception Throws an exception derived from openmpt::exception if the instrument is outside the specified range. \sa openmpt::ext::interactive::get_instrument_mute_status */ virtual void set_instrument_mute_status( std::int32_t instrument, bool mute ) = 0; //! Get the current mute status for an instrument /*! \param instrument The instrument whose mute status should be retrieved, in range [0, openmpt::module::get_num_instruments()[ if openmpt::module::get_num_instruments is not 0, otherwise in [0, openmpt::module::get_num_samples()[ \return The current instrument mute status. true is muted, false is unmuted. \throws openmpt::exception Throws an exception derived from openmpt::exception if the instrument is outside the specified range. \sa openmpt::ext::interactive::set_instrument_mute_status */ virtual bool get_instrument_mute_status( std::int32_t instrument ) const = 0; //! Play a note using the specified instrument /*! \param instrument The instrument that should be played, in range [0, openmpt::module::get_num_instruments()[ if openmpt::module::get_num_instruments is not 0, otherwise in [0, openmpt::module::get_num_samples()[ \param note The note to play, in rage [0, 119]. 60 is the middle C. \param volume The volume at which the note should be triggered, in range [0.0, 1.0] \param panning The panning position at which the note should be triggered, in range [-1.0, 1.0], 0.0 is center. \return The channel on which the note is played. This can pe be passed to openmpt::ext::interactive::stop_note to stop the note. \throws openmpt::exception Throws an exception derived from openmpt::exception if the instrument or note is outside the specified range. \sa openmpt::ext::interactive::stop_note */ virtual std::int32_t play_note( std::int32_t instrument, std::int32_t note, double volume, double panning ) = 0; //! Stop the note playing on the specified channel /*! \param channel The channel on which the note should be stopped. \throws openmpt::exception Throws an exception derived from openmpt::exception if the channel index is invalid. \sa openmpt::ext::interactive::play_note */ virtual void stop_note( std::int32_t channel ) = 0; }; // class interactive /* add stuff here */ #undef LIBOPENMPT_DECLARE_EXT_CXX_INTERFACE #undef LIBOPENMPT_EXT_CXX_INTERFACE } // namespace ext } // namespace openmpt /*! @} */ #endif // LIBOPENMPT_EXT_HPP libopenmpt-0.3.6+release.autotools/libopenmpt/libopenmpt_ext.h0000644000372100037210000003660213233130322021630 00000000000000/* * libopenmpt_ext.h * ---------------- * Purpose: libopenmpt public c interface for libopenmpt extensions * Notes : * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #ifndef LIBOPENMPT_EXT_H #define LIBOPENMPT_EXT_H #include "libopenmpt_config.h" #include "libopenmpt.h" #ifdef __cplusplus extern "C" { #endif /*! * \page libopenmpt_ext_c_overview libopenmpt_ext C API * * libopenmpt_ext is included in all builds by default. * * \section libopenmpt-ext-c-detailed Detailed documentation * * \ref libopenmpt_ext_c * */ /*! \defgroup libopenmpt_ext_c libopenmpt_ext C */ /*! \addtogroup libopenmpt_ext_c * @{ */ /*! \brief Opaque type representing a libopenmpt extension module */ typedef struct openmpt_module_ext openmpt_module_ext; /*! \brief Construct an openmpt_module_ext * * \param stream_callbacks Input stream callback operations. * \param stream Input stream to load the module from. * \param logfunc Logging function where warning and errors are written. The logging function may be called throughout the lifetime of openmpt_module_ext. May be NULL. * \param loguser User-defined data associated with this module. This value will be passed to the logging callback function (logfunc) * \param errfunc Error function to define error behaviour. May be NULL. * \param erruser Error function user context. Used to pass any user-defined data associated with this module to the logging function. * \param error Pointer to an integer where an error may get stored. May be NULL. * \param error_message Pointer to a string pointer where an error message may get stored. May be NULL. * \param ctls A map of initial ctl values, see openmpt_module_get_ctls. * \return A pointer to the constructed openmpt_module_ext, or NULL on failure. * \remarks The input data can be discarded after an openmpt_module_ext has been constructed successfully. * \sa openmpt_stream_callbacks * \sa \ref libopenmpt_c_fileio * \since 0.3.0 */ LIBOPENMPT_API openmpt_module_ext * openmpt_module_ext_create( openmpt_stream_callbacks stream_callbacks, void * stream, openmpt_log_func logfunc, void * loguser, openmpt_error_func errfunc, void * erruser, int * error, const char * * error_message, const openmpt_module_initial_ctl * ctls ); /*! \brief Construct an openmpt_module_ext * * \param filedata Data to load the module from. * \param filesize Amount of data available. * \param logfunc Logging function where warning and errors are written. The logging function may be called throughout the lifetime of openmpt_module_ext. * \param loguser User-defined data associated with this module. This value will be passed to the logging callback function (logfunc) * \param errfunc Error function to define error behaviour. May be NULL. * \param erruser Error function user context. Used to pass any user-defined data associated with this module to the logging function. * \param error Pointer to an integer where an error may get stored. May be NULL. * \param error_message Pointer to a string pointer where an error message may get stored. May be NULL. * \param ctls A map of initial ctl values, see openmpt_module_get_ctls. * \return A pointer to the constructed openmpt_module_ext, or NULL on failure. * \remarks The input data can be discarded after an openmpt_module_ext has been constructed successfully. * \sa \ref libopenmpt_c_fileio * \since 0.3.0 */ LIBOPENMPT_API openmpt_module_ext * openmpt_module_ext_create_from_memory( const void * filedata, size_t filesize, openmpt_log_func logfunc, void * loguser, openmpt_error_func errfunc, void * erruser, int * error, const char * * error_message, const openmpt_module_initial_ctl * ctls ); /*! \brief Unload a previously created openmpt_module_ext from memory. * * \param mod_ext The module to unload. */ LIBOPENMPT_API void openmpt_module_ext_destroy( openmpt_module_ext * mod_ext ); /*! \brief Retrieve the openmpt_module handle from an openmpt_module_ext handle. * * \param mod_ext The extension module handle to convert * \return An equivalent openmpt_module handle to pass to standard libopenmpt functions * \since 0.3.0 */ LIBOPENMPT_API openmpt_module * openmpt_module_ext_get_module( openmpt_module_ext * mod_ext ); /*! Retrieve a libopenmpt extension. * * \param mod_ext The module handle to work on. * \param interface_id The name of the extension interface to retrieve (e.g. LIBOPENMPT_EXT_C_INTERFACE_PATTERN_VIS). * \param interface Appropriate structure of interface function pointers which is to be filled by this function (e.g. a pointer to a openmpt_module_ext_interface_pattern_vis structure). * \param interface_size Size of the interface's structure of function pointers (e.g. sizeof(openmpt_module_ext_interface_pattern_vis)). * \return 1 on success, 0 if the interface was not found. * \since 0.3.0 */ LIBOPENMPT_API int openmpt_module_ext_get_interface( openmpt_module_ext * mod_ext, const char * interface_id, void * interface, size_t interface_size ); #ifndef LIBOPENMPT_EXT_C_INTERFACE_PATTERN_VIS #define LIBOPENMPT_EXT_C_INTERFACE_PATTERN_VIS "pattern_vis" #endif /*! Pattern command type */ #define OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_UNKNOWN 0 #define OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_GENERAL 1 #define OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_GLOBAL 2 #define OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_VOLUME 3 #define OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_PANNING 4 #define OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_PITCH 5 typedef struct openmpt_module_ext_interface_pattern_vis { /*! Get pattern command type for pattern highlighting * * \param mod_ext The module handle to work on. * \param pattern The pattern whose data should be retrieved. * \param row The row from which the data should be retrieved. * \param channel The channel from which the data should be retrieved. * \return The command type in the effect column at the given pattern position (see OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_*) * \sa openmpt_module_ext_interface_pattern_vis::get_pattern_row_channel_volume_effect_type */ int ( * get_pattern_row_channel_volume_effect_type ) ( openmpt_module_ext * mod_ext, int32_t pattern, int32_t row, int32_t channel ); /*! Get pattern command type for pattern highlighting * * \param mod_ext The module handle to work on. * \param pattern The pattern whose data should be retrieved. * \param row The row from which the data should be retrieved. * \param channel The channel from which the data should be retrieved. * \return The command type in the effect column at the given pattern position (see OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_*) * \sa openmpt_module_ext_interface_pattern_vis::get_pattern_row_channel_volume_effect_type */ int ( * get_pattern_row_channel_effect_type ) ( openmpt_module_ext * mod_ext, int32_t pattern, int32_t row, int32_t channel ); } openmpt_module_ext_interface_pattern_vis; #ifndef LIBOPENMPT_EXT_C_INTERFACE_INTERACTIVE #define LIBOPENMPT_EXT_C_INTERFACE_INTERACTIVE "interactive" #endif typedef struct openmpt_module_ext_interface_interactive { /*! Set the current ticks per row (speed) * * \param mod_ext The module handle to work on. * \param speed The new tick count in range [1, 65535]. * \return 1 on success, 0 on failure. * \remarks The tick count may be reset by pattern commands at any time. * \sa openmpt_module_get_current_speed */ int ( * set_current_speed ) ( openmpt_module_ext * mod_ext, int32_t speed ); /*! Set the current module tempo * * \param mod_ext The module handle to work on. * \param tempo The new tempo in range [32, 512]. The exact meaning of the value depends on the tempo mode used by the module. * \return 1 on success, 0 on failure. * \remarks The tempo may be reset by pattern commands at any time. Use openmpt_module_ext_interface_interactive::set_tempo_factor to apply a tempo factor that is independent of pattern commands. * \sa openmpt_module_get_current_tempo */ int ( * set_current_tempo ) ( openmpt_module_ext * mod_ext, int32_t tempo ); /*! Set the current module tempo factor without affecting playback pitch * * \param mod_ext The module handle to work on. * \param factor The new tempo factor in range ]0.0, 4.0] - 1.0 means unmodified tempo. * \return 1 on success, 0 on failure. * \remarks Modifying the tempo without applying the same pitch factor using openmpt_module_ext_interface_interactive::set_pitch_factor may cause rhythmic samples (e.g. drum loops) to go out of sync. * \sa openmpt_module_ext_interface_interactive::get_tempo_factor */ int ( * set_tempo_factor ) ( openmpt_module_ext * mod_ext, double factor ); /*! Gets the current module tempo factor * * \param mod_ext The module handle to work on. * \return The current tempo factor. * \sa openmpt_module_ext_interface_interactive::set_tempo_factor */ double ( * get_tempo_factor ) ( openmpt_module_ext * mod_ext ); /*! Set the current module pitch factor without affecting playback speed * * \param mod_ext The module handle to work on. * \param factor The new pitch factor in range ]0.0, 4.0] - 1.0 means unmodified pitch. * \return 1 on success, 0 on failure. * \remarks Modifying the pitch without applying the the same tempo factor using openmpt_module_ext_interface_interactive::set_tempo_factor may cause rhythmic samples (e.g. drum loops) to go out of sync. * \remarks To shift the pich by `n` semitones, the parameter can be calculated as follows: `pow( 2.0, n / 12.0 )` * \sa openmpt_module_ext_interface_interactive::get_pitch_factor */ int ( * set_pitch_factor ) ( openmpt_module_ext * mod_ext, double factor ); /*! Gets the current module pitch factor * * \param mod_ext The module handle to work on. * \return The current pitch factor. * \sa openmpt_module_ext_interface_interactive::set_pitch_factor */ double ( * get_pitch_factor ) ( openmpt_module_ext * mod_ext ); /*! Set the current global volume * * \param mod_ext The module handle to work on. * \param volume The new global volume in range [0.0, 1.0] * \return 1 on success, 0 on failure. * \remarks The global volume may be reset by pattern commands at any time. Use openmpt_module_set_render_param to apply a global overall volume factor that is independent of pattern commands. * \sa openmpt_module_ext_interface_interactive::get_global_volume */ int ( * set_global_volume ) ( openmpt_module_ext * mod_ext, double volume ); /*! Get the current global volume * * \param mod_ext The module handle to work on. * \return The current global volume in range [0.0, 1.0] * \sa openmpt_module_ext_interface_interactive::set_global_volume */ double ( * get_global_volume ) ( openmpt_module_ext * mod_ext ); /*! Set the current channel volume for a channel * * \param mod_ext The module handle to work on. * \param channel The channel whose volume should be set, in range [0, openmpt_module_get_num_channels()[ * \param volume The new channel volume in range [0.0, 1.0] * \return 1 on success, 0 on failure (channel out of range). * \remarks The channel volume may be reset by pattern commands at any time. * \sa openmpt_module_ext_interface_interactive::get_channel_volume */ int ( * set_channel_volume ) ( openmpt_module_ext * mod_ext, int32_t channel, double volume ); /*! Get the current channel volume for a channel * * \param mod_ext The module handle to work on. * \param channel The channel whose volume should be retrieved, in range [0, openmpt_module_get_num_channels()[ * \return The current channel volume in range [0.0, 1.0] * \sa openmpt_module_ext_interface_interactive::set_channel_volume */ double ( * get_channel_volume ) ( openmpt_module_ext * mod_ext, int32_t channel ); /*! Set the current mute status for a channel * * \param mod_ext The module handle to work on. * \param channel The channel whose mute status should be set, in range [0, openmpt_module_get_num_channels()[ * \param mute The new mute status. true is muted, false is unmuted. * \return 1 on success, 0 on failure (channel out of range). * \sa openmpt_module_ext_interface_interactive::get_channel_mute_status */ int ( * set_channel_mute_status ) ( openmpt_module_ext * mod_ext, int32_t channel, int mute ); /*! Get the current mute status for a channel * * \param mod_ext The module handle to work on. * \param channel The channel whose mute status should be retrieved, in range [0, openmpt_module_get_num_channels()[ * \return The current channel mute status. 1 is muted, 0 is unmuted, -1 means the instrument was out of range * \sa openmpt_module_ext_interface_interactive::set_channel_mute_status */ int ( * get_channel_mute_status ) ( openmpt_module_ext * mod_ext, int32_t channel ); /*! Set the current mute status for an instrument * * \param mod_ext The module handle to work on. * \param instrument The instrument whose mute status should be set, in range [0, openmpt_module_get_num_instruments()[ if openmpt_module_get_num_instruments is not 0, otherwise in [0, openmpt_module_get_num_samples()[ * \param mute The new mute status. true is muted, false is unmuted. * \return 1 on success, 0 on failure (instrument out of range). * \sa openmpt_module_ext_interface_interactive::get_instrument_mute_status */ int ( * set_instrument_mute_status ) ( openmpt_module_ext * mod_ext, int32_t instrument, int mute ); /*! Get the current mute status for an instrument * * \param mod_ext The module handle to work on. * \param instrument The instrument whose mute status should be retrieved, in range [0, openmpt_module_get_num_instruments()[ if openmpt_module_get_num_instruments is not 0, otherwise in [0, openmpt_module_get_num_samples()[ * \return The current instrument mute status. 1 is muted, 0 is unmuted, -1 means the instrument was out of range * \sa openmpt_module_ext_interface_interactive::set_instrument_mute_status */ int ( * get_instrument_mute_status ) ( openmpt_module_ext * mod_ext, int32_t instrument ); /*! Play a note using the specified instrument * * \param mod_ext The module handle to work on. * \param instrument The instrument that should be played, in range [0, openmpt_module_get_num_instruments()[ if openmpt_module_get_num_instruments is not 0, otherwise in [0, openmpt_module_get_num_samples()[ * \param note The note to play, in rage [0, 119]. 60 is the middle C. * \param volume The volume at which the note should be triggered, in range [0.0, 1.0] * \param panning The panning position at which the note should be triggered, in range [-1.0, 1.0], 0.0 is center. * \return The channel on which the note is played. This can pe be passed to openmpt_module_ext_interface_interactive::stop_note to stop the note. -1 means that no channel could be allocated and the note is not played. * \sa openmpt_module_ext_interface_interactive::stop_note */ int32_t ( * play_note ) ( openmpt_module_ext * mod_ext, int32_t instrument, int32_t note, double volume, double panning ); /*! Stop the note playing on the specified channel * * \param mod_ext The module handle to work on. * \param channel The channel on which the note should be stopped. * \return 1 on success, 0 on failure (channel out of range). * \sa openmpt_module_ext_interface_interactive::play_note */ int ( * stop_note ) ( openmpt_module_ext * mod_ext, int32_t channel ); } openmpt_module_ext_interface_interactive; /* add stuff here */ #ifdef __cplusplus } #endif /*! * @} */ #endif /* LIBOPENMPT_EXT_H */ libopenmpt-0.3.6+release.autotools/libopenmpt/libopenmpt_impl.cpp0000644000372100037210000017506513214777522022355 00000000000000/* * libopenmpt_impl.cpp * ------------------- * Purpose: libopenmpt private interface implementation * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "common/stdafx.h" #include "libopenmpt_internal.h" #include "libopenmpt.hpp" #include "libopenmpt_impl.hpp" #include #include #include #include #include #include #include #include #include #include "common/version.h" #include "common/misc_util.h" #include "common/FileReader.h" #include "common/Logging.h" #include "common/mptMutex.h" #include "soundlib/Sndfile.h" #include "soundlib/mod_specifications.h" #include "soundlib/AudioReadTarget.h" OPENMPT_NAMESPACE_BEGIN #if MPT_OS_WINDOWS && MPT_OS_WINDOWS_WINRT #if defined(_WIN32_WINNT) #if (_WIN32_WINNT < 0x0602) #if MPT_COMPILER_MSVC #pragma message("Warning: libopenmpt for WinRT is built with reduced functionality. Please #define _WIN32_WINNT 0x0602.") #elif MPT_COMPILER_GCC || MPT_COMPILER_CLANG || MPT_COMPILER_MSVCCLANGC2 #warning "Warning: libopenmpt for WinRT is built with reduced functionality. Please #define _WIN32_WINNT 0x0602." #else // There is no portable way to display a warning. // Try to provoke a warning with an unused variable. static int Warning_libopenmpt_for_WinRT_is_built_with_reduced_functionality_Please_define_WIN32_WINNT_0x0602; #endif #endif // _WIN32_WINNT #endif // _WIN32_WINNT #endif // MPT_OS_WINDOWS && MPT_OS_WINDOWS_WINRT #if defined(MPT_BUILD_MSVC) || defined(MPT_BUILD_VCPKG) #if MPT_OS_WINDOWS_WINRT #pragma comment(lib, "ole32.lib") #else #pragma comment(lib, "rpcrt4.lib") #endif #if defined(MPT_WITH_MEDIAFOUNDATION) #pragma comment(lib, "mf.lib") #pragma comment(lib, "mfplat.lib") #pragma comment(lib, "mfreadwrite.lib") #pragma comment(lib, "mfuuid.lib") // static lib #pragma comment(lib, "propsys.lib") #endif // MPT_WITH_MEDIAFOUNDATION #ifndef NO_DMO #pragma comment(lib, "dmoguids.lib") #pragma comment(lib, "strmiids.lib") #endif // !NO_DMO #endif // MPT_BUILD_MSVC #if MPT_PLATFORM_MULTITHREADED && MPT_MUTEX_NONE #if MPT_COMPILER_MSVC #pragma message("Warning: libopenmpt built in non thread-safe mode because mutexes are not supported by the C++ standard library available.") #elif MPT_COMPILER_GCC || MPT_COMPILER_CLANG || MPT_COMPILER_MSVCCLANGC2 #warning "Warning: libopenmpt built in non thread-safe mode because mutexes are not supported by the C++ standard library available." #else // There is no portable way to display a warning. // Try to provoke a warning with an unused variable. static int Warning_libopenmpt_built_in_non_thread_safe_mode_because_mutexes_are_not_supported_by_the_CPlusPlus_standard_library_available; #endif #endif // MPT_MUTEX_NONE #if 0 #if (!MPT_COMPILER_HAS_CONSTEXPR11) #if MPT_COMPILER_MSVC #pragma message("Warning: libopenmpt is built with a compiler not supporting constexpr. Referring to libopenmpt from global initializers will result in undefined behaviour.") #elif MPT_COMPILER_GCC || MPT_COMPILER_CLANG || MPT_COMPILER_MSVCCLANGC2 #warning "Warning: libopenmpt is built with a compiler not supporting constexpr. Referring to libopenmpt from global initializers will result in undefined behaviour.") #else // There is no portable way to display a warning. // Try to provoke a warning with an unused variable. static int Warning_libopenmpt_is_built_with_a_compiler_not_supporting_constexpr_Referring_to_libopenmpt_from_global_initializers_will_result_in_undefined_behaviour; #endif #endif // "MPT_COMPILER_HAS_CONSTEXPR11 #endif #if defined(MPT_ASSERT_HANDLER_NEEDED) && !defined(ENABLE_TESTS) MPT_NOINLINE void AssertHandler(const char *file, int line, const char *function, const char *expr, const char *msg) { if(msg) { mpt::log::Logger().SendLogMessage(mpt::log::Context(file, line, function), LogError, "ASSERT", MPT_USTRING("ASSERTION FAILED: ") + mpt::ToUnicode(mpt::CharsetASCII, msg) + MPT_USTRING(" (") + mpt::ToUnicode(mpt::CharsetASCII, expr) + MPT_USTRING(")") ); } else { mpt::log::Logger().SendLogMessage(mpt::log::Context(file, line, function), LogError, "ASSERT", MPT_USTRING("ASSERTION FAILED: ") + mpt::ToUnicode(mpt::CharsetASCII, expr) ); } #if defined(MPT_BUILD_FATAL_ASSERTS) std::abort(); #endif // MPT_BUILD_FATAL_ASSERTS } #endif // MPT_ASSERT_HANDLER_NEEDED && !ENABLE_TESTS OPENMPT_NAMESPACE_END using namespace OpenMPT; namespace openmpt { namespace version { std::uint32_t get_library_version() { return OPENMPT_API_VERSION; } std::uint32_t get_core_version() { return MptVersion::num; } static std::string get_library_version_string() { std::string str; const MptVersion::SourceInfo sourceInfo = MptVersion::GetSourceInfo(); str += mpt::fmt::val(OPENMPT_API_VERSION_MAJOR); str += "."; str += mpt::fmt::val(OPENMPT_API_VERSION_MINOR); str += "."; str += mpt::fmt::val(OPENMPT_API_VERSION_PATCH); if ( std::string(OPENMPT_API_VERSION_PREREL).length() > 0 ) { str += OPENMPT_API_VERSION_PREREL; } std::vector fields; if ( sourceInfo.Revision ) { fields.push_back( "r" + mpt::fmt::val( sourceInfo.Revision ) ); } if ( sourceInfo.IsDirty ) { fields.push_back( "modified" ); } else if ( sourceInfo.HasMixedRevisions ) { fields.push_back( "mixed" ); } if ( sourceInfo.IsPackage ) { fields.push_back( "pkg" ); } if ( !fields.empty() ) { str += "+"; str += mpt::String::Combine( fields, std::string(".") ); } return str; } static std::string get_library_features_string() { return mpt::String::Trim(MptVersion::GetBuildFeaturesString()); } static std::string get_core_version_string() { return MptVersion::GetVersionStringExtended(); } static std::string get_source_url_string() { return MptVersion::GetSourceInfo().GetUrlWithRevision(); } static std::string get_source_date_string() { return MptVersion::GetSourceInfo().Date; } static std::string get_source_revision_string() { const MptVersion::SourceInfo sourceInfo = MptVersion::GetSourceInfo(); return sourceInfo.Revision ? mpt::fmt::val(sourceInfo.Revision) : std::string(); } static std::string get_build_string() { return MptVersion::GetBuildDateString(); } static std::string get_build_compiler_string() { return MptVersion::GetBuildCompilerString(); } static std::string get_credits_string() { return mpt::ToCharset(mpt::CharsetUTF8, MptVersion::GetFullCreditsString()); } static std::string get_contact_string() { return mpt::ToCharset(mpt::CharsetUTF8, MPT_USTRING("Forum: ") + MptVersion::GetURL("forum")); } static std::string get_license_string() { return mpt::ToCharset(mpt::CharsetUTF8, MptVersion::GetLicenseString()); } static std::string get_url_string() { return mpt::ToCharset(mpt::CharsetUTF8, MptVersion::GetURL("website")); } static std::string get_support_forum_url_string() { return mpt::ToCharset(mpt::CharsetUTF8, MptVersion::GetURL("forum")); } static std::string get_bugtracker_url_string() { return mpt::ToCharset(mpt::CharsetUTF8, MptVersion::GetURL("bugtracker")); } std::string get_string( const std::string & key ) { if ( key == "" ) { return std::string(); } else if ( key == "library_version" ) { return get_library_version_string(); } else if ( key == "library_version_major" ) { return mpt::fmt::val(OPENMPT_API_VERSION_MAJOR); } else if ( key == "library_version_minor" ) { return mpt::fmt::val(OPENMPT_API_VERSION_MINOR); } else if ( key == "library_version_patch" ) { return mpt::fmt::val(OPENMPT_API_VERSION_PATCH); } else if ( key == "library_version_prerel" ) { return mpt::fmt::val(OPENMPT_API_VERSION_PREREL); } else if ( key == "library_version_is_release" ) { return ( std::string(OPENMPT_API_VERSION_PREREL).length() == 0 ) ? "1" : "0"; } else if ( key == "library_features" ) { return get_library_features_string(); } else if ( key == "core_version" ) { return get_core_version_string(); } else if ( key == "source_url" ) { return get_source_url_string(); } else if ( key == "source_date" ) { return get_source_date_string(); } else if ( key == "source_revision" ) { return get_source_revision_string(); } else if ( key == "source_is_modified" ) { return MptVersion::GetSourceInfo().IsDirty ? "1" : "0"; } else if ( key == "source_has_mixed_revision" ) { return MptVersion::GetSourceInfo().HasMixedRevisions ? "1" : "0"; } else if ( key == "source_is_package" ) { return MptVersion::GetSourceInfo().IsPackage ? "1" : "0"; } else if ( key == "build" ) { return get_build_string(); } else if ( key == "build_compiler" ) { return get_build_compiler_string(); } else if ( key == "credits" ) { return get_credits_string(); } else if ( key == "contact" ) { return get_contact_string(); } else if ( key == "license" ) { return get_license_string(); } else if ( key == "url" ) { return get_url_string(); } else if ( key == "support_forum_url" ) { return get_support_forum_url_string(); } else if ( key == "bugtracker_url" ) { return get_bugtracker_url_string(); } else { return std::string(); } } } // namespace version log_interface::log_interface() { return; } log_interface::~log_interface() { return; } std_ostream_log::std_ostream_log( std::ostream & dst ) : destination(dst) { return; } std_ostream_log::~std_ostream_log() { return; } void std_ostream_log::log( const std::string & message ) const { destination.flush(); destination << message << std::endl; destination.flush(); } class log_forwarder : public ILog { private: log_interface & destination; public: log_forwarder( log_interface & dest ) : destination(dest) { return; } virtual ~log_forwarder() { return; } private: void AddToLog( LogLevel level, const mpt::ustring & text ) const { destination.log( mpt::ToCharset( mpt::CharsetUTF8, LogLevelToString( level ) + MPT_USTRING(": ") + text ) ); } }; // class log_forwarder class loader_log : public ILog { private: mutable std::vector > m_Messages; public: std::vector > GetMessages() const; private: void AddToLog( LogLevel level, const mpt::ustring & text ) const; }; // class loader_log std::vector > loader_log::GetMessages() const { return m_Messages; } void loader_log::AddToLog( LogLevel level, const mpt::ustring & text ) const { m_Messages.push_back( std::make_pair( level, mpt::ToCharset( mpt::CharsetUTF8, text ) ) ); } void module_impl::PushToCSoundFileLog( const std::string & text ) const { m_sndFile->AddToLog( LogError, mpt::ToUnicode( mpt::CharsetUTF8, text ) ); } void module_impl::PushToCSoundFileLog( int loglevel, const std::string & text ) const { m_sndFile->AddToLog( static_cast( loglevel ), mpt::ToUnicode( mpt::CharsetUTF8, text ) ); } module_impl::subsong_data::subsong_data( double duration, std::int32_t start_row, std::int32_t start_order, std::int32_t sequence ) : duration(duration) , start_row(start_row) , start_order(start_order) , sequence(sequence) { return; } static ResamplingMode filterlength_to_resamplingmode(std::int32_t length) { ResamplingMode result = SRCMODE_POLYPHASE; if ( length == 0 ) { result = SRCMODE_POLYPHASE; } else if ( length >= 8 ) { result = SRCMODE_POLYPHASE; } else if ( length >= 3 ) { result = SRCMODE_SPLINE; } else if ( length >= 2 ) { result = SRCMODE_LINEAR; } else if ( length >= 1 ) { result = SRCMODE_NEAREST; } else { throw openmpt::exception("negative filter length"); } return result; } static std::int32_t resamplingmode_to_filterlength(ResamplingMode mode) { switch ( mode ) { case SRCMODE_NEAREST: return 1; break; case SRCMODE_LINEAR: return 2; break; case SRCMODE_SPLINE: return 4; break; case SRCMODE_POLYPHASE: case SRCMODE_FIRFILTER: case SRCMODE_DEFAULT: return 8; default: throw openmpt::exception("unknown interpolation filter length set internally"); break; } } static void ramping_to_mixersettings( MixerSettings & settings, int ramping ) { if ( ramping == -1 ) { settings.SetVolumeRampUpMicroseconds( MixerSettings().GetVolumeRampUpMicroseconds() ); settings.SetVolumeRampDownMicroseconds( MixerSettings().GetVolumeRampDownMicroseconds() ); } else if ( ramping <= 0 ) { settings.SetVolumeRampUpMicroseconds( 0 ); settings.SetVolumeRampDownMicroseconds( 0 ); } else { settings.SetVolumeRampUpMicroseconds( ramping * 1000 ); settings.SetVolumeRampDownMicroseconds( ramping * 1000 ); } } static void mixersettings_to_ramping( int & ramping, const MixerSettings & settings ) { std::int32_t ramp_us = std::max( settings.GetVolumeRampUpMicroseconds(), settings.GetVolumeRampDownMicroseconds() ); if ( ( settings.GetVolumeRampUpMicroseconds() == MixerSettings().GetVolumeRampUpMicroseconds() ) && ( settings.GetVolumeRampDownMicroseconds() == MixerSettings().GetVolumeRampDownMicroseconds() ) ) { ramping = -1; } else if ( ramp_us <= 0 ) { ramping = 0; } else { ramping = ( ramp_us + 500 ) / 1000; } } std::string module_impl::mod_string_to_utf8( const std::string & encoded ) const { return mpt::ToCharset( mpt::CharsetUTF8, m_sndFile->GetCharsetInternal(), encoded ); } void module_impl::apply_mixer_settings( std::int32_t samplerate, int channels ) { bool samplerate_changed = static_cast( m_sndFile->m_MixerSettings.gdwMixingFreq ) != samplerate; bool channels_changed = static_cast( m_sndFile->m_MixerSettings.gnChannels ) != channels; if ( samplerate_changed || channels_changed ) { MixerSettings mixersettings = m_sndFile->m_MixerSettings; std::int32_t volrampin_us = mixersettings.GetVolumeRampUpMicroseconds(); std::int32_t volrampout_us = mixersettings.GetVolumeRampDownMicroseconds(); mixersettings.gdwMixingFreq = samplerate; mixersettings.gnChannels = channels; mixersettings.SetVolumeRampUpMicroseconds( volrampin_us ); mixersettings.SetVolumeRampDownMicroseconds( volrampout_us ); m_sndFile->SetMixerSettings( mixersettings ); } if ( samplerate_changed ) { m_sndFile->SuspendPlugins(); m_sndFile->ResumePlugins(); } } void module_impl::apply_libopenmpt_defaults() { set_render_param( module::RENDER_STEREOSEPARATION_PERCENT, 100 ); m_sndFile->Order.SetSequence( 0 ); } module_impl::subsongs_type module_impl::get_subsongs() const { std::vector subsongs; if ( m_sndFile->Order.GetNumSequences() == 0 ) { throw openmpt::exception("module contains no songs"); } for ( SEQUENCEINDEX seq = 0; seq < m_sndFile->Order.GetNumSequences(); ++seq ) { const std::vector lengths = m_sndFile->GetLength( eNoAdjust, GetLengthTarget( true ).StartPos( seq, 0, 0 ) ); for ( std::vector::const_iterator l = lengths.begin(); l != lengths.end(); ++l ) { subsongs.push_back( subsong_data( l->duration, l->startRow, l->startOrder, seq ) ); } } return subsongs; } void module_impl::init_subsongs( subsongs_type & subsongs ) const { subsongs = get_subsongs(); } bool module_impl::has_subsongs_inited() const { return !m_subsongs.empty(); } void module_impl::ctor( const std::map< std::string, std::string > & ctls ) { m_sndFile = mpt::make_unique(); m_loaded = false; m_Dither = mpt::make_unique(mpt::global_prng()); m_LogForwarder = mpt::make_unique( *m_Log ); m_sndFile->SetCustomLog( m_LogForwarder.get() ); m_current_subsong = 0; m_currentPositionSeconds = 0.0; m_Gain = 1.0f; m_ctl_load_skip_samples = false; m_ctl_load_skip_patterns = false; m_ctl_load_skip_plugins = false; m_ctl_load_skip_subsongs_init = false; m_ctl_seek_sync_samples = false; // init member variables that correspond to ctls for ( std::map< std::string, std::string >::const_iterator i = ctls.begin(); i != ctls.end(); ++i ) { ctl_set( i->first, i->second, false ); } } void module_impl::load( const FileReader & file, const std::map< std::string, std::string > & ctls ) { loader_log loaderlog; m_sndFile->SetCustomLog( &loaderlog ); { int load_flags = CSoundFile::loadCompleteModule; if ( m_ctl_load_skip_samples ) { load_flags &= ~CSoundFile::loadSampleData; } if ( m_ctl_load_skip_patterns ) { load_flags &= ~CSoundFile::loadPatternData; } if ( m_ctl_load_skip_plugins ) { load_flags &= ~(CSoundFile::loadPluginData | CSoundFile::loadPluginInstance); } if ( !m_sndFile->Create( file, static_cast( load_flags ) ) ) { throw openmpt::exception("error loading file"); } if ( !m_ctl_load_skip_subsongs_init ) { init_subsongs( m_subsongs ); } m_loaded = true; } m_sndFile->SetCustomLog( m_LogForwarder.get() ); std::vector > loaderMessages = loaderlog.GetMessages(); for ( std::vector >::iterator i = loaderMessages.begin(); i != loaderMessages.end(); ++i ) { PushToCSoundFileLog( i->first, i->second ); m_loaderMessages.push_back( mpt::ToCharset( mpt::CharsetUTF8, LogLevelToString( i->first ) ) + std::string(": ") + i->second ); } // init CSoundFile state that corresponds to ctls for ( std::map< std::string, std::string >::const_iterator i = ctls.begin(); i != ctls.end(); ++i ) { ctl_set( i->first, i->second, false ); } } bool module_impl::is_loaded() const { return m_loaded; } std::size_t module_impl::read_wrapper( std::size_t count, std::int16_t * left, std::int16_t * right, std::int16_t * rear_left, std::int16_t * rear_right ) { m_sndFile->ResetMixStat(); std::size_t count_read = 0; while ( count > 0 ) { std::int16_t * const buffers[4] = { left + count_read, right + count_read, rear_left + count_read, rear_right + count_read }; AudioReadTargetGainBuffer target(*m_Dither, 0, buffers, m_Gain); std::size_t count_chunk = m_sndFile->Read( static_cast( std::min( count, std::numeric_limits::max() / 2 / 4 / 4 ) ), // safety margin / samplesize / channels target ); if ( count_chunk == 0 ) { break; } count -= count_chunk; count_read += count_chunk; } return count_read; } std::size_t module_impl::read_wrapper( std::size_t count, float * left, float * right, float * rear_left, float * rear_right ) { m_sndFile->ResetMixStat(); std::size_t count_read = 0; while ( count > 0 ) { float * const buffers[4] = { left + count_read, right + count_read, rear_left + count_read, rear_right + count_read }; AudioReadTargetGainBuffer target(*m_Dither, 0, buffers, m_Gain); std::size_t count_chunk = m_sndFile->Read( static_cast( std::min( count, std::numeric_limits::max() / 2 / 4 / 4 ) ), // safety margin / samplesize / channels target ); if ( count_chunk == 0 ) { break; } count -= count_chunk; count_read += count_chunk; } return count_read; } std::size_t module_impl::read_interleaved_wrapper( std::size_t count, std::size_t channels, std::int16_t * interleaved ) { m_sndFile->ResetMixStat(); std::size_t count_read = 0; while ( count > 0 ) { AudioReadTargetGainBuffer target(*m_Dither, interleaved + count_read * channels, 0, m_Gain); std::size_t count_chunk = m_sndFile->Read( static_cast( std::min( count, std::numeric_limits::max() / 2 / 4 / 4 ) ), // safety margin / samplesize / channels target ); if ( count_chunk == 0 ) { break; } count -= count_chunk; count_read += count_chunk; } return count_read; } std::size_t module_impl::read_interleaved_wrapper( std::size_t count, std::size_t channels, float * interleaved ) { m_sndFile->ResetMixStat(); std::size_t count_read = 0; while ( count > 0 ) { AudioReadTargetGainBuffer target(*m_Dither, interleaved + count_read * channels, 0, m_Gain); std::size_t count_chunk = m_sndFile->Read( static_cast( std::min( count, std::numeric_limits::max() / 2 / 4 / 4 ) ), // safety margin / samplesize / channels target ); if ( count_chunk == 0 ) { break; } count -= count_chunk; count_read += count_chunk; } return count_read; } std::vector module_impl::get_supported_extensions() { std::vector retval; std::vector extensions = CSoundFile::GetSupportedExtensions( false ); std::copy( extensions.begin(), extensions.end(), std::back_insert_iterator >( retval ) ); return retval; } bool module_impl::is_extension_supported( const char * extension ) { return CSoundFile::IsExtensionSupported( extension ); } bool module_impl::is_extension_supported( const std::string & extension ) { return CSoundFile::IsExtensionSupported( extension.c_str() ); } double module_impl::could_open_probability( const OpenMPT::FileReader & file, double effort, std::unique_ptr log ) { try { if ( effort >= 0.8 ) { std::unique_ptr sndFile = mpt::make_unique(); std::unique_ptr logForwarder = mpt::make_unique( *log ); sndFile->SetCustomLog( logForwarder.get() ); if ( !sndFile->Create( file, CSoundFile::loadCompleteModule ) ) { return 0.0; } sndFile->Destroy(); return 1.0; } else if ( effort >= 0.6 ) { std::unique_ptr sndFile = mpt::make_unique(); std::unique_ptr logForwarder = mpt::make_unique( *log ); sndFile->SetCustomLog( logForwarder.get() ); if ( !sndFile->Create( file, CSoundFile::loadNoPatternOrPluginData ) ) { return 0.0; } sndFile->Destroy(); return 0.8; } else if ( effort >= 0.2 ) { std::unique_ptr sndFile = mpt::make_unique(); std::unique_ptr logForwarder = mpt::make_unique( *log ); sndFile->SetCustomLog( logForwarder.get() ); if ( !sndFile->Create( file, CSoundFile::onlyVerifyHeader ) ) { return 0.0; } sndFile->Destroy(); return 0.6; } else if ( effort >= 0.1 ) { FileReader::PinnedRawDataView view = file.GetPinnedRawDataView( probe_file_header_get_recommended_size() ); int probe_file_header_result = probe_file_header( probe_file_header_flags_default, view.data(), view.size(), file.GetLength() ); double result = 0.0; switch ( probe_file_header_result ) { case probe_file_header_result_success: result = 0.6; break; case probe_file_header_result_failure: result = 0.0; break; case probe_file_header_result_wantmoredata: result = 0.3; break; default: throw openmpt::exception(""); break; } return result; } else { return 0.2; } } catch ( ... ) { return 0.0; } } double module_impl::could_open_probability( callback_stream_wrapper stream, double effort, std::unique_ptr log ) { CallbackStream fstream; fstream.stream = stream.stream; fstream.read = stream.read; fstream.seek = stream.seek; fstream.tell = stream.tell; return could_open_probability( make_FileReader( fstream ), effort, std::move(log) ); } double module_impl::could_open_probability( std::istream & stream, double effort, std::unique_ptr log ) { return could_open_probability( make_FileReader( &stream ), effort, std::move(log) ); } std::size_t module_impl::probe_file_header_get_recommended_size() { return CSoundFile::ProbeRecommendedSize; } int module_impl::probe_file_header( std::uint64_t flags, const std::uint8_t * data, std::size_t size, std::uint64_t filesize ) { int result = 0; switch ( CSoundFile::Probe( static_cast( flags ), mpt::span( mpt::byte_cast( data ), size ), &filesize ) ) { case CSoundFile::ProbeSuccess: result = probe_file_header_result_success; break; case CSoundFile::ProbeFailure: result = probe_file_header_result_failure; break; case CSoundFile::ProbeWantMoreData: result = probe_file_header_result_wantmoredata; break; default: throw exception("internal error"); break; } return result; } int module_impl::probe_file_header( std::uint64_t flags, const void * data, std::size_t size, std::uint64_t filesize ) { int result = 0; switch ( CSoundFile::Probe( static_cast( flags ), mpt::span( mpt::void_cast( data ), size ), &filesize ) ) { case CSoundFile::ProbeSuccess: result = probe_file_header_result_success; break; case CSoundFile::ProbeFailure: result = probe_file_header_result_failure; break; case CSoundFile::ProbeWantMoreData: result = probe_file_header_result_wantmoredata; break; default: throw exception("internal error"); break; } return result; } int module_impl::probe_file_header( std::uint64_t flags, const std::uint8_t * data, std::size_t size ) { int result = 0; switch ( CSoundFile::Probe( static_cast( flags ), mpt::span( mpt::byte_cast( data ), size ), nullptr ) ) { case CSoundFile::ProbeSuccess: result = probe_file_header_result_success; break; case CSoundFile::ProbeFailure: result = probe_file_header_result_failure; break; case CSoundFile::ProbeWantMoreData: result = probe_file_header_result_wantmoredata; break; default: throw exception("internal error"); break; } return result; } int module_impl::probe_file_header( std::uint64_t flags, const void * data, std::size_t size ) { int result = 0; switch ( CSoundFile::Probe( static_cast( flags ), mpt::span( mpt::void_cast( data ), size ), nullptr ) ) { case CSoundFile::ProbeSuccess: result = probe_file_header_result_success; break; case CSoundFile::ProbeFailure: result = probe_file_header_result_failure; break; case CSoundFile::ProbeWantMoreData: result = probe_file_header_result_wantmoredata; break; default: throw exception("internal error"); break; } return result; } int module_impl::probe_file_header( std::uint64_t flags, std::istream & stream ) { int result = 0; char buffer[ PROBE_RECOMMENDED_SIZE ]; MemsetZero( buffer ); std::size_t size_read = 0; std::size_t size_toread = CSoundFile::ProbeRecommendedSize; if ( stream.bad() ) { throw exception("error reading stream"); } const bool seekable = FileDataContainerStdStreamSeekable::IsSeekable( &stream ); const uint64 filesize = ( seekable ? FileDataContainerStdStreamSeekable::GetLength( &stream ) : 0 ); while ( ( size_toread > 0 ) && stream ) { stream.read( buffer + size_read, size_toread ); if ( stream.bad() ) { throw exception("error reading stream"); } else if ( stream.eof() ) { // normal } else if ( stream.fail() ) { throw exception("error reading stream"); } else { // normal } std::size_t read_count = static_cast( stream.gcount() ); size_read += read_count; size_toread -= read_count; } switch ( CSoundFile::Probe( static_cast( flags ), mpt::span( mpt::byte_cast( buffer ), size_read ), seekable ? &filesize : nullptr ) ) { case CSoundFile::ProbeSuccess: result = probe_file_header_result_success; break; case CSoundFile::ProbeFailure: result = probe_file_header_result_failure; break; case CSoundFile::ProbeWantMoreData: result = probe_file_header_result_wantmoredata; break; default: throw exception("internal error"); break; } return result; } int module_impl::probe_file_header( std::uint64_t flags, callback_stream_wrapper stream ) { int result = 0; char buffer[ PROBE_RECOMMENDED_SIZE ]; MemsetZero( buffer ); std::size_t size_read = 0; std::size_t size_toread = CSoundFile::ProbeRecommendedSize; if ( !stream.read ) { throw exception("error reading stream"); } CallbackStream fstream; fstream.stream = stream.stream; fstream.read = stream.read; fstream.seek = stream.seek; fstream.tell = stream.tell; const bool seekable = FileDataContainerCallbackStreamSeekable::IsSeekable( fstream ); const uint64 filesize = ( seekable ? FileDataContainerCallbackStreamSeekable::GetLength( fstream ) : 0 ); while ( size_toread > 0 ) { std::size_t read_count = stream.read( stream.stream, buffer + size_read, size_toread ); size_read += read_count; size_toread -= read_count; if ( read_count == 0 ) { // eof break; } } switch ( CSoundFile::Probe( static_cast( flags ), mpt::span( mpt::byte_cast( buffer ), size_read ), seekable ? &filesize : nullptr ) ) { case CSoundFile::ProbeSuccess: result = probe_file_header_result_success; break; case CSoundFile::ProbeFailure: result = probe_file_header_result_failure; break; case CSoundFile::ProbeWantMoreData: result = probe_file_header_result_wantmoredata; break; default: throw exception("internal error"); break; } return result; } module_impl::module_impl( callback_stream_wrapper stream, std::unique_ptr log, const std::map< std::string, std::string > & ctls ) : m_Log(std::move(log)) { ctor( ctls ); CallbackStream fstream; fstream.stream = stream.stream; fstream.read = stream.read; fstream.seek = stream.seek; fstream.tell = stream.tell; load( make_FileReader( fstream ), ctls ); apply_libopenmpt_defaults(); } module_impl::module_impl( std::istream & stream, std::unique_ptr log, const std::map< std::string, std::string > & ctls ) : m_Log(std::move(log)) { ctor( ctls ); load( make_FileReader( &stream ), ctls ); apply_libopenmpt_defaults(); } module_impl::module_impl( const std::vector & data, std::unique_ptr log, const std::map< std::string, std::string > & ctls ) : m_Log(std::move(log)) { ctor( ctls ); load( make_FileReader( mpt::as_span( data ) ), ctls ); apply_libopenmpt_defaults(); } module_impl::module_impl( const std::vector & data, std::unique_ptr log, const std::map< std::string, std::string > & ctls ) : m_Log(std::move(log)) { ctor( ctls ); load( make_FileReader( mpt::byte_cast< mpt::span< const mpt::byte > >( mpt::as_span( data ) ) ), ctls ); apply_libopenmpt_defaults(); } module_impl::module_impl( const std::uint8_t * data, std::size_t size, std::unique_ptr log, const std::map< std::string, std::string > & ctls ) : m_Log(std::move(log)) { ctor( ctls ); load( make_FileReader( mpt::as_span( data, size ) ), ctls ); apply_libopenmpt_defaults(); } module_impl::module_impl( const char * data, std::size_t size, std::unique_ptr log, const std::map< std::string, std::string > & ctls ) : m_Log(std::move(log)) { ctor( ctls ); load( make_FileReader( mpt::byte_cast< mpt::span< const mpt::byte > >( mpt::as_span( data, size ) ) ), ctls ); apply_libopenmpt_defaults(); } module_impl::module_impl( const void * data, std::size_t size, std::unique_ptr log, const std::map< std::string, std::string > & ctls ) : m_Log(std::move(log)) { ctor( ctls ); load( make_FileReader( mpt::as_span( mpt::void_cast< const mpt::byte * >( data ), size ) ), ctls ); apply_libopenmpt_defaults(); } module_impl::~module_impl() { m_sndFile->Destroy(); } std::int32_t module_impl::get_render_param( int param ) const { std::int32_t result = 0; switch ( param ) { case module::RENDER_MASTERGAIN_MILLIBEL: { result = static_cast( 1000.0f * 2.0f * std::log10( m_Gain ) ); } break; case module::RENDER_STEREOSEPARATION_PERCENT: { result = m_sndFile->m_MixerSettings.m_nStereoSeparation * 100 / MixerSettings::StereoSeparationScale; } break; case module::RENDER_INTERPOLATIONFILTER_LENGTH: { result = resamplingmode_to_filterlength( m_sndFile->m_Resampler.m_Settings.SrcMode ); } break; case module::RENDER_VOLUMERAMPING_STRENGTH: { int ramping = 0; mixersettings_to_ramping( ramping, m_sndFile->m_MixerSettings ); result = ramping; } break; default: throw openmpt::exception("unknown render param"); break; } return result; } void module_impl::set_render_param( int param, std::int32_t value ) { switch ( param ) { case module::RENDER_MASTERGAIN_MILLIBEL: { m_Gain = static_cast( std::pow( 10.0f, value * 0.001f * 0.5f ) ); } break; case module::RENDER_STEREOSEPARATION_PERCENT: { std::int32_t newvalue = value * MixerSettings::StereoSeparationScale / 100; if ( newvalue != static_cast( m_sndFile->m_MixerSettings.m_nStereoSeparation ) ) { MixerSettings settings = m_sndFile->m_MixerSettings; settings.m_nStereoSeparation = newvalue; m_sndFile->SetMixerSettings( settings ); } } break; case module::RENDER_INTERPOLATIONFILTER_LENGTH: { CResamplerSettings newsettings = m_sndFile->m_Resampler.m_Settings; newsettings.SrcMode = filterlength_to_resamplingmode( value ); if ( newsettings != m_sndFile->m_Resampler.m_Settings ) { m_sndFile->SetResamplerSettings( newsettings ); } } break; case module::RENDER_VOLUMERAMPING_STRENGTH: { MixerSettings newsettings = m_sndFile->m_MixerSettings; ramping_to_mixersettings( newsettings, value ); if ( m_sndFile->m_MixerSettings.VolumeRampUpMicroseconds != newsettings.VolumeRampUpMicroseconds || m_sndFile->m_MixerSettings.VolumeRampDownMicroseconds != newsettings.VolumeRampDownMicroseconds ) { m_sndFile->SetMixerSettings( newsettings ); } } break; default: throw openmpt::exception("unknown render param"); break; } } std::size_t module_impl::read( std::int32_t samplerate, std::size_t count, std::int16_t * mono ) { if ( !mono ) { throw openmpt::exception("null pointer"); } apply_mixer_settings( samplerate, 1 ); count = read_wrapper( count, mono, 0, 0, 0 ); m_currentPositionSeconds += static_cast( count ) / static_cast( samplerate ); return count; } std::size_t module_impl::read( std::int32_t samplerate, std::size_t count, std::int16_t * left, std::int16_t * right ) { if ( !left || !right ) { throw openmpt::exception("null pointer"); } apply_mixer_settings( samplerate, 2 ); count = read_wrapper( count, left, right, 0, 0 ); m_currentPositionSeconds += static_cast( count ) / static_cast( samplerate ); return count; } std::size_t module_impl::read( std::int32_t samplerate, std::size_t count, std::int16_t * left, std::int16_t * right, std::int16_t * rear_left, std::int16_t * rear_right ) { if ( !left || !right || !rear_left || !rear_right ) { throw openmpt::exception("null pointer"); } apply_mixer_settings( samplerate, 4 ); count = read_wrapper( count, left, right, rear_left, rear_right ); m_currentPositionSeconds += static_cast( count ) / static_cast( samplerate ); return count; } std::size_t module_impl::read( std::int32_t samplerate, std::size_t count, float * mono ) { if ( !mono ) { throw openmpt::exception("null pointer"); } apply_mixer_settings( samplerate, 1 ); count = read_wrapper( count, mono, 0, 0, 0 ); m_currentPositionSeconds += static_cast( count ) / static_cast( samplerate ); return count; } std::size_t module_impl::read( std::int32_t samplerate, std::size_t count, float * left, float * right ) { if ( !left || !right ) { throw openmpt::exception("null pointer"); } apply_mixer_settings( samplerate, 2 ); count = read_wrapper( count, left, right, 0, 0 ); m_currentPositionSeconds += static_cast( count ) / static_cast( samplerate ); return count; } std::size_t module_impl::read( std::int32_t samplerate, std::size_t count, float * left, float * right, float * rear_left, float * rear_right ) { if ( !left || !right || !rear_left || !rear_right ) { throw openmpt::exception("null pointer"); } apply_mixer_settings( samplerate, 4 ); count = read_wrapper( count, left, right, rear_left, rear_right ); m_currentPositionSeconds += static_cast( count ) / static_cast( samplerate ); return count; } std::size_t module_impl::read_interleaved_stereo( std::int32_t samplerate, std::size_t count, std::int16_t * interleaved_stereo ) { if ( !interleaved_stereo ) { throw openmpt::exception("null pointer"); } apply_mixer_settings( samplerate, 2 ); count = read_interleaved_wrapper( count, 2, interleaved_stereo ); m_currentPositionSeconds += static_cast( count ) / static_cast( samplerate ); return count; } std::size_t module_impl::read_interleaved_quad( std::int32_t samplerate, std::size_t count, std::int16_t * interleaved_quad ) { if ( !interleaved_quad ) { throw openmpt::exception("null pointer"); } apply_mixer_settings( samplerate, 4 ); count = read_interleaved_wrapper( count, 4, interleaved_quad ); m_currentPositionSeconds += static_cast( count ) / static_cast( samplerate ); return count; } std::size_t module_impl::read_interleaved_stereo( std::int32_t samplerate, std::size_t count, float * interleaved_stereo ) { if ( !interleaved_stereo ) { throw openmpt::exception("null pointer"); } apply_mixer_settings( samplerate, 2 ); count = read_interleaved_wrapper( count, 2, interleaved_stereo ); m_currentPositionSeconds += static_cast( count ) / static_cast( samplerate ); return count; } std::size_t module_impl::read_interleaved_quad( std::int32_t samplerate, std::size_t count, float * interleaved_quad ) { if ( !interleaved_quad ) { throw openmpt::exception("null pointer"); } apply_mixer_settings( samplerate, 4 ); count = read_interleaved_wrapper( count, 4, interleaved_quad ); m_currentPositionSeconds += static_cast( count ) / static_cast( samplerate ); return count; } double module_impl::get_duration_seconds() const { std::unique_ptr subsongs_temp = has_subsongs_inited() ? std::unique_ptr() : mpt::make_unique( get_subsongs() ); const subsongs_type & subsongs = has_subsongs_inited() ? m_subsongs : *subsongs_temp; if ( m_current_subsong == all_subsongs ) { // Play all subsongs consecutively. double total_duration = 0.0; for ( std::size_t i = 0; i < subsongs.size(); ++i ) { total_duration += subsongs[i].duration; } return total_duration; } return subsongs[m_current_subsong].duration; } void module_impl::select_subsong( std::int32_t subsong ) { std::unique_ptr subsongs_temp = has_subsongs_inited() ? std::unique_ptr() : mpt::make_unique( get_subsongs() ); const subsongs_type & subsongs = has_subsongs_inited() ? m_subsongs : *subsongs_temp; if ( subsong != all_subsongs && ( subsong < 0 || subsong >= static_cast( subsongs.size() ) ) ) { throw openmpt::exception("invalid subsong"); } m_current_subsong = subsong; m_sndFile->m_SongFlags.set( SONG_PLAYALLSONGS, subsong == all_subsongs ); if ( subsong == all_subsongs ) { subsong = 0; } m_sndFile->Order.SetSequence( static_cast( subsongs[subsong].sequence ) ); set_position_order_row( subsongs[subsong].start_order, subsongs[subsong].start_row ); m_currentPositionSeconds = 0.0; } std::int32_t module_impl::get_selected_subsong() const { return m_current_subsong; } void module_impl::set_repeat_count( std::int32_t repeat_count ) { m_sndFile->SetRepeatCount( repeat_count ); } std::int32_t module_impl::get_repeat_count() const { return m_sndFile->GetRepeatCount(); } double module_impl::get_position_seconds() const { return m_currentPositionSeconds; } double module_impl::set_position_seconds( double seconds ) { std::unique_ptr subsongs_temp = has_subsongs_inited() ? std::unique_ptr() : mpt::make_unique( get_subsongs() ); const subsongs_type & subsongs = has_subsongs_inited() ? m_subsongs : *subsongs_temp; const subsong_data * subsong = 0; double base_seconds = 0.0; if ( m_current_subsong == all_subsongs ) { // When playing all subsongs, find out which subsong this time would belong to. subsong = &subsongs.back(); for ( std::size_t i = 0; i < subsongs.size(); ++i ) { if ( base_seconds + subsongs[i].duration > seconds ) { subsong = &subsongs[i]; break; } base_seconds += subsong->duration; } seconds -= base_seconds; } else { subsong = &subsongs[m_current_subsong]; } GetLengthType t = m_sndFile->GetLength( eNoAdjust, GetLengthTarget( seconds ).StartPos( static_cast( subsong->sequence ), static_cast( subsong->start_order ), static_cast( subsong->start_row ) ) ).back(); m_sndFile->m_PlayState.m_nCurrentOrder = t.lastOrder; m_sndFile->SetCurrentOrder( t.lastOrder ); m_sndFile->m_PlayState.m_nNextRow = t.lastRow; m_currentPositionSeconds = base_seconds + m_sndFile->GetLength( m_ctl_seek_sync_samples ? eAdjustSamplePositions : eAdjust, GetLengthTarget( t.lastOrder, t.lastRow ).StartPos( static_cast( subsong->sequence ), static_cast( subsong->start_order ), static_cast( subsong->start_row ) ) ).back().duration; return m_currentPositionSeconds; } double module_impl::set_position_order_row( std::int32_t order, std::int32_t row ) { if ( order < 0 || order >= m_sndFile->Order().GetLengthTailTrimmed() ) { return m_currentPositionSeconds; } PATTERNINDEX pattern = m_sndFile->Order()[order]; if ( m_sndFile->Patterns.IsValidIndex( pattern ) ) { if ( row < 0 || row >= static_cast( m_sndFile->Patterns[pattern].GetNumRows() ) ) { return m_currentPositionSeconds; } } else { row = 0; } m_sndFile->m_PlayState.m_nCurrentOrder = static_cast( order ); m_sndFile->SetCurrentOrder( static_cast( order ) ); m_sndFile->m_PlayState.m_nNextRow = static_cast( row ); m_currentPositionSeconds = m_sndFile->GetLength( m_ctl_seek_sync_samples ? eAdjustSamplePositions : eAdjust, GetLengthTarget( static_cast( order ), static_cast( row ) ) ).back().duration; return m_currentPositionSeconds; } std::vector module_impl::get_metadata_keys() const { std::vector retval; retval.push_back("type"); retval.push_back("type_long"); retval.push_back("container"); retval.push_back("container_long"); retval.push_back("tracker"); retval.push_back("artist"); retval.push_back("title"); retval.push_back("date"); retval.push_back("message"); retval.push_back("message_raw"); retval.push_back("warnings"); return retval; } std::string module_impl::get_metadata( const std::string & key ) const { if ( key == std::string("type") ) { return mpt::ToCharset(mpt::CharsetUTF8, CSoundFile::ModTypeToString( m_sndFile->GetType() ) ); } else if ( key == std::string("type_long") ) { return mpt::ToCharset(mpt::CharsetUTF8, CSoundFile::ModTypeToTracker( m_sndFile->GetType() ) ); } else if ( key == std::string("container") ) { return mpt::ToCharset(mpt::CharsetUTF8, CSoundFile::ModContainerTypeToString( m_sndFile->GetContainerType() ) ); } else if ( key == std::string("container_long") ) { return mpt::ToCharset(mpt::CharsetUTF8, CSoundFile::ModContainerTypeToTracker( m_sndFile->GetContainerType() ) ); } else if ( key == std::string("tracker") ) { return mpt::ToCharset(mpt::CharsetUTF8, m_sndFile->m_madeWithTracker ); } else if ( key == std::string("artist") ) { return mpt::ToCharset( mpt::CharsetUTF8, m_sndFile->m_songArtist ); } else if ( key == std::string("title") ) { return mod_string_to_utf8( m_sndFile->GetTitle() ); } else if ( key == std::string("date") ) { if ( m_sndFile->GetFileHistory().empty() ) { return std::string(); } return mpt::ToCharset(mpt::CharsetUTF8, m_sndFile->GetFileHistory()[m_sndFile->GetFileHistory().size() - 1].AsISO8601() ); } else if ( key == std::string("message") ) { std::string retval = m_sndFile->m_songMessage.GetFormatted( SongMessage::leLF ); if ( retval.empty() ) { std::string tmp; bool valid = false; for ( INSTRUMENTINDEX i = 1; i <= m_sndFile->GetNumInstruments(); ++i ) { std::string instname = m_sndFile->GetInstrumentName( i ); if ( !instname.empty() ) { valid = true; } tmp += instname; tmp += "\n"; } if ( valid ) { retval = tmp; } } if ( retval.empty() ) { std::string tmp; bool valid = false; for ( SAMPLEINDEX i = 1; i <= m_sndFile->GetNumSamples(); ++i ) { std::string samplename = m_sndFile->GetSampleName( i ); if ( !samplename.empty() ) { valid = true; } tmp += samplename; tmp += "\n"; } if ( valid ) { retval = tmp; } } return mod_string_to_utf8( retval ); } else if ( key == std::string("message_raw") ) { std::string retval = m_sndFile->m_songMessage.GetFormatted( SongMessage::leLF ); return mod_string_to_utf8( retval ); } else if ( key == std::string("warnings") ) { std::string retval; bool first = true; for ( std::vector::const_iterator i = m_loaderMessages.begin(); i != m_loaderMessages.end(); ++i ) { if ( !first ) { retval += "\n"; } else { first = false; } retval += *i; } return retval; } return ""; } std::int32_t module_impl::get_current_speed() const { return m_sndFile->m_PlayState.m_nMusicSpeed; } std::int32_t module_impl::get_current_tempo() const { return static_cast( m_sndFile->m_PlayState.m_nMusicTempo.GetInt() ); } std::int32_t module_impl::get_current_order() const { return m_sndFile->GetCurrentOrder(); } std::int32_t module_impl::get_current_pattern() const { std::int32_t order = m_sndFile->GetCurrentOrder(); if ( order < 0 || order >= m_sndFile->Order().GetLengthTailTrimmed() ) { return m_sndFile->GetCurrentPattern(); } std::int32_t pattern = m_sndFile->Order()[order]; if ( !m_sndFile->Patterns.IsValidIndex( static_cast( pattern ) ) ) { return -1; } return pattern; } std::int32_t module_impl::get_current_row() const { return m_sndFile->m_PlayState.m_nRow; } std::int32_t module_impl::get_current_playing_channels() const { return m_sndFile->GetMixStat(); } float module_impl::get_current_channel_vu_mono( std::int32_t channel ) const { if ( channel < 0 || channel >= m_sndFile->GetNumChannels() ) { return 0.0f; } const float left = m_sndFile->m_PlayState.Chn[channel].nLeftVU * (1.0f/128.0f); const float right = m_sndFile->m_PlayState.Chn[channel].nRightVU * (1.0f/128.0f); return std::sqrt(left*left + right*right); } float module_impl::get_current_channel_vu_left( std::int32_t channel ) const { if ( channel < 0 || channel >= m_sndFile->GetNumChannels() ) { return 0.0f; } return m_sndFile->m_PlayState.Chn[channel].dwFlags[CHN_SURROUND] ? 0.0f : m_sndFile->m_PlayState.Chn[channel].nLeftVU * (1.0f/128.0f); } float module_impl::get_current_channel_vu_right( std::int32_t channel ) const { if ( channel < 0 || channel >= m_sndFile->GetNumChannels() ) { return 0.0f; } return m_sndFile->m_PlayState.Chn[channel].dwFlags[CHN_SURROUND] ? 0.0f : m_sndFile->m_PlayState.Chn[channel].nRightVU * (1.0f/128.0f); } float module_impl::get_current_channel_vu_rear_left( std::int32_t channel ) const { if ( channel < 0 || channel >= m_sndFile->GetNumChannels() ) { return 0.0f; } return m_sndFile->m_PlayState.Chn[channel].dwFlags[CHN_SURROUND] ? m_sndFile->m_PlayState.Chn[channel].nLeftVU * (1.0f/128.0f) : 0.0f; } float module_impl::get_current_channel_vu_rear_right( std::int32_t channel ) const { if ( channel < 0 || channel >= m_sndFile->GetNumChannels() ) { return 0.0f; } return m_sndFile->m_PlayState.Chn[channel].dwFlags[CHN_SURROUND] ? m_sndFile->m_PlayState.Chn[channel].nRightVU * (1.0f/128.0f) : 0.0f; } std::int32_t module_impl::get_num_subsongs() const { std::unique_ptr subsongs_temp = has_subsongs_inited() ? std::unique_ptr() : mpt::make_unique( get_subsongs() ); const subsongs_type & subsongs = has_subsongs_inited() ? m_subsongs : *subsongs_temp; return static_cast( subsongs.size() ); } std::int32_t module_impl::get_num_channels() const { return m_sndFile->GetNumChannels(); } std::int32_t module_impl::get_num_orders() const { return m_sndFile->Order().GetLengthTailTrimmed(); } std::int32_t module_impl::get_num_patterns() const { return m_sndFile->Patterns.GetNumPatterns(); } std::int32_t module_impl::get_num_instruments() const { return m_sndFile->GetNumInstruments(); } std::int32_t module_impl::get_num_samples() const { return m_sndFile->GetNumSamples(); } std::vector module_impl::get_subsong_names() const { std::vector retval; std::unique_ptr subsongs_temp = has_subsongs_inited() ? std::unique_ptr() : mpt::make_unique( get_subsongs() ); const subsongs_type & subsongs = has_subsongs_inited() ? m_subsongs : *subsongs_temp; for ( std::size_t i = 0; i < subsongs.size(); ++i ) { retval.push_back( mod_string_to_utf8( m_sndFile->Order( static_cast( subsongs[i].sequence ) ).GetName() ) ); } return retval; } std::vector module_impl::get_channel_names() const { std::vector retval; for ( CHANNELINDEX i = 0; i < m_sndFile->GetNumChannels(); ++i ) { retval.push_back( mod_string_to_utf8( m_sndFile->ChnSettings[i].szName ) ); } return retval; } std::vector module_impl::get_order_names() const { std::vector retval; for ( ORDERINDEX i = 0; i < m_sndFile->Order().GetLengthTailTrimmed(); ++i ) { PATTERNINDEX pat = m_sndFile->Order()[i]; if ( m_sndFile->Patterns.IsValidIndex( pat ) ) { retval.push_back( mod_string_to_utf8( m_sndFile->Patterns[ m_sndFile->Order()[i] ].GetName() ) ); } else { if ( pat == m_sndFile->Order.GetIgnoreIndex() ) { retval.push_back( "+++ skip" ); } else if ( pat == m_sndFile->Order.GetInvalidPatIndex() ) { retval.push_back( "--- stop" ); } else { retval.push_back( "???" ); } } } return retval; } std::vector module_impl::get_pattern_names() const { std::vector retval; for ( PATTERNINDEX i = 0; i < m_sndFile->Patterns.GetNumPatterns(); ++i ) { retval.push_back( mod_string_to_utf8( m_sndFile->Patterns[i].GetName() ) ); } return retval; } std::vector module_impl::get_instrument_names() const { std::vector retval; for ( INSTRUMENTINDEX i = 1; i <= m_sndFile->GetNumInstruments(); ++i ) { retval.push_back( mod_string_to_utf8( m_sndFile->GetInstrumentName( i ) ) ); } return retval; } std::vector module_impl::get_sample_names() const { std::vector retval; for ( SAMPLEINDEX i = 1; i <= m_sndFile->GetNumSamples(); ++i ) { retval.push_back( mod_string_to_utf8( m_sndFile->GetSampleName( i ) ) ); } return retval; } std::int32_t module_impl::get_order_pattern( std::int32_t o ) const { if ( o < 0 || o >= m_sndFile->Order().GetLengthTailTrimmed() ) { return -1; } return m_sndFile->Order()[o]; } std::int32_t module_impl::get_pattern_num_rows( std::int32_t p ) const { if ( !IsInRange( p, std::numeric_limits::min(), std::numeric_limits::max() ) || !m_sndFile->Patterns.IsValidPat( static_cast( p ) ) ) { return 0; } return m_sndFile->Patterns[p].GetNumRows(); } std::uint8_t module_impl::get_pattern_row_channel_command( std::int32_t p, std::int32_t r, std::int32_t c, int cmd ) const { if ( !IsInRange( p, std::numeric_limits::min(), std::numeric_limits::max() ) || !m_sndFile->Patterns.IsValidPat( static_cast( p ) ) ) { return 0; } const CPattern &pattern = m_sndFile->Patterns[p]; if ( r < 0 || r >= static_cast( pattern.GetNumRows() ) ) { return 0; } if ( c < 0 || c >= m_sndFile->GetNumChannels() ) { return 0; } if ( cmd < module::command_note || cmd > module::command_parameter ) { return 0; } const ModCommand & cell = *pattern.GetpModCommand( static_cast( r ), static_cast( c ) ); switch ( cmd ) { case module::command_note: return cell.note; break; case module::command_instrument: return cell.instr; break; case module::command_volumeffect: return cell.volcmd; break; case module::command_effect: return cell.command; break; case module::command_volume: return cell.vol; break; case module::command_parameter: return cell.param; break; } return 0; } /* highlight chars explained: : empty/space . : empty/dot n : generic note m : special note i : generic instrument u : generic volume column effect v : generic volume column parameter e : generic effect column effect f : generic effect column parameter */ std::pair< std::string, std::string > module_impl::format_and_highlight_pattern_row_channel_command( std::int32_t p, std::int32_t r, std::int32_t c, int cmd ) const { if ( !IsInRange( p, std::numeric_limits::min(), std::numeric_limits::max() ) || !m_sndFile->Patterns.IsValidPat( static_cast( p ) ) ) { return std::make_pair( std::string(), std::string() ); } const CPattern &pattern = m_sndFile->Patterns[p]; if ( r < 0 || r >= static_cast( pattern.GetNumRows() ) ) { return std::make_pair( std::string(), std::string() ); } if ( c < 0 || c >= m_sndFile->GetNumChannels() ) { return std::make_pair( std::string(), std::string() ); } if ( cmd < module::command_note || cmd > module::command_parameter ) { return std::make_pair( std::string(), std::string() ); } const ModCommand & cell = *pattern.GetpModCommand( static_cast( r ), static_cast( c ) ); switch ( cmd ) { case module::command_note: return std::make_pair( ( cell.IsNote() || cell.IsSpecialNote() ) ? m_sndFile->GetNoteName( cell.note, cell.instr ) : std::string("...") , ( cell.IsNote() ) ? std::string("nnn") : cell.IsSpecialNote() ? std::string("mmm") : std::string("...") ); break; case module::command_instrument: return std::make_pair( cell.instr ? mpt::fmt::HEX0<2>( cell.instr ) : std::string("..") , cell.instr ? std::string("ii") : std::string("..") ); break; case module::command_volumeffect: return std::make_pair( cell.IsPcNote() ? std::string(" ") : cell.volcmd != VOLCMD_NONE ? std::string( 1, m_sndFile->GetModSpecifications().GetVolEffectLetter( cell.volcmd ) ) : std::string(" ") , cell.IsPcNote() ? std::string(" ") : cell.volcmd != VOLCMD_NONE ? std::string("u") : std::string(" ") ); break; case module::command_volume: return std::make_pair( cell.IsPcNote() ? mpt::fmt::HEX0<2>( cell.GetValueVolCol() & 0xff ) : cell.volcmd != VOLCMD_NONE ? mpt::fmt::HEX0<2>( cell.vol ) : std::string("..") , cell.IsPcNote() ? std::string("vv") : cell.volcmd != VOLCMD_NONE ? std::string("vv") : std::string("..") ); break; case module::command_effect: return std::make_pair( cell.IsPcNote() ? mpt::fmt::HEX0<1>( ( cell.GetValueEffectCol() & 0x0f00 ) > 16 ) : cell.command != CMD_NONE ? std::string( 1, m_sndFile->GetModSpecifications().GetEffectLetter( cell.command ) ) : std::string(".") , cell.IsPcNote() ? std::string("e") : cell.command != CMD_NONE ? std::string("e") : std::string(".") ); break; case module::command_parameter: return std::make_pair( cell.IsPcNote() ? mpt::fmt::HEX0<2>( cell.GetValueEffectCol() & 0x00ff ) : cell.command != CMD_NONE ? mpt::fmt::HEX0<2>( cell.param ) : std::string("..") , cell.IsPcNote() ? std::string("ff") : cell.command != CMD_NONE ? std::string("ff") : std::string("..") ); break; } return std::make_pair( std::string(), std::string() ); } std::string module_impl::format_pattern_row_channel_command( std::int32_t p, std::int32_t r, std::int32_t c, int cmd ) const { return format_and_highlight_pattern_row_channel_command( p, r, c, cmd ).first; } std::string module_impl::highlight_pattern_row_channel_command( std::int32_t p, std::int32_t r, std::int32_t c, int cmd ) const { return format_and_highlight_pattern_row_channel_command( p, r, c, cmd ).second; } std::pair< std::string, std::string > module_impl::format_and_highlight_pattern_row_channel( std::int32_t p, std::int32_t r, std::int32_t c, std::size_t width, bool pad ) const { std::string text = pad ? std::string( width, ' ' ) : std::string(); std::string high = pad ? std::string( width, ' ' ) : std::string(); if ( !IsInRange( p, std::numeric_limits::min(), std::numeric_limits::max() ) || !m_sndFile->Patterns.IsValidPat( static_cast( p ) ) ) { return std::make_pair( text, high ); } const CPattern &pattern = m_sndFile->Patterns[p]; if ( r < 0 || r >= static_cast( pattern.GetNumRows() ) ) { return std::make_pair( text, high ); } if ( c < 0 || c >= m_sndFile->GetNumChannels() ) { return std::make_pair( text, high ); } // 0000000001111 // 1234567890123 // "NNN IIvVV EFF" const ModCommand & cell = *pattern.GetpModCommand( static_cast( r ), static_cast( c ) ); text.clear(); high.clear(); text += ( cell.IsNote() || cell.IsSpecialNote() ) ? m_sndFile->GetNoteName( cell.note, cell.instr ) : std::string("..."); high += ( cell.IsNote() ) ? std::string("nnn") : cell.IsSpecialNote() ? std::string("mmm") : std::string("..."); if ( ( width == 0 ) || ( width >= 6 ) ) { text += std::string(" "); high += std::string(" "); text += cell.instr ? mpt::fmt::HEX0<2>( cell.instr ) : std::string(".."); high += cell.instr ? std::string("ii") : std::string(".."); } if ( ( width == 0 ) || ( width >= 9 ) ) { text += cell.IsPcNote() ? std::string(" ") + mpt::fmt::HEX0<2>( cell.GetValueVolCol() & 0xff ) : cell.volcmd != VOLCMD_NONE ? std::string( 1, m_sndFile->GetModSpecifications().GetVolEffectLetter( cell.volcmd ) ) + mpt::fmt::HEX0<2>( cell.vol ) : std::string(" .."); high += cell.IsPcNote() ? std::string(" vv") : cell.volcmd != VOLCMD_NONE ? std::string("uvv") : std::string(" .."); } if ( ( width == 0 ) || ( width >= 13 ) ) { text += std::string(" "); high += std::string(" "); text += cell.IsPcNote() ? mpt::fmt::HEX0<3>( cell.GetValueEffectCol() & 0x0fff ) : cell.command != CMD_NONE ? std::string( 1, m_sndFile->GetModSpecifications().GetEffectLetter( cell.command ) ) + mpt::fmt::HEX0<2>( cell.param ) : std::string("..."); high += cell.IsPcNote() ? std::string("eff") : cell.command != CMD_NONE ? std::string("eff") : std::string("..."); } if ( ( width != 0 ) && ( text.length() > width ) ) { text = text.substr( 0, width ); } else if ( ( width != 0 ) && pad ) { text += std::string( width - text.length(), ' ' ); } if ( ( width != 0 ) && ( high.length() > width ) ) { high = high.substr( 0, width ); } else if ( ( width != 0 ) && pad ) { high += std::string( width - high.length(), ' ' ); } return std::make_pair( text, high ); } std::string module_impl::format_pattern_row_channel( std::int32_t p, std::int32_t r, std::int32_t c, std::size_t width, bool pad ) const { return format_and_highlight_pattern_row_channel( p, r, c, width, pad ).first; } std::string module_impl::highlight_pattern_row_channel( std::int32_t p, std::int32_t r, std::int32_t c, std::size_t width, bool pad ) const { return format_and_highlight_pattern_row_channel( p, r, c, width, pad ).second; } std::vector module_impl::get_ctls() const { std::vector retval; retval.push_back( "load.skip_samples" ); retval.push_back( "load.skip_patterns" ); retval.push_back( "load.skip_plugins" ); retval.push_back( "load.skip_subsongs_init" ); retval.push_back( "seek.sync_samples" ); retval.push_back( "subsong" ); retval.push_back( "play.tempo_factor" ); retval.push_back( "play.pitch_factor" ); retval.push_back( "render.resampler.emulate_amiga" ); retval.push_back( "dither" ); return retval; } std::string module_impl::ctl_get( std::string ctl, bool throw_if_unknown ) const { if ( !ctl.empty() ) { char rightmost = ctl.back(); if ( rightmost == '!' || rightmost == '?' ) { if ( rightmost == '!' ) { throw_if_unknown = true; } else if ( rightmost == '?' ) { throw_if_unknown = false; } ctl = ctl.substr( 0, ctl.length() - 1 ); } } if ( ctl == "" ) { throw openmpt::exception("empty ctl"); } else if ( ctl == "load.skip_samples" || ctl == "load_skip_samples" ) { return mpt::fmt::val( m_ctl_load_skip_samples ); } else if ( ctl == "load.skip_patterns" || ctl == "load_skip_patterns" ) { return mpt::fmt::val( m_ctl_load_skip_patterns ); } else if ( ctl == "load.skip_plugins" ) { return mpt::fmt::val( m_ctl_load_skip_plugins ); } else if ( ctl == "load.skip_subsongs_init" ) { return mpt::fmt::val( m_ctl_load_skip_subsongs_init ); } else if ( ctl == "seek.sync_samples" ) { return mpt::fmt::val( m_ctl_seek_sync_samples ); } else if ( ctl == "subsong" ) { return mpt::fmt::val( get_selected_subsong() ); } else if ( ctl == "play.tempo_factor" ) { if ( !is_loaded() ) { return "1.0"; } return mpt::fmt::val( 65536.0 / m_sndFile->m_nTempoFactor ); } else if ( ctl == "play.pitch_factor" ) { if ( !is_loaded() ) { return "1.0"; } return mpt::fmt::val( m_sndFile->m_nFreqFactor / 65536.0 ); } else if ( ctl == "render.resampler.emulate_amiga" ) { return mpt::fmt::val( m_sndFile->m_Resampler.m_Settings.emulateAmiga ); } else if ( ctl == "dither" ) { return mpt::fmt::val( static_cast( m_Dither->GetMode() ) ); } else { if ( throw_if_unknown ) { throw openmpt::exception("unknown ctl: " + ctl); } else { return std::string(); } } } void module_impl::ctl_set( std::string ctl, const std::string & value, bool throw_if_unknown ) { if ( !ctl.empty() ) { char rightmost = ctl.back(); if ( rightmost == '!' || rightmost == '?' ) { if ( rightmost == '!' ) { throw_if_unknown = true; } else if ( rightmost == '?' ) { throw_if_unknown = false; } ctl = ctl.substr( 0, ctl.length() - 1 ); } } if ( ctl == "" ) { throw openmpt::exception("empty ctl: := " + value); } else if ( ctl == "load.skip_samples" || ctl == "load_skip_samples" ) { m_ctl_load_skip_samples = ConvertStrTo( value ); } else if ( ctl == "load.skip_patterns" || ctl == "load_skip_patterns" ) { m_ctl_load_skip_patterns = ConvertStrTo( value ); } else if ( ctl == "load.skip_plugins" ) { m_ctl_load_skip_plugins = ConvertStrTo( value ); } else if ( ctl == "load.skip_subsongs_init" ) { m_ctl_load_skip_subsongs_init = ConvertStrTo( value ); } else if ( ctl == "seek.sync_samples" ) { m_ctl_seek_sync_samples = ConvertStrTo( value ); } else if ( ctl == "subsong" ) { select_subsong( ConvertStrTo( value ) ); } else if ( ctl == "play.tempo_factor" ) { if ( !is_loaded() ) { return; } double factor = ConvertStrTo( value ); if ( factor <= 0.0 || factor > 4.0 ) { throw openmpt::exception("invalid tempo factor"); } m_sndFile->m_nTempoFactor = Util::Round( 65536.0 / factor ); m_sndFile->RecalculateSamplesPerTick(); } else if ( ctl == "play.pitch_factor" ) { if ( !is_loaded() ) { return; } double factor = ConvertStrTo( value ); if ( factor <= 0.0 || factor > 4.0 ) { throw openmpt::exception("invalid pitch factor"); } m_sndFile->m_nFreqFactor = Util::Round( 65536.0 * factor ); m_sndFile->RecalculateSamplesPerTick(); } else if ( ctl == "render.resampler.emulate_amiga" ) { CResamplerSettings newsettings = m_sndFile->m_Resampler.m_Settings; newsettings.emulateAmiga = ConvertStrTo( value ); if ( newsettings != m_sndFile->m_Resampler.m_Settings ) { m_sndFile->SetResamplerSettings( newsettings ); } } else if ( ctl == "dither" ) { int dither = ConvertStrTo( value ); if ( dither < 0 || dither >= NumDitherModes ) { dither = DitherDefault; } m_Dither->SetMode( static_cast( dither ) ); } else { if ( throw_if_unknown ) { throw openmpt::exception("unknown ctl: " + ctl + " := " + value); } else { // ignore } } } } // namespace openmpt libopenmpt-0.3.6+release.autotools/libopenmpt/bindings/0000755000372100037210000000000013235362225020307 500000000000000libopenmpt-0.3.6+release.autotools/libopenmpt/bindings/freebasic/0000755000372100037210000000000013235362226022233 500000000000000libopenmpt-0.3.6+release.autotools/libopenmpt/bindings/freebasic/libopenmpt.bi0000644000372100037210000026765613231373725024670 00000000000000/' ' libopenmpt.bi ' ------------- ' Purpose: libopenmpt public interface for FreeBASIC ' Notes : (currently none) ' Authors: Johannes Schultz ' OpenMPT Devs ' The OpenMPT source code is released under the BSD license. Read LICENSE for more details. '/ #Include Once "crt/stdio.bi" #Include Once "file.bi" #Inclib "openmpt" /'* \page libopenmpt_freebasic_overview FreeBASIC API \section libopenmpt_freebasic_error Error Handling - Functions with no return value in the corresponding C++ API return 0 on failure and 1 on success. - Functions that return integer values signal error condition by returning an invalid value (-1 in most cases, 0 in some cases). - All functions that work on an openmpt_module object will call an openmpt_error_func and depending on the value returned by this function log the error code and/xor/or store it inside the openmpt_module object. Stored error codes can be accessed with the openmpt_module_error_get_last() and openmpt_module_error_get_last_message(). Stored errors will not get cleared automatically and should be reset with openmpt_module_error_clear(). - Some functions not directly related to an openmpt_module object take an explicit openmpt_error_func error function callback and a pointer to an int and behave analog to the functions working on an openmpt_module object. \section libopenmpt_freebasic_strings Strings - All strings returned from libopenmpt are encoded in UTF-8. - All strings passed to libopenmpt should also be encoded in UTF-8. Behaviour in case of invalid UTF-8 is unspecified. - libopenmpt does not enforce or expect any particular Unicode normalization form. - Some libopenmpt functions return strings and are provided in two flavours: The raw libopenmpt function (with a trailing underscore) and a FreeBASIC wrapper function that completely takes care of memory handling (recommended). All strings returned from raw libopenmpt functions are dynamically allocated and must be freed with openmpt_free_string(). When using the FreeBASIC wrappers (which is the recommended way), FreeBASIC automatically takes care of this. - All strings passed to libopenmpt are copied. No ownership is assumed or transferred. \section libopenmpt_freebasic_outputformat Output Format libopenmpt supports a wide range of PCM output formats: [8000..192000]/[mono|stereo|quad]/[f32|i16]. Unless you have some very specific requirements demanding a particular aspect of the output format, you should always prefer 48000/stereo/f32 as the libopenmpt PCM format. - Please prefer 48000Hz unless the user explicitly demands something else. Practically all audio equipment and file formats use 48000Hz nowadays. - Practically all module formats are made for stereo output. Mono will not give you any measurable speed improvements and can trivially be obtained from the stereo output anyway. Quad is not expected by almost all modules and even if they do use surround effects, they expect the effects to be mixed to stereo. - Floating point output provides headroom instead of hard clipping if the module is louder than 0dBFs, will give you a better signal-to-noise ratio than int16 output, and avoid the need to apply an additional dithering to the output by libopenmpt. Unless your platform has no floating point unit at all, floating point will thus also be slightly faster. \section libopenmpt_freebasic_threads libopenmpt in multi-threaded environments - libopenmpt is thread-aware. - Individual libopenmpt objects are not thread-safe. - libopenmpt itself does not spawn any user-visible threads but may spawn threads for internal use. - You must ensure to only ever access a particular libopenmpt object from a single thread at a time. - Consecutive accesses can happen from different threads. - Different objects can be accessed concurrently from different threads. \section libopenmpt_freebasic_detailed Detailed documentation \ref libopenmpt_freebasic '/ Extern "C" '* API version of this header file Const OPENMPT_API_VERSION_MAJOR = 0 Const OPENMPT_API_VERSION_MINOR = 3 Const OPENMPT_API_VERSION_PATCH = 0 Const OPENMPT_API_VERSION = (OPENMPT_API_VERSION_MAJOR Shl 24) Or (OPENMPT_API_VERSION_MINOR Shl 16) Or (OPENMPT_API_VERSION_PATCH Shl 0) #Define OPENMPT_API_VERSION_STRING (OPENMPT_API_VERSION_MAJOR & "." & OPENMPT_API_VERSION_MINOR & "." & OPENMPT_API_VERSION_PATCH) /'* \brief Get the libopenmpt version number Returns the libopenmpt version number. \return The value represents (major Shl 24 + minor Shl 16 + patch Shl 0). \remarks libopenmpt < 0.3.0-pre used the following scheme: (major Shl 24 + minor Shl 16 + revision). \remarks Check the HiWord of the return value against OPENMPT_API_VERSION to ensure that the correct library version is loaded. '/ Declare Function openmpt_get_library_version() As ULong /'* \brief Get the core version number Return the OpenMPT core version number. \return The value represents (majormajor << 24 + major << 16 + minor << 8 + minorminor). '/ Declare Function openmpt_get_core_version() As ULong '* Return a verbose library version string from openmpt_get_string(). \deprecated Please use \code "library_version" \endcode directly. #Define OPENMPT_STRING_LIBRARY_VERSION "library_version" '* Return a verbose library features string from openmpt_get_string(). \deprecated Please use \code "library_features" \endcode directly. #Define OPENMPT_STRING_LIBRARY_FEATURES "library_features" '* Return a verbose OpenMPT core version string from openmpt_get_string(). \deprecated Please use \code "core_version" \endcode directly. #Define OPENMPT_STRING_CORE_VERSION "core_version" '* Return information about the current build (e.g. the build date or compiler used) from openmpt_get_string(). \deprecated Please use \code "build" \endcode directly. #Define OPENMPT_STRING_BUILD "build" '* Return all contributors from openmpt_get_string(). \deprecated Please use \code "credits" \endcode directly. #Define OPENMPT_STRING_CREDITS "credits" '* Return contact information about libopenmpt from openmpt_get_string(). \deprecated Please use \code "contact" \endcode directly. #Define OPENMPT_STRING_CONTACT "contact" '* Return the libopenmpt license from openmpt_get_string(). \deprecated Please use \code "license" \endcode directly. #Define OPENMPT_STRING_LICENSE "license" /'* \brief Free a string returned by libopenmpt Frees any string that got returned by libopenmpt. '/ Declare Sub openmpt_free_string(ByVal Str As Const ZString Ptr) /'* \brief Get library related metadata. \param key Key to query. Possible keys are: - "library_version": verbose library version string - "library_version_is_release": "1" if the version is an officially released version - "library_features": verbose library features string - "core_version": verbose OpenMPT core version string - "source_url": original source code URL - "source_date": original source code date - "source_revision": original source code revision - "source_is_modified": "1" if the original source has been modified - "source_has_mixed_revisions": "1" if the original source has been compiled from different various revision - "source_is_package": "1" if the original source has been obtained from a source pacakge instead of source code version control - "build": information about the current build (e.g. the build date or compiler used) - "build_compiler": information about the compiler used to build libopenmpt - "credits": all contributors - "contact": contact information about libopenmpt - "license": the libopenmpt license - "url": libopenmpt website URL - "support_forum_url": libopenmpt support and discussions forum URL - "bugtracker_url": libopenmpt bug and issue tracker URL \return A (possibly multi-line) string containing the queried information. If no information is available, the string is empty. \remarks Use openmpt_get_string to automatically handle the lifetime of the returned pointer. '/ Declare Function openmpt_get_string_ Alias "openmpt_get_string" (ByVal key As Const ZString Ptr) As Const ZString Ptr /'* \brief Get a list of supported file extensions \return The semicolon-separated list of extensions supported by this libopenmpt build. The extensions are returned lower-case without a leading dot. \remarks Use openmpt_get_supported_extensions to automatically handle the lifetime of the returned pointer. '/ Declare Function openmpt_get_supported_extensions() As Const ZString Ptr /'* \brief Query whether a file extension is supported \param extension file extension to query without a leading dot. The case is ignored. \return 1 if the extension is supported by libopenmpt, 0 otherwise. '/ Declare Function openmpt_is_extension_supported(ByVal extension As Const ZString Ptr) As Long '* Seek to the given offset relative to the beginning of the file. Const OPENMPT_STREAM_SEEK_SET = 0 '* Seek to the given offset relative to the current position in the file. Const OPENMPT_STREAM_SEEK_CUR = 1 '* Seek to the given offset relative to the end of the file. Const OPENMPT_STREAM_SEEK_END = 2 /'* \brief Read bytes from stream Read bytes data from stream to dst. \param stream Stream to read data from \param dst Target where to copy data. \param bytes Number of bytes to read. \return Number of bytes actually read and written to dst. \retval 0 End of stream or error. \remarks Short reads are allowed as long as they return at least 1 byte if EOF is not reached. '/ Type openmpt_stream_read_func As Function(ByVal stream As Any Ptr, ByVal dst As Any Ptr, ByVal bytes As UInteger) As UInteger /'* \brief Seek stream position Seek to stream position offset at whence. \param stream Stream to operate on. \param offset Offset to seek to. \param whence OPENMPT_STREAM_SEEK_SET, OPENMPT_STREAM_SEEK_CUR, OPENMPT_STREAM_SEEK_END. See C89 documentation. \return Returns 0 on success. \retval 0 Success. \retval -1 Failure. Position does not get updated. \remarks libopenmpt will not try to seek beyond the file size, thus it is not important whether you allow for virtual positioning after the file end, or return an error in that case. The position equal to the file size needs to be seekable to. '/ Type openmpt_stream_seek_func As Function(ByVal stream As Any Ptr, ByVal offset As LongInt, ByVal whence As Long) As Long /'* \brief Tell stream position Tell position of stream. \param stream Stream to operate on. \return Current position in stream. \retval -1 Failure. '/ Type openmpt_stream_tell_func As Function(ByVal stream As Any Ptr) As LongInt /'* \brief Stream callbacks Stream callbacks used by libopenmpt for stream operations. '/ Type openmpt_stream_callbacks /'* \brief Read callback. \sa openmpt_stream_read_func '/ read_func As openmpt_stream_read_func /'* \brief Seek callback. Seek callback can be NULL if seeking is not supported. \sa openmpt_stream_seek_func '/ seek_func As openmpt_stream_seek_func /'* \brief Tell callback. Tell callback can be NULL if seeking is not supported. \sa openmpt_stream_tell_func '/ tell_func As openmpt_stream_tell_func End Type /'* \brief Logging function \param message UTF-8 encoded log message. \param user User context that was passed to openmpt_module_create2(), openmpt_module_create_from_memory2() or openmpt_could_open_probability2(). '/ Type openmpt_log_func As Sub(ByVal message As Const ZString Ptr, ByVal user As Any Ptr) /'* \brief Default logging function Default logging function that logs anything to stderr. '/ Declare Sub openmpt_log_func_default(ByVal message As Const ZString Ptr, ByVal user As Any Ptr) /'* \brief Silent logging function Silent logging function that throws any log message away. '/ Declare Sub openmpt_log_func_silent(ByVal message As Const ZString Ptr, ByVal user As Any Ptr) '* No error. \since 0.3.0 Const OPENMPT_ERROR_OK = 0 '* Lowest value libopenmpt will use for any of its own error codes. \since 0.3.0 Const OPENMPT_ERROR_BASE = 256 '* Unknown internal error. \since 0.3.0 Const OPENMPT_ERROR_UNKNOWN = OPENMPT_ERROR_BASE + 1 '* Unknown internal C++ exception. \since 0.3.0 Const OPENMPT_ERROR_EXCEPTION = OPENMPT_ERROR_BASE + 11 '* Out of memory. \since 0.3.0 Const OPENMPT_ERROR_OUT_OF_MEMORY = OPENMPT_ERROR_BASE + 21 '* Runtime error. \since 0.3.0 Const OPENMPT_ERROR_RUNTIME = OPENMPT_ERROR_BASE + 30 '* Range error. \since 0.3.0 Const OPENMPT_ERROR_RANGE = OPENMPT_ERROR_BASE + 31 '* Arithmetic overflow. \since 0.3.0 Const OPENMPT_ERROR_OVERFLOW = OPENMPT_ERROR_BASE + 32 '* Arithmetic underflow. \since 0.3.0 Const OPENMPT_ERROR_UNDERFLOW = OPENMPT_ERROR_BASE + 33 '* Logic error. \since 0.3.0 Const OPENMPT_ERROR_LOGIC = OPENMPT_ERROR_BASE + 40 '* Value domain error. \since 0.3.0 Const OPENMPT_ERROR_DOMAIN = OPENMPT_ERROR_BASE + 41 '* Maximum supported size exceeded. \since 0.3.0 Const OPENMPT_ERROR_LENGTH = OPENMPT_ERROR_BASE + 42 '* Argument out of range. \since 0.3.0 Const OPENMPT_ERROR_OUT_OF_RANGE = OPENMPT_ERROR_BASE + 43 '* Invalid argument. \since 0.3.0 Const OPENMPT_ERROR_INVALID_ARGUMENT = OPENMPT_ERROR_BASE + 44 '* General libopenmpt error. \since 0.3.0 Const OPENMPT_ERROR_GENERAL = OPENMPT_ERROR_BASE + 101 '* openmpt_module Ptr is invalid. \since 0.3.0 Const OPENMPT_ERROR_INVALID_MODULE_POINTER = OPENMPT_ERROR_BASE + 102 '* NULL pointer argument. \since 0.3.0 Const OPENMPT_ERROR_ARGUMENT_NULL_POINTER = OPENMPT_ERROR_BASE + 103 /'* \brief Check whether the error is transient Checks whether an error code represents a transient error which may not occur again in a later try if for example memory has been freed up after an out-of-memory error. \param errorcode Error code. \retval 0 Error is not transient. \retval 1 Error is transient. \sa OPENMPT_ERROR_OUT_OF_MEMORY \since 0.3.0 '/ Declare Function openmpt_error_is_transient(ByVal errorcode As Long) As Long /'* \brief Convert error code to text Converts an error code into a text string describing the error. \param errorcode Error code. \return Allocated string describing the error. \retval NULL Not enough memory to allocate the string. \since 0.3.0 \remarks Use openmpt_error_string to automatically handle the lifetime of the returned pointer. '/ Declare Function openmpt_error_string_ Alias "openmpt_error_string" (ByVal errorcode As Long) As Const ZString Ptr '* Do not log or store the error. \since 0.3.0 Const OPENMPT_ERROR_FUNC_RESULT_NONE = 0 '* Log the error. \since 0.3.0 Const OPENMPT_ERROR_FUNC_RESULT_LOG = 1 '* Store the error. \since 0.3.0 Const OPENMPT_ERROR_FUNC_RESULT_STORE = 2 '* Log and store the error. \since 0.3.0 Const OPENMPT_ERROR_FUNC_RESULT_DEFAULT = OPENMPT_ERROR_FUNC_RESULT_LOG Or OPENMPT_ERROR_FUNC_RESULT_STORE /'* \brief Error function \param errorcode Error code. \param user User context that was passed to openmpt_module_create2(), openmpt_module_create_from_memory2() or openmpt_could_open_probability2(). \return Mask of OPENMPT_ERROR_FUNC_RESULT_LOG and OPENMPT_ERROR_FUNC_RESULT_STORE. \retval OPENMPT_ERROR_FUNC_RESULT_NONE Do not log or store the error. \retval OPENMPT_ERROR_FUNC_RESULT_LOG Log the error. \retval OPENMPT_ERROR_FUNC_RESULT_STORE Store the error. \retval OPENMPT_ERROR_FUNC_RESULT_DEFAULT Log and store the error. \sa OPENMPT_ERROR_FUNC_RESULT_NONE \sa OPENMPT_ERROR_FUNC_RESULT_LOG \sa OPENMPT_ERROR_FUNC_RESULT_STORE \sa OPENMPT_ERROR_FUNC_RESULT_DEFAULT \sa openmpt_error_func_default \sa openmpt_error_func_log \sa openmpt_error_func_store \sa openmpt_error_func_ignore \sa openmpt_error_func_errno \since 0.3.0 '/ Type openmpt_error_func As Function(ByVal errorcode As Long, ByVal user As Any Ptr) As Long /'* \brief Default error function Causes all errors to be logged and stored. \param errorcode Error code. \param user Ignored. \retval OPENMPT_ERROR_FUNC_RESULT_DEFAULT Always. \since 0.3.0 '/ Declare Function openmpt_error_func_default(ByVal errorcode As Long, ByVal User As Any Ptr) As Long /'* \brief Log error function Causes all errors to be logged. \param errorcode Error code. \param user Ignored. \retval OPENMPT_ERROR_FUNC_RESULT_LOG Always. \since 0.3.0 '/ Declare Function openmpt_error_func_log(ByVal errorcode As Long, ByVal user As Any Ptr) As Long /'* \brief Store error function Causes all errors to be stored. \param errorcode Error code. \param user Ignored. \retval OPENMPT_ERROR_FUNC_RESULT_STORE Always. \since 0.3.0 '/ Declare Function openmpt_error_func_store(ByVal errorcode As Long, ByVal user As Any Ptr) As Long /'* \brief Ignore error function Causes all errors to be neither logged nor stored. \param errorcode Error code. \param user Ignored. \retval OPENMPT_ERROR_FUNC_RESULT_NONE Always. \since 0.3.0 '/ Declare Function openmpt_error_func_ignore(ByVal errorcode As Long, ByVal user As Any Ptr) As Long /'* \brief Errno error function Causes all errors to be stored in the pointer passed in as user. \param errorcode Error code. \param user Pointer to an int as generated by openmpt_error_func_errno_userdata. \retval OPENMPT_ERROR_FUNC_RESULT_NONE user is not NULL. \retval OPENMPT_ERROR_FUNC_RESULT_DEFAULT user is NULL. \since 0.3.0 '/ Declare Function openmpt_error_func_errno(ByVal errorcode As Long, ByVal user As Any Ptr) As Long /'* \brief User pointer for openmpt_error_func_errno Provides a suitable user pointer argument for openmpt_error_func_errno. \param errorcode Pointer to an integer value to be used as output by openmpt_error_func_errno. \retval Cast(Any Ptr, errorcode). \since 0.3.0 '/ Declare Function openmpt_error_func_errno_userdata(ByVal errorcode As Long Ptr) As Any Ptr /'* \brief Roughly scan the input stream to find out whether libopenmpt might be able to open it \param stream_callbacks Input stream callback operations. \param stream Input stream to scan. \param effort Effort to make when validating stream. Effort 0.0 does not even look at stream at all and effort 1.0 completely loads the file from stream. A lower effort requires less data to be loaded but only gives a rough estimate answer. Use an effort of 0.25 to only verify the header data of the module file. \param logfunc Logging function where warning and errors are written. May be NULL. \param user Logging function user context. \return Probability between 0.0 and 1.0. \remarks openmpt_could_open_probability() can return any value between 0.0 and 1.0. Only 0.0 and 1.0 are definitive answers, all values in between are just estimates. In general, any return value >0.0 means that you should try loading the file, and any value below 1.0 means that loading may fail. If you want a threshold above which you can be reasonably sure that libopenmpt will be able to load the file, use >=0.5. If you see the need for a threshold below which you could reasonably outright reject a file, use <0.25 (Note: Such a threshold for rejecting on the lower end is not recommended, but may be required for better integration into some other framework's probe scoring.). \remarks openmpt_could_open_probability() expects the complete file data to be eventually available to it, even if it is asked to just parse the header. Verification will be unreliable (both false positives and false negatives), if you pretend that the file is just some few bytes of initial data threshold in size. In order to really just access the first bytes of a file, check in your callback functions whether data or seeking is requested beyond your initial data threshold, and in that case, return an error. openmpt_could_open_probability() will treat this as any other I/O error and return 0.0. You must not expect the correct result in this case. You instead must remember that it asked for more data than you currently want to provide to it and treat this situation as if openmpt_could_open_probability() returned 0.5. \sa openmpt_stream_callbacks \deprecated Please use openmpt_module_could_open_probability2(). \since 0.3.0 '/ Declare Function openmpt_could_open_probability(ByVal stream_callbacks As openmpt_stream_callbacks, ByVal stream As Any Ptr, ByVal effort As Double, ByVal logfunc As openmpt_log_func, ByVal user As Any Ptr) As Double /'* \brief Roughly scan the input stream to find out whether libopenmpt might be able to open it \param stream_callbacks Input stream callback operations. \param stream Input stream to scan. \param effort Effort to make when validating stream. Effort 0.0 does not even look at stream at all and effort 1.0 completely loads the file from stream. A lower effort requires less data to be loaded but only gives a rough estimate answer. Use an effort of 0.25 to only verify the header data of the module file. \param logfunc Logging function where warning and errors are written. May be NULL. \param loguser Logging function user context. \param errfunc Error function to define error behaviour. May be NULL. \param erruser Error function user context. \param errorcode Pointer to an integer where an error may get stored. May be NULL. \param error_message Pointer to a string pointer where an error message may get stored. May be NULL. \return Probability between 0.0 and 1.0. \remarks openmpt_probe_file_header() or openmpt_probe_file_header_without_filesize() provide a simpler and faster interface that fits almost all use cases better. It is recommended to use openmpt_probe_file_header() or openmpt_probe_file_header_without_filesize() instead of openmpt_could_open_probability(). \remarks openmpt_could_open_probability2() can return any value between 0.0 and 1.0. Only 0.0 and 1.0 are definitive answers, all values in between are just estimates. In general, any return value >0.0 means that you should try loading the file, and any value below 1.0 means that loading may fail. If you want a threshold above which you can be reasonably sure that libopenmpt will be able to load the file, use >=0.5. If you see the need for a threshold below which you could reasonably outright reject a file, use <0.25 (Note: Such a threshold for rejecting on the lower end is not recommended, but may be required for better integration into some other framework's probe scoring.). \remarks openmpt_could_open_probability2() expects the complete file data to be eventually available to it, even if it is asked to just parse the header. Verification will be unreliable (both false positives and false negatives), if you pretend that the file is just some few bytes of initial data threshold in size. In order to really just access the first bytes of a file, check in your callback functions whether data or seeking is requested beyond your initial data threshold, and in that case, return an error. openmpt_could_open_probability() will treat this as any other I/O error and return 0.0. You must not expect the correct result in this case. You instead must remember that it asked for more data than you currently want to provide to it and treat this situation as if openmpt_could_open_probability() returned 0.5. \sa openmpt_stream_callbacks \sa openmpt_probe_file_header \sa openmpt_probe_file_header_without_filesize \since 0.3.0 '/ Declare Function openmpt_could_open_probability2(ByVal stream_callbacks As openmpt_stream_callbacks, ByVal stream As Any Ptr, ByVal effort As Double, ByVal logfunc As openmpt_log_func, ByVal loguser As Any Ptr, ByVal errfunc As openmpt_error_func, ByVal erruser As Any Ptr, ByVal errorcode As Long Ptr, ByVal error_message As Const ZString Ptr Ptr) As Double /'* \brief Get recommended header size for successfull format probing \sa openmpt_probe_file_header() \sa openmpt_probe_file_header_without_filesize() \since 0.3.0 '/ Declare Function openmpt_probe_file_header_get_recommended_size() As UInteger '* Probe for module formats in openmpt_probe_file_header() or openmpt_probe_file_header_without_filesize(). \since 0.3.0 Const OPENMPT_PROBE_FILE_HEADER_FLAGS_MODULES = 1 '* Probe for module-specific container formats in openmpt_probe_file_header() or openmpt_probe_file_header_without_filesize(). \since 0.3.0 Const OPENMPT_PROBE_FILE_HEADER_FLAGS_CONTAINERS = 2 '* Probe for the default set of formats in openmpt_probe_file_header() or openmpt_probe_file_header_without_filesize(). \since 0.3.0 Const OPENMPT_PROBE_FILE_HEADER_FLAGS_DEFAULT = OPENMPT_PROBE_FILE_HEADER_FLAGS_MODULES or OPENMPT_PROBE_FILE_HEADER_FLAGS_CONTAINERS '* Probe for no formats in openmpt_probe_file_header() or openmpt_probe_file_header_without_filesize(). \since 0.3.0 Const OPENMPT_PROBE_FILE_HEADER_FLAGS_NONE = 0 '* Possible return values fo openmpt_probe_file_header() and openmpt_probe_file_header_without_filesize(). \since 0.3.0 Const OPENMPT_PROBE_FILE_HEADER_RESULT_SUCCESS = 1 '* Possible return values fo openmpt_probe_file_header() and openmpt_probe_file_header_without_filesize(). \since 0.3.0 Const OPENMPT_PROBE_FILE_HEADER_RESULT_FAILURE = 0 '* Possible return values fo openmpt_probe_file_header() and openmpt_probe_file_header_without_filesize(). \since 0.3.0 Const OPENMPT_PROBE_FILE_HEADER_RESULT_WANTMOREDATA = -1 '* Possible return values fo openmpt_probe_file_header() and openmpt_probe_file_header_without_filesize(). \since 0.3.0 Const OPENMPT_PROBE_FILE_HEADER_RESULT_ERROR = -255 /'* \brief Probe the provided bytes from the beginning of a file for supported file format headers to find out whether libopenmpt might be able to open it \param flags Ored mask of OPENMPT_PROBE_FILE_HEADER_FLAGS_MODULES and OPENMPT_PROBE_FILE_HEADER_FLAGS_CONTAINERS, or OPENMPT_PROBE_FILE_HEADER_FLAGS_DEFAULT. \param data Beginning of the file data. \param size Size of the beginning of the file data. \param filesize Full size of the file data on disk. \param logfunc Logging function where warning and errors are written. May be NULL. \param loguser Logging function user context. Used to pass any user-defined data associated with this module to the logging function. \param errfunc Error function to define error behaviour. May be NULL. \param erruser Error function user context. Used to pass any user-defined data associated with this module to the logging function. \param error Pointer to an integer where an error may get stored. May be NULL. \param error_message Pointer to a string pointer where an error message may get stored. May be NULL. \remarks It is recommended to provide openmpt_probe_file_header_get_recommended_size() bytes of data for data and size. If the file is smaller, only provide the filesize amount and set size and filesize to the file's size. \remarks openmpt_could_open_probability2() provides a more elaborate interface that might be required for special use cases. It is recommended to use openmpt_probe_file_header() though, if possible. \retval OPENMPT_PROBE_FILE_HEADER_RESULT_SUCCESS The file will most likely be supported by libopenmpt. \retval OPENMPT_PROBE_FILE_HEADER_RESULT_FAILURE The file is not supported by libopenmpt. \retval OPENMPT_PROBE_FILE_HEADER_RESULT_WANTMOREDATA An answer could not be determined with the amount of data provided. \retval OPENMPT_PROBE_FILE_HEADER_RESULT_ERROR An internal error occurred. \sa openmpt_probe_file_header_get_recommended_size() \sa openmpt_probe_file_header_without_filesize() \sa openmpt_probe_file_header_from_stream() \sa openmpt_could_open_probability2() \since 0.3.0 '/ Declare Function openmpt_probe_file_header(ByVal flags As ULongInt, ByVal Data As Const Any Ptr, ByVal size As UInteger, ByVal filesize As ULongInt, ByVal logfunc As openmpt_log_func, ByVal loguser As Any Ptr, ByVal errfunc As openmpt_error_func, ByVal erruser As Any Ptr, ByVal Error As Long Ptr, ByVal error_message As Const ZString Ptr Ptr) As Long /'* \brief Probe the provided bytes from the beginning of a file for supported file format headers to find out whether libopenmpt might be able to open it \param flags Ored mask of OPENMPT_PROBE_FILE_HEADER_FLAGS_MODULES and OPENMPT_PROBE_FILE_HEADER_FLAGS_CONTAINERS, or OPENMPT_PROBE_FILE_HEADER_FLAGS_DEFAULT. \param data Beginning of the file data. \param size Size of the beginning of the file data. \param logfunc Logging function where warning and errors are written. May be NULL. \param loguser Logging function user context. Used to pass any user-defined data associated with this module to the logging function. \param errfunc Error function to define error behaviour. May be NULL. \param erruser Error function user context. Used to pass any user-defined data associated with this module to the logging function. \param error Pointer to an integer where an error may get stored. May be NULL. \param error_message Pointer to a string pointer where an error message may get stored. May be NULL. \remarks It is recommended to use openmpt_probe_file_header() and provide the acutal file's size as a parameter if at all possible. libopenmpt can provide more accurate answers if the filesize is known. \remarks It is recommended to provide openmpt_probe_file_header_get_recommended_size() bytes of data for data and size. If the file is smaller, only provide the filesize amount and set size to the file's size. \remarks openmpt_could_open_probability2() provides a more elaborate interface that might be required for special use cases. It is recommended to use openmpt_probe_file_header() though, if possible. \retval OPENMPT_PROBE_FILE_HEADER_RESULT_SUCCESS The file will most likely be supported by libopenmpt. \retval OPENMPT_PROBE_FILE_HEADER_RESULT_FAILURE The file is not supported by libopenmpt. \retval OPENMPT_PROBE_FILE_HEADER_RESULT_WANTMOREDATA An answer could not be determined with the amount of data provided. \retval OPENMPT_PROBE_FILE_HEADER_RESULT_ERROR An internal error occurred. \sa openmpt_probe_file_header_get_recommended_size() \sa openmpt_probe_file_header() \sa openmpt_probe_file_header_from_stream() \sa openmpt_could_open_probability2() \since 0.3.0 '/ Declare Function openmpt_probe_file_header_without_filesize(ByVal flags As ULongInt, ByVal Data As Const Any Ptr, ByVal size As UInteger, ByVal logfunc As openmpt_log_func, ByVal loguser As Any Ptr, ByVal errfunc As openmpt_error_func, ByVal erruser As Any Ptr, ByVal Error As Long Ptr, ByVal error_message As Const ZString Ptr Ptr) As Long /'* \brief Probe the provided bytes from the beginning of a file for supported file format headers to find out whether libopenmpt might be able to open it \param flags Ored mask of OPENMPT_PROBE_FILE_HEADER_FLAGS_MODULES and OPENMPT_PROBE_FILE_HEADER_FLAGS_CONTAINERS, or OPENMPT_PROBE_FILE_HEADER_FLAGS_DEFAULT. \param stream_callbacks Input stream callback operations. \param stream Input stream to scan. \param logfunc Logging function where warning and errors are written. May be NULL. \param loguser Logging function user context. Used to pass any user-defined data associated with this module to the logging function. \param errfunc Error function to define error behaviour. May be NULL. \param erruser Error function user context. Used to pass any user-defined data associated with this module to the logging function. \param error Pointer to an integer where an error may get stored. May be NULL. \param error_message Pointer to a string pointer where an error message may get stored. May be NULL. \remarks The stream is left in an unspecified state when this function returns. \remarks It is recommended to provide openmpt_probe_file_header_get_recommended_size() bytes of data for data and size. If the file is smaller, only provide the filesize amount and set size and filesize to the file's size. \remarks openmpt_could_open_probability2() provides a more elaborate interface that might be required for special use cases. It is recommended to use openmpt_probe_file_header() though, if possible. \retval OPENMPT_PROBE_FILE_HEADER_RESULT_SUCCESS The file will most likely be supported by libopenmpt. \retval OPENMPT_PROBE_FILE_HEADER_RESULT_FAILURE The file is not supported by libopenmpt. \retval OPENMPT_PROBE_FILE_HEADER_RESULT_WANTMOREDATA An answer could not be determined with the amount of data provided. \retval OPENMPT_PROBE_FILE_HEADER_RESULT_ERROR An internal error occurred. \sa openmpt_probe_file_header_get_recommended_size() \sa openmpt_probe_file_header() \sa openmpt_probe_file_header_without_filesize() \sa openmpt_could_open_probability2() \since 0.3.0 '/ Declare Function openmpt_probe_file_header_from_stream(ByVal flags As ULongInt, ByVal stream_callbacks As openmpt_stream_callbacks, ByVal stream As Any Ptr, ByVal logfunc As openmpt_log_func, ByVal loguser As Any Ptr, ByVal errfunc As openmpt_error_func, ByVal erruser As Any Ptr, ByVal Error As Long Ptr, ByVal error_message As Const ZString Ptr Ptr) As Long '* \brief Opaque type representing a libopenmpt module Type openmpt_module opaque As Any Ptr End Type Type openmpt_module_initial_ctl ctl As Const ZString Ptr value As Const ZString Ptr End Type /'* \brief Construct an openmpt_module \param stream_callbacks Input stream callback operations. \param stream Input stream to load the module from. \param logfunc Logging function where warning and errors are written. The logging function may be called throughout the lifetime of openmpt_module. \param user User-defined data associated with this module. This value will be passed to the logging callback function (logfunc) \param ctls A map of initial ctl values. See openmpt_module_get_ctls(). \return A pointer to the constructed openmpt_module, or NULL on failure. \remarks The input data can be discarded after an openmpt_module has been constructed successfully. \sa openmpt_stream_callbacks '/ Declare Function openmpt_module_create(ByVal stream_callbacks As openmpt_stream_callbacks, ByVal stream As Any Ptr, ByVal logfunc As openmpt_log_func = 0, ByVal user As Any Ptr = 0, ByVal ctls As Const openmpt_module_initial_ctl Ptr = 0) As openmpt_module Ptr /'* \brief Construct an openmpt_module \param stream_callbacks Input stream callback operations. \param stream Input stream to load the module from. \param logfunc Logging function where warning and errors are written. The logging function may be called throughout the lifetime of openmpt_module. May be NULL. \param loguser User-defined data associated with this module. This value will be passed to the logging callback function (logfunc) \param errfunc Error function to define error behaviour. May be NULL. \param erruser Error function user context. \param errorcode Pointer to an integer where an error may get stored. May be NULL. \param error_message Pointer to a string pointer where an error message may get stored. May be NULL. \param ctls A map of initial ctl values. See openmpt_module_get_ctls(). \return A pointer to the constructed openmpt_module, or NULL on failure. \remarks The input data can be discarded after an openmpt_module has been constructed successfully. \sa openmpt_stream_callbacks \since 0.3.0 '/ Declare Function openmpt_module_create2(ByVal stream_callbacks As openmpt_stream_callbacks, ByVal stream As Any Ptr, ByVal logfunc As openmpt_log_func = 0, ByVal loguser As Any Ptr = 0, ByVal errfunc As openmpt_error_func = 0, ByVal erruser As Any Ptr = 0, ByVal errorcode As Long Ptr = 0, ByVal error_message As Const ZString Ptr Ptr = 0, ByVal ctls As Const openmpt_module_initial_ctl Ptr = 0) As openmpt_module Ptr /'* \brief Construct an openmpt_module \param filedata Data to load the module from. \param filesize Amount of data available. \param logfunc Logging function where warning and errors are written. The logging function may be called throughout the lifetime of openmpt_module. \param user User-defined data associated with this module. This value will be passed to the logging callback function (logfunc) \param ctls A map of initial ctl values. See openmpt_module_get_ctls(). \return A pointer to the constructed openmpt_module, or NULL on failure. \remarks The input data can be discarded after an openmpt_module has been constructed successfully. '/ Declare Function openmpt_module_create_from_memory(ByVal filedata As Const Any Ptr, ByVal filesize As UInteger, ByVal logfunc As openmpt_log_func = 0, ByVal user As Any Ptr = 0, ByVal ctls As Const openmpt_module_initial_ctl Ptr = 0) As openmpt_module Ptr /'* \brief Construct an openmpt_module \param filedata Data to load the module from. \param filesize Amount of data available. \param logfunc Logging function where warning and errors are written. The logging function may be called throughout the lifetime of openmpt_module. \param loguser User-defined data associated with this module. This value will be passed to the logging callback function (logfunc) \param errfunc Error function to define error behaviour. May be NULL. \param erruser Error function user context. \param errorcode Pointer to an integer where an error may get stored. May be NULL. \param error_message Pointer to a string pointer where an error message may get stored. May be NULL. \param ctls A map of initial ctl values. See openmpt_module_get_ctls(). \return A pointer to the constructed openmpt_module, or NULL on failure. \remarks The input data can be discarded after an openmpt_module has been constructed successfully. \since 0.3.0 '/ Declare Function openmpt_module_create_from_memory2(ByVal filedata As Const Any Ptr, ByVal filesize As UInteger, ByVal logfunc As openmpt_log_func, ByVal loguser As Any Ptr, ByVal errfunc As openmpt_error_func, ByVal erruser As Any Ptr, ByVal errorcode As Long Ptr, ByVal error_message As Const ZString Ptr Ptr, ByVal ctls As Const openmpt_module_initial_ctl Ptr) As openmpt_module Ptr /'* \brief Unload a previously created openmpt_module from memory. \param module The module to unload. '/ Declare Sub openmpt_module_destroy(ByVal module As openmpt_module Ptr) /'* \brief Set logging function. Set the logging function of an already constructed openmpt_module. \param module The module handle to work on. \param logfunc Logging function where warning and errors are written. The logging function may be called throughout the lifetime of openmpt_module. \param loguser User-defined data associated with this module. This value will be passed to the logging callback function (logfunc) \since 0.3.0 '/ Declare Sub openmpt_module_set_log_func(ByVal module As openmpt_module Ptr, ByVal logfunc As openmpt_log_func, ByVal loguser As Any Ptr) /'* \brief Set error function. Set the error function of an already constructed openmpt_module. \param module The module handle to work on. \param errfunc Error function to define error behaviour. May be NULL. \param erruser Error function user context. \since 0.3.0 '/ Declare Sub openmpt_module_set_error_func(ByVal module As openmpt_module Ptr, ByVal errfunc As openmpt_error_func, ByVal erruser As Any Ptr) /'* \brief Get last error. Return the error currently stored in an openmpt_module. The stored error is not cleared. \param module The module handle to work on. \return The error currently stored. \sa openmpt_module_error_get_last_message \sa openmpt_module_error_set_last \sa openmpt_module_error_clear \since 0.3.0 '/ Declare Function openmpt_module_error_get_last(ByVal module As openmpt_module Ptr) As Long /'* \brief Get last error message. Return the error message currently stored in an openmpt_module. The stored error is not cleared. \param module The module handle to work on. \return The error message currently stored. \sa openmpt_module_error_set_last \sa openmpt_module_error_clear \since 0.3.0 \remarks Use openmpt_module_error_get_last_message to automatically handle the lifetime of the returned pointer. '/ Declare Function openmpt_module_error_get_last_message_ Alias "openmpt_module_error_get_last_message" (ByVal module As openmpt_module Ptr) As Const ZString Ptr /'* \brief Set last error. Set the error currently stored in an openmpt_module. \param module The module handle to work on. \param errorcode Error to be stored. \sa openmpt_module_error_get_last \sa openmpt_module_error_clear \since 0.3.0 '/ Declare Sub openmpt_module_error_set_last(ByVal module As openmpt_module Ptr, ByVal errorcode As Long) /'* \brief Clear last error. Set the error currently stored in an openmpt_module to OPPENMPT_ERROR_OK. \param module The module handle to work on. \sa openmpt_module_error_get_last \sa openmpt_module_error_set_last \since 0.3.0 '/ Declare Sub openmpt_module_error_clear(ByVal module As openmpt_module Ptr) /'* \defgroup openmpt_module_render_param Render param indices \brief Parameter index to use with openmpt_module_get_render_param() and openmpt_module_set_render_param() @{ '/ /'* \brief Master Gain The related value represents a relative gain in milliBel.\n The default value is 0.\n The supported value range is unlimited.\n '/ Const OPENMPT_MODULE_RENDER_MASTERGAIN_MILLIBEL = 1 /'* \brief Stereo Separation The related value represents the stereo separation generated by the libopenmpt mixer in percent.\n The default value is 100.\n The supported value range is [0,200].\n '/ Const OPENMPT_MODULE_RENDER_STEREOSEPARATION_PERCENT = 2 /'* \brief Interpolation Filter The related value represents the interpolation filter length used by the libopenmpt mixer.\n The default value is 0, which indicates a recommended default value.\n The supported value range is [0,inf). Values greater than the implementation limit are clamped to the maximum supported value.\n Currently supported values: - 0: internal default - 1: no interpolation (zero order hold) - 2: linear interpolation - 4: cubic interpolation - 8: windowed sinc with 8 taps '/ Const OPENMPT_MODULE_RENDER_INTERPOLATIONFILTER_LENGTH = 3 /'* \brief Volume Ramping Strength The related value represents the amount of volume ramping done by the libopenmpt mixer.\n The default value is -1, which indicates a recommended default value.\n The meaningful value range is [-1..10].\n A value of 0 completely disables volume ramping. This might cause clicks in sound output.\n Higher values imply slower/softer volume ramps. '/ Const OPENMPT_MODULE_RENDER_VOLUMERAMPING_STRENGTH = 4 '* @} /'* \defgroup openmpt_module_command_index Pattern cell indices \brief Parameter index to use with openmpt_module_get_pattern_row_channel_command(), openmpt_module_format_pattern_row_channel_command() and openmpt_module_highlight_pattern_row_channel_command() @{ '/ Const OPENMPT_MODULE_COMMAND_NOTE = 0 Const OPENMPT_MODULE_COMMAND_INSTRUMENT = 1 Const OPENMPT_MODULE_COMMAND_VOLUMEEFFECT = 2 Const OPENMPT_MODULE_COMMAND_EFFECT = 3 Const OPENMPT_MODULE_COMMAND_VOLUME = 4 Const OPENMPT_MODULE_COMMAND_PARAMETER = 5 '* @} /'* \brief Select a sub-song from a multi-song module \param module The module handle to work on. \param subsong Index of the sub-song. -1 plays all sub-songs consecutively. \return 1 on success, 0 on failure. \sa openmpt_module_get_num_subsongs, openmpt_module_get_selected_subsong, openmpt_module_get_subsong_name \remarks Whether subsong -1 (all subsongs consecutively), subsong 0 or some other subsong is selected by default, is an implementation detail and subject to change. If you do not want to care about subsongs, it is recommended to just not call openmpt_module_select_subsong() at all. '/ Declare Function openmpt_module_select_subsong(ByVal module As openmpt_module Ptr, ByVal subsong As Long) As Long /'* \brief Get currently selected sub-song from a multi-song module \param module The module handle to work on. \return Currently selected sub-song. -1 for all subsongs consecutively, 0 or greater for the current sub-song index. \sa openmpt_module_get_num_subsongs, openmpt_module_select_subsong, openmpt_module_get_subsong_name \since 0.3.0 '/ Declare Function openmpt_module_get_selected_subsong(ByVal module As openmpt_module Ptr) As Long /'* \brief Set Repeat Count \param module The module handle to work on. \param repeat_count Repeat Count - -1: repeat forever - 0: play once, repeat zero times (the default) - n>0: play once and repeat n times after that \return 1 on success, 0 on failure. \sa openmpt_module_get_repeat_count '/ Declare Function openmpt_module_set_repeat_count(ByVal module As openmpt_module Ptr, ByVal repeat_count As Long) As Long /'* \brief Get Repeat Count \param module The module handle to work on. \return Repeat Count - -1: repeat forever - 0: play once, repeat zero times (the default) - n>0: play once and repeat n times after that \sa openmpt_module_set_repeat_count '/ Declare Function openmpt_module_get_repeat_count(ByVal module As openmpt_module Ptr) As Long /'* \brief approximate song duration \param module The module handle to work on. \return Approximate duration of current sub-song in seconds. '/ Declare Function openmpt_module_get_duration_seconds(ByVal module As openmpt_module Ptr) As Double /'* \brief Set approximate current song position \param module The module handle to work on. \param seconds Seconds to seek to. If seconds is out of range, the position gets set to song start or end respectively. \return Approximate new song position in seconds. \sa openmpt_module_get_position_seconds '/ Declare Function openmpt_module_set_position_seconds(ByVal module As openmpt_module Ptr, ByVal seconds As Double) As Double /'* \brief Get current song position \param module The module handle to work on. \return Current song position in seconds. \sa openmpt_module_set_position_seconds '/ Declare Function openmpt_module_get_position_seconds(ByVal module As openmpt_module Ptr) As Double /'* \brief Set approximate current song position If order or row are out of range, to position is not modified and the current position is returned. \param module The module handle to work on. \param order Pattern order number to seek to. \param row Pattern row number to seek to. \return Approximate new song position in seconds. \sa openmpt_module_set_position_seconds \sa openmpt_module_get_position_seconds '/ Declare Function openmpt_module_set_position_order_row(ByVal module As openmpt_module Ptr, ByVal order As Long, ByVal row As Long) As Double /'* \brief Get render parameter \param module The module handle to work on. \param param Parameter to query. See \ref openmpt_module_render_param \param value Pointer to the variable that receives the current value of the parameter. \return 1 on success, 0 on failure (invalid param or value is NULL). \sa OPENMPT_MODULE_RENDER_MASTERGAIN_MILLIBEL \sa OPENMPT_MODULE_RENDER_STEREOSEPARATION_PERCENT \sa OPENMPT_MODULE_RENDER_INTERPOLATIONFILTER_LENGTH \sa OPENMPT_MODULE_RENDER_VOLUMERAMPING_STRENGTH \sa openmpt_module_set_render_param '/ Declare Function openmpt_module_get_render_param(ByVal module As openmpt_module Ptr, ByVal param As Long, ByVal value As Long Ptr) As Long /'* \brief Set render parameter \param module The module handle to work on. \param param Parameter to set. See \ref openmpt_module_render_param \param value The value to set param to. \return 1 on success, 0 on failure (invalid param). \sa OPENMPT_MODULE_RENDER_MASTERGAIN_MILLIBEL \sa OPENMPT_MODULE_RENDER_STEREOSEPARATION_PERCENT \sa OPENMPT_MODULE_RENDER_INTERPOLATIONFILTER_LENGTH \sa OPENMPT_MODULE_RENDER_VOLUMERAMPING_STRENGTH \sa openmpt_module_get_render_param '/ Declare Function openmpt_module_set_render_param(ByVal module As openmpt_module Ptr, ByVal param As Long, ByVal value As Long) As Long '*@{ /'* \brief Render audio data \param module The module handle to work on. \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. \param count Number of audio frames to render per channel. \param mono Pointer to a buffer of at least count elements that receives the mono/center output. \return The number of frames actually rendered. \retval 0 The end of song has been reached. \remarks The output buffers are only written to up to the returned number of elements. \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. \remarks It is recommended to use the floating point API because of the greater dynamic range and no implied clipping. \sa \ref libopenmpt_freebasic_outputformat '/ Declare Function openmpt_module_read_mono(ByVal module As openmpt_module Ptr, ByVal samplerate As Long, ByVal count As UInteger, ByVal mono As Short Ptr) As UInteger /'* \brief Render audio data \param module The module handle to work on. \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. \param count Number of audio frames to render per channel. \param left Pointer to a buffer of at least count elements that receives the left output. \param right Pointer to a buffer of at least count elements that receives the right output. \return The number of frames actually rendered. \retval 0 The end of song has been reached. \remarks The output buffers are only written to up to the returned number of elements. \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. \remarks It is recommended to use the floating point API because of the greater dynamic range and no implied clipping. \sa \ref libopenmpt_freebasic_outputformat '/ Declare Function openmpt_module_read_stereo(ByVal module As openmpt_module Ptr, ByVal samplerate As Long, ByVal count As UInteger, ByVal Left As Short Ptr, ByVal Right As Short Ptr) As UInteger /'* \brief Render audio data \param module The module handle to work on. \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. \param count Number of audio frames to render per channel. \param left Pointer to a buffer of at least count elements that receives the left output. \param right Pointer to a buffer of at least count elements that receives the right output. \param rear_left Pointer to a buffer of at least count elements that receives the rear left output. \param rear_right Pointer to a buffer of at least count elements that receives the rear right output. \return The number of frames actually rendered. \retval 0 The end of song has been reached. \remarks The output buffers are only written to up to the returned number of elements. \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. \remarks It is recommended to use the floating point API because of the greater dynamic range and no implied clipping. \sa \ref libopenmpt_freebasic_outputformat '/ Declare Function openmpt_module_read_quad(ByVal module As openmpt_module Ptr, ByVal samplerate As Long, ByVal count As UInteger, ByVal Left As Short Ptr, ByVal Right As Short Ptr, ByVal rear_left As Short Ptr, ByVal rear_right As Short Ptr) As UInteger /'* \brief Render audio data \param module The module handle to work on. \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. \param count Number of audio frames to render per channel. \param mono Pointer to a buffer of at least count elements that receives the mono/center output. \return The number of frames actually rendered. \retval 0 The end of song has been reached. \remarks The output buffers are only written to up to the returned number of elements. \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. \remarks Floating point samples are in the [-1.0..1.0] nominal range. They are not clipped to that range though and thus might overshoot. \sa \ref libopenmpt_freebasic_outputformat '/ Declare Function openmpt_module_read_float_mono(ByVal module As openmpt_module Ptr, ByVal samplerate As Long, ByVal count As UInteger, ByVal mono As Single Ptr) As UInteger /'* \brief Render audio data \param module The module handle to work on. \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. \param count Number of audio frames to render per channel. \param left Pointer to a buffer of at least count elements that receives the left output. \param right Pointer to a buffer of at least count elements that receives the right output. \return The number of frames actually rendered. \retval 0 The end of song has been reached. \remarks The output buffers are only written to up to the returned number of elements. \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. \remarks Floating point samples are in the [-1.0..1.0] nominal range. They are not clipped to that range though and thus might overshoot. \sa \ref libopenmpt_freebasic_outputformat '/ Declare Function openmpt_module_read_float_stereo(ByVal module As openmpt_module Ptr, ByVal samplerate As Long, ByVal count As UInteger, ByVal Left As Single Ptr, ByVal Right As Single Ptr) As UInteger /'* \brief Render audio data \param module The module handle to work on. \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. \param count Number of audio frames to render per channel. \param left Pointer to a buffer of at least count elements that receives the left output. \param right Pointer to a buffer of at least count elements that receives the right output. \param rear_left Pointer to a buffer of at least count elements that receives the rear left output. \param rear_right Pointer to a buffer of at least count elements that receives the rear right output. \return The number of frames actually rendered. \retval 0 The end of song has been reached. \remarks The output buffers are only written to up to the returned number of elements. \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. \remarks Floating point samples are in the [-1.0..1.0] nominal range. They are not clipped to that range though and thus might overshoot. \sa \ref libopenmpt_freebasic_outputformat '/ Declare Function openmpt_module_read_float_quad(ByVal module As openmpt_module Ptr, ByVal samplerate As Long, ByVal count As UInteger, ByVal Left As Single Ptr, ByVal Right As Single Ptr, ByVal rear_left As Single Ptr, ByVal rear_right As Single Ptr) As UInteger /'* \brief Render audio data \param module The module handle to work on. \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. \param count Number of audio frames to render per channel. \param interleaved_stereo Pointer to a buffer of at least count*2 elements that receives the interleaved stereo output in the order (L,R). \return The number of frames actually rendered. \retval 0 The end of song has been reached. \remarks The output buffers are only written to up to the returned number of elements. \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. \remarks It is recommended to use the floating point API because of the greater dynamic range and no implied clipping. \sa \ref libopenmpt_freebasic_outputformat '/ Declare Function openmpt_module_read_interleaved_stereo(ByVal module As openmpt_module Ptr, ByVal samplerate As Long, ByVal count As UInteger, ByVal interleaved_stereo As Short Ptr) As UInteger /'* \brief Render audio data \param module The module handle to work on. \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. \param count Number of audio frames to render per channel. \param interleaved_quad Pointer to a buffer of at least count*4 elements that receives the interleaved suad surround output in the order (L,R,RL,RR). \return The number of frames actually rendered. \retval 0 The end of song has been reached. \remarks The output buffers are only written to up to the returned number of elements. \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. \remarks It is recommended to use the floating point API because of the greater dynamic range and no implied clipping. \sa \ref libopenmpt_freebasic_outputformat '/ Declare Function openmpt_module_read_interleaved_quad(ByVal module As openmpt_module Ptr, ByVal samplerate As Long, ByVal count As UInteger, ByVal interleaved_quad As Short Ptr) As UInteger /'* \brief Render audio data \param module The module handle to work on. \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. \param count Number of audio frames to render per channel. \param interleaved_stereo Pointer to a buffer of at least count*2 elements that receives the interleaved stereo output in the order (L,R). \return The number of frames actually rendered. \retval 0 The end of song has been reached. \remarks The output buffers are only written to up to the returned number of elements. \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. \remarks Floating point samples are in the [-1.0..1.0] nominal range. They are not clipped to that range though and thus might overshoot. \sa \ref libopenmpt_freebasic_outputformat '/ Declare Function openmpt_module_read_interleaved_float_stereo(ByVal module As openmpt_module Ptr, ByVal samplerate As Long, ByVal count As UInteger, ByVal interleaved_stereo As Single Ptr) As UInteger /'* \brief Render audio data \param module The module handle to work on. \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. \param count Number of audio frames to render per channel. \param interleaved_quad Pointer to a buffer of at least count*4 elements that receives the interleaved suad surround output in the order (L,R,RL,RR). \return The number of frames actually rendered. \retval 0 The end of song has been reached. \remarks The output buffers are only written to up to the returned number of elements. \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. \remarks Floating point samples are in the [-1.0..1.0] nominal range. They are not clipped to that range though and thus might overshoot. \sa \ref libopenmpt_freebasic_outputformat '/ Declare Function openmpt_module_read_interleaved_float_quad(ByVal module As openmpt_module Ptr, ByVal samplerate As Long, ByVal count As UInteger, ByVal interleaved_quad As Single Ptr) As UInteger '*@} /'* \brief Get the list of supported metadata item keys \param module The module handle to work on. \return Metadata item keys supported by openmpt_module_get_metadata, as a semicolon-separated list. \sa openmpt_module_get_metadata \remarks Use openmpt_module_get_metadata_keys to automatically handle the lifetime of the returned pointer. '/ Declare Function openmpt_module_get_metadata_keys_ Alias "openmpt_module_get_metadata_keys" (ByVal module As openmpt_module Ptr) As Const ZString Ptr /'* \brief Get a metadata item value \param module The module handle to work on. \param key Metadata item key to query. Use openmpt_module_get_metadata_keys to check for available keys. Possible keys are: - type: Module format extension (e.g. it) - type_long: Tracker name associated with the module format (e.g. Impulse Tracker) - container: Container format the module file is embedded in, if any (e.g. umx) - container_long: Full container name if the module is embedded in a container (e.g. Unreal Music) - tracker: Tracker that was (most likely) used to save the module file, if known - artist: Author of the module - title: Module title - date: Date the module was last saved, in ISO-8601 format. - message: Song message. If the song message is empty or the module format does not support song messages, a list of instrument and sample names is returned instead. - message_raw: Song message. If the song message is empty or the module format does not support song messages, an empty string is returned. - warnings: A list of warnings that were generated while loading the module. \return The associated value for key. \sa openmpt_module_get_metadata_keys \remarks Use openmpt_module_get_metadata to automatically handle the lifetime of the returned pointer. '/ Declare Function openmpt_module_get_metadata_ Alias "openmpt_module_get_metadata" (ByVal module As openmpt_module Ptr, ByVal key As Const ZString Ptr) As Const ZString Ptr /'* \brief Get the current speed \param module The module handle to work on. \return The current speed in ticks per row. '/ Declare Function openmpt_module_get_current_speed(ByVal module As openmpt_module Ptr) As Long /'* \brief Get the current tempo \param module The module handle to work on. \return The current tempo in tracker units. The exact meaning of this value depends on the tempo mode being used. '/ Declare Function openmpt_module_get_current_tempo(ByVal module As openmpt_module Ptr) As Long /'* \brief Get the current order \param module The module handle to work on. \return The current order at which the module is being played back. '/ Declare Function openmpt_module_get_current_order(ByVal module As openmpt_module Ptr) As Long /'* \brief Get the current pattern \param module The module handle to work on. \return The current pattern that is being played. '/ Declare Function openmpt_module_get_current_pattern(ByVal module As openmpt_module Ptr) As Long /'* \brief Get the current row \param module The module handle to work on. \return The current row at which the current pattern is being played. '/ Declare Function openmpt_module_get_current_row(ByVal module As openmpt_module Ptr) As Long /'* \brief Get the current amount of playing channels. \param module The module handle to work on. \return The amount of sample channels that are currently being rendered. '/ Declare Function openmpt_module_get_current_playing_channels(ByVal module As openmpt_module Ptr) As Long /'* \brief Get an approximate indication of the channel volume. \param module The module handle to work on. \param channel The channel whose volume should be retrieved. \return The approximate channel volume. \remarks The returned value is solely based on the note velocity and does not take the actual waveform of the playing sample into account. '/ Declare Function openmpt_module_get_current_channel_vu_mono(ByVal module As openmpt_module Ptr, ByVal channel As Long) As Single /'* \brief Get an approximate indication of the channel volume on the front-left speaker. \param module The module handle to work on. \param channel The channel whose volume should be retrieved. \return The approximate channel volume. \remarks The returned value is solely based on the note velocity and does not take the actual waveform of the playing sample into account. '/ Declare Function openmpt_module_get_current_channel_vu_left(ByVal module As openmpt_module Ptr, ByVal channel As Long) As Single /'* \brief Get an approximate indication of the channel volume on the front-right speaker. \param module The module handle to work on. \param channel The channel whose volume should be retrieved. \return The approximate channel volume. \remarks The returned value is solely based on the note velocity and does not take the actual waveform of the playing sample into account. '/ Declare Function openmpt_module_get_current_channel_vu_right(ByVal module As openmpt_module Ptr, ByVal channel As Long) As Single /'* \brief Get an approximate indication of the channel volume on the rear-left speaker. \param module The module handle to work on. \param channel The channel whose volume should be retrieved. \return The approximate channel volume. \remarks The returned value is solely based on the note velocity and does not take the actual waveform of the playing sample into account. '/ Declare Function openmpt_module_get_current_channel_vu_rear_left(ByVal module As openmpt_module Ptr, ByVal channel As Long) As Single /'* \brief Get an approximate indication of the channel volume on the rear-right speaker. \param module The module handle to work on. \param channel The channel whose volume should be retrieved. \return The approximate channel volume. \remarks The returned value is solely based on the note velocity and does not take the actual waveform of the playing sample into account. '/ Declare Function openmpt_module_get_current_channel_vu_rear_right(ByVal module As openmpt_module Ptr, ByVal channel As Long) As Single /'* \brief Get the number of sub-songs \param module The module handle to work on. \return The number of sub-songs in the module. This includes any "hidden" songs (songs that share the same sequence, but start at different order indices) and "normal" sub-songs or "sequences" (if the format supports them). \sa openmpt_module_get_subsong_name, openmpt_module_select_subsong, openmpt_module_get_selected_subsong '/ Declare Function openmpt_module_get_num_subsongs(ByVal module As openmpt_module Ptr) As Long /'* \brief Get the number of pattern channels \param module The module handle to work on. \return The number of pattern channels in the module. Not all channels do necessarily contain data. \remarks The number of pattern channels is completely independent of the number of output channels. libopenmpt can render modules in mono, stereo or quad surround, but the choice of which of the three modes to use must not be made based on the return value of this function, which may be any positive integer amount. Only use this function for informational purposes. '/ Declare Function openmpt_module_get_num_channels(ByVal module As openmpt_module Ptr) As Long /'* \brief Get the number of orders \param module The module handle to work on. \return The number of orders in the current sequence of the module. '/ Declare Function openmpt_module_get_num_orders(ByVal module As openmpt_module Ptr) As Long /'* \brief Get the number of patterns \param module The module handle to work on. \return The number of distinct patterns in the module. '/ Declare Function openmpt_module_get_num_patterns(ByVal module As openmpt_module Ptr) As Long /'* \brief Get the number of instruments \param module The module handle to work on. \return The number of instrument slots in the module. Instruments are a layer on top of samples, and are not supported by all module formats. '/ Declare Function openmpt_module_get_num_instruments(ByVal module As openmpt_module Ptr) As Long /'* \brief Get the number of samples \param module The module handle to work on. \return The number of sample slots in the module. '/ Declare Function openmpt_module_get_num_samples(ByVal module As openmpt_module Ptr) As Long /'* \brief Get a sub-song name \param module The module handle to work on. \param index The sub-song whose name should be retrieved \return The sub-song name. \sa openmpt_module_get_num_subsongs, openmpt_module_select_subsong, openmpt_module_get_selected_subsong \remarks Use openmpt_module_get_subsong_name to automatically handle the lifetime of the returned pointer. '/ Declare Function openmpt_module_get_subsong_name_ Alias "openmpt_module_get_subsong_name" (ByVal module As openmpt_module Ptr, ByVal index As Long) As Const ZString Ptr /'* \brief Get a channel name \param module The module handle to work on. \param index The channel whose name should be retrieved \return The channel name. \sa openmpt_module_get_num_channels \remarks Use openmpt_module_get_channel_name to automatically handle the lifetime of the returned pointer. '/ Declare Function openmpt_module_get_channel_name_ Alias "openmpt_module_get_channel_name" (ByVal module As openmpt_module Ptr, ByVal index As Long) As Const ZString Ptr /'* \brief Get an order name \param module The module handle to work on. \param index The order whose name should be retrieved \return The order name. \sa openmpt_module_get_num_orders \remarks Use openmpt_module_get_order_name to automatically handle the lifetime of the returned pointer. '/ Declare Function openmpt_module_get_order_name_ Alias "openmpt_module_get_order_name" (ByVal module As openmpt_module Ptr, ByVal index As Long) As Const ZString Ptr /'* \brief Get a pattern name \param module The module handle to work on. \param index The pattern whose name should be retrieved \return The pattern name. \sa openmpt_module_get_num_patterns \remarks Use openmpt_module_get_pattern_name to automatically handle the lifetime of the returned pointer. '/ Declare Function openmpt_module_get_pattern_name_ Alias "openmpt_module_get_pattern_name" (ByVal module As openmpt_module Ptr, ByVal index As Long) As Const ZString Ptr /'* \brief Get an instrument name \param module The module handle to work on. \param index The instrument whose name should be retrieved \return The instrument name. \sa openmpt_module_get_num_instruments \remarks Use openmpt_module_get_instrument_name to automatically handle the lifetime of the returned pointer. '/ Declare Function openmpt_module_get_instrument_name_ Alias "openmpt_module_get_instrument_name" (ByVal module As openmpt_module Ptr, ByVal index As Long) As Const ZString Ptr /'* \brief Get a sample name \param module The module handle to work on. \param index The sample whose name should be retrieved \return The sample name. \sa openmpt_module_get_num_samples \remarks Use openmpt_module_get_sample_name to automatically handle the lifetime of the returned pointer. '/ Declare Function openmpt_module_get_sample_name_ Alias "openmpt_module_get_sample_name" (ByVal module As openmpt_module Ptr, ByVal index As Long) As Const ZString Ptr /'* \brief Get pattern at order position \param module The module handle to work on. \param order The order item whose pattern index should be retrieved. \return The pattern index found at the given order position of the current sequence. '/ Declare Function openmpt_module_get_order_pattern(ByVal module As openmpt_module Ptr, ByVal order As Long) As Long /'* \brief Get the number of rows in a pattern \param module The module handle to work on. \param pattern The pattern whose row count should be retrieved. \return The number of rows in the given pattern. If the pattern does not exist, 0 is returned. '/ Declare Function openmpt_module_get_pattern_num_rows(ByVal module As openmpt_module Ptr, ByVal pattern As Long) As Long /'* \brief Get raw pattern content \param module The module handle to work on. \param pattern The pattern whose data should be retrieved. \param row The row from which the data should be retrieved. \param channel The channel from which the data should be retrieved. \param command The cell index at which the data should be retrieved. See \ref openmpt_module_command_index \return The internal, raw pattern data at the given pattern position. '/ Declare Function openmpt_module_get_pattern_row_channel_command_(ByVal module As openmpt_module Ptr, ByVal pattern As Long, ByVal row As Long, ByVal channel As Long, ByVal command_ As Long) As UByte /'* \brief Get formatted (human-readable) pattern content \param module The module handle to work on. \param pattern The pattern whose data should be retrieved. \param row The row from which the data should be retrieved. \param channel The channel from which the data should be retrieved. \param command The cell index at which the data should be retrieved. \return The formatted pattern data at the given pattern position. See \ref openmpt_module_command_index \sa openmpt_module_highlight_pattern_row_channel_command \remarks Use openmpt_module_format_pattern_row_channel_command to automatically handle the lifetime of the returned pointer. '/ Declare Function openmpt_module_format_pattern_row_channel_command_ Alias "openmpt_module_format_pattern_row_channel_command" (ByVal module As openmpt_module Ptr, ByVal pattern As Long, ByVal row As Long, ByVal channel As Long, ByVal command_ As Long) As Const ZString Ptr /'* \brief Get highlighting information for formatted pattern content \param module The module handle to work on. \param pattern The pattern whose data should be retrieved. \param row The row from which the data should be retrieved. \param channel The channel from which the data should be retrieved. \param command The cell index at which the data should be retrieved. See \ref openmpt_module_command_index \return The highlighting string for the formatted pattern data as retrieved by openmpt_module_get_pattern_row_channel_command at the given pattern position. \remarks The returned string will map each character position of the string returned by openmpt_module_get_pattern_row_channel_command to a highlighting instruction. Possible highlighting characters are: - " " : empty/space - "." : empty/dot - "n" : generic note - "m" : special note - "i" : generic instrument - "u" : generic volume column effect - "v" : generic volume column parameter - "e" : generic effect column effect - "f" : generic effect column parameter \sa openmpt_module_get_pattern_row_channel_command \remarks Use openmpt_module_highlight_pattern_row_channel_command to automatically handle the lifetime of the returned pointer. '/ Declare Function openmpt_module_highlight_pattern_row_channel_command_ Alias "openmpt_module_highlight_pattern_row_channel_command" (ByVal module As openmpt_module Ptr, ByVal pattern As Long, ByVal row As Long, ByVal channel As Long, ByVal command_ As Long) As Const ZString Ptr /'* \brief Get formatted (human-readable) pattern content \param module The module handle to work on. \param pattern The pattern whose data should be retrieved. \param row The row from which the data should be retrieved. \param channel The channel from which the data should be retrieved. \param width The maximum number of characters the string should contain. 0 means no limit. \param pad If true, the string will be resized to the exact length provided in the width parameter. \return The formatted pattern data at the given pattern position. \sa openmpt_module_highlight_pattern_row_channel \remarks Use openmpt_module_format_pattern_row_channel to automatically handle the lifetime of the returned pointer. '/ Declare Function openmpt_module_format_pattern_row_channel_ Alias "openmpt_module_format_pattern_row_channel" (ByVal module As openmpt_module Ptr, ByVal pattern As Long, ByVal row As Long, ByVal channel As Long, ByVal width_ As UInteger, ByVal pad As Long) As Const ZString Ptr /'* \brief Get highlighting information for formatted pattern content \param module The module handle to work on. \param pattern The pattern whose data should be retrieved. \param row The row from which the data should be retrieved. \param channel The channel from which the data should be retrieved. \param width The maximum number of characters the string should contain. 0 means no limit. \param pad If true, the string will be resized to the exact length provided in the width parameter. \return The highlighting string for the formatted pattern data as retrieved by openmpt_module_format_pattern_row_channel at the given pattern position. \sa openmpt_module_format_pattern_row_channel \remarks Use openmpt_module_highlight_pattern_row_channel to automatically handle the lifetime of the returned pointer. '/ Declare Function openmpt_module_highlight_pattern_row_channel_ Alias "openmpt_module_highlight_pattern_row_channel" (ByVal module As openmpt_module Ptr, ByVal pattern As Long, ByVal row As Long, ByVal channel As Long, ByVal width_ As UInteger, ByVal pad As Long) As Const ZString Ptr /'* \brief Retrieve supported ctl keys \param module The module handle to work on. \return A semicolon-separated list containing all supported ctl keys. \remarks Currently supported ctl values are: - load.skip_samples: Set to "1" to avoid loading samples into memory - load.skip_patterns: Set to "1" to avoid loading patterns into memory - load.skip_plugins: Set to "1" to avoid loading plugins - load.skip_subsongs_init: Set to "1" to avoid pre-initializing sub-songs. Skipping results in faster module loading but slower seeking. - seek.sync_samples: Set to "1" to sync sample playback when using openmpt_module_set_position_seconds or openmpt_module_set_position_order_row. - subsong: The current subsong. Setting it has identical semantics as openmpt_module_select_subsong(), getting it returns the currently selected subsong. - play.tempo_factor: Set a floating point tempo factor. "1.0" is the default tempo. - play.pitch_factor: Set a floating point pitch factor. "1.0" is the default pitch. - render.resampler.emulate_amiga: Set to "1" to enable the Amiga resampler for Amiga modules. This emulates the sound characteristics of the Paula chip and overrides the selected interpolation filter. Non-Amiga module formats are not affected by this setting. - dither: Set the dither algorithm that is used for the 16 bit versions of openmpt_module_read. Supported values are: - 0: No dithering. - 1: Default mode. Chosen by OpenMPT code, might change. - 2: Rectangular, 0.5 bit depth, no noise shaping (original ModPlug Tracker). - 3: Rectangular, 1 bit depth, simple 1st order noise shaping \remarks Use openmpt_module_get_ctls to automatically handle the lifetime of the returned pointer. '/ Declare Function openmpt_module_get_ctls_ Alias "openmpt_module_get_ctls" (ByVal module As openmpt_module Ptr) As Const ZString Ptr /'* \brief Get current ctl value \param module The module handle to work on. \param ctl The ctl key whose value should be retrieved. \return The associated ctl value, or NULL on failure. \sa openmpt_module_get_ctls \remarks Use openmpt_module_ctl_get to automatically handle the lifetime of the returned pointer. '/ Declare Function openmpt_module_ctl_get_ Alias "openmpt_module_ctl_get" (ByVal module As openmpt_module Ptr, ByVal ctl As Const ZString Ptr) As Const ZString Ptr /'* \brief Set ctl value \param module The module handle to work on. \param ctl The ctl key whose value should be set. \param value The value that should be set. \return 1 if successful, 0 in case the value is not sensible (e.g. negative tempo factor) or the ctl is not recognized. \sa openmpt_module_get_ctls '/ Declare Function openmpt_module_ctl_set(ByVal module As openmpt_module Ptr, ByVal ctl As Const ZString Ptr, ByVal value As Const ZString Ptr) As Long '* Callbacks for CRT FILE* handling Function openmpt_stream_read_func(ByVal stream As Any Ptr, ByVal dst As Any Ptr, ByVal bytes As UInteger) As UInteger Dim retval As UInteger = 0 Var f = Cast( FILE Ptr, stream ) If ( f = 0 ) Then Return 0 retval = fread( dst, 1, bytes, f ) If ( retval <= 0 ) Then Return 0 Return retval End Function '* Callbacks for CRT FILE* handling Function openmpt_stream_seek_func(ByVal stream As Any Ptr, ByVal offset As LongInt, ByVal whence As Long) As Long Var f = Cast( FILE Ptr, stream ) If ( f = 0 ) Then Return -1 Dim fwhence As Long Select Case whence Case OPENMPT_STREAM_SEEK_SET fwhence = SEEK_SET Case OPENMPT_STREAM_SEEK_CUR fwhence = SEEK_CUR Case OPENMPT_STREAM_SEEK_END fwhence = SEEK_END Case Else Return -1 End Select Return IIf(fseek( f, offset, fwhence ) <> 0, -1, 0) End Function '* Callbacks for CRT FILE* handling Function openmpt_stream_tell_func(ByVal stream As Any Ptr) As LongInt Dim retval As LongInt = 0 Var f = Cast( FILE Ptr, stream ) If ( f = 0 ) Then Return -1 EndIf retval = ftell( f ) If ( retval < 0 ) Then Return -1 Return retval End Function End Extern '* Retrieve the set of stream callbacks for CRT FILE* Function openmpt_stream_get_file_callbacks() As openmpt_stream_callbacks Static callbacks As openmpt_stream_callbacks = (@openmpt_stream_read_func, @openmpt_stream_seek_func, @openmpt_stream_tell_func) Return callbacks End Function /'* \brief Construct an openmpt_module \param file The FreeBASIC file handle to load from. \param logfunc Logging function where warning and errors are written. May be NULL. \param loguser Logging function user context. Used to pass any user-defined data associated with this module to the logging function. \param errfunc Error function to define error behaviour. May be NULL. \param erruser Error function user context. Used to pass any user-defined data associated with this module to the error function. \param errorcode Pointer to an integer where an error may get stored. May be NULL. \param error_message Pointer to a string pointer where an error message may get stored. May be NULL. \param ctls A map of initial ctl values. See openmpt_module_get_ctls(). \return A pointer to the constructed openmpt_module, or NULL on failure. \remarks The file handle can be closed after an openmpt_module has been constructed successfully. \sa openmpt_module_create2 '/ Function openmpt_module_create_from_fbhandle2(_ ByVal file As Integer,_ ByVal logfunc As openmpt_log_func = 0,_ ByVal loguser As Any Ptr = 0,_ ByVal errfunc As openmpt_error_func = 0,_ ByVal erruser As Any Ptr = 0,_ ByVal errorcode As Long Ptr = 0,_ ByVal error_message As Const ZString Ptr Ptr = 0,_ ByVal ctls As Const openmpt_module_initial_ctl Ptr = 0) As openmpt_module Ptr Return openmpt_module_create2(openmpt_stream_get_file_callbacks(), Cast(FILE Ptr, FileAttr(file, fbFileAttrHandle)), logfunc, loguser, errfunc, erruser, errorcode, error_message, ctls) End Function /'* \brief Construct an openmpt_module \param file The FreeBASIC file handle to load from. \param logfunc Logging function where warning and errors are written. May be NULL. \param loguser Logging function user context. Used to pass any user-defined data associated with this module to the logging function. \param ctls A map of initial ctl values. See openmpt_module_get_ctls(). \return A pointer to the constructed openmpt_module, or NULL on failure. \remarks The file handle can be closed after an openmpt_module has been constructed successfully. \deprecated Please use openmpt_module_create_from_fbhandle2(). \sa openmpt_module_create2 '/ Function openmpt_module_create_from_fbhandle(_ ByVal file As Integer,_ ByVal logfunc As openmpt_log_func = 0,_ ByVal loguser As Any Ptr = 0,_ ByVal ctls As Const openmpt_module_initial_ctl Ptr = 0) As openmpt_module Ptr Return openmpt_module_create_from_fbhandle2(file, logfunc, loguser, 0, 0, 0, 0, ctls) End Function /'* \brief Construct an openmpt_module \param filename The file to load from. \param logfunc Logging function where warning and errors are written. May be NULL. \param loguser Logging function user context. Used to pass any user-defined data associated with this module to the logging function. \param errfunc Error function to define error behaviour. May be NULL. \param erruser Error function user context. Used to pass any user-defined data associated with this module to the error function. \param errorcode Pointer to an integer where an error may get stored. May be NULL. \param error_message Pointer to a string pointer where an error message may get stored. May be NULL. \param ctls A map of initial ctl values. See openmpt_module_get_ctls(). \return A pointer to the constructed openmpt_module, or NULL on failure. \sa openmpt_module_create2 '/ Function openmpt_module_create_from_filename2(_ ByRef filename As String,_ ByVal logfunc As openmpt_log_func = 0,_ ByVal loguser As Any Ptr = 0,_ ByVal errfunc As openmpt_error_func = 0,_ ByVal erruser As Any Ptr = 0,_ ByVal errorcode As Long Ptr = 0,_ ByVal error_message As Const ZString Ptr Ptr = 0,_ ByVal ctls As Const openmpt_module_initial_ctl Ptr = 0) As openmpt_module Ptr Var file = fopen(filename, "rb") Var retval = CPtr(openmpt_module Ptr, 0) If(file <> 0) Then retval = openmpt_module_create2(openmpt_stream_get_file_callbacks(), file, logfunc, loguser, errfunc, erruser, errorcode, error_message, ctls) fclose(file) EndIf Return retval End Function /'* \brief Construct an openmpt_module \param filename The file to load from. \param logfunc Logging function where warning and errors are written. May be NULL. \param loguser Logging function user context. Used to pass any user-defined data associated with this module to the logging function. \param ctls A map of initial ctl values. See openmpt_module_get_ctls(). \return A pointer to the constructed openmpt_module, or NULL on failure. \deprecated Please use openmpt_module_create_from_filename2(). \sa openmpt_module_create2 '/ Function openmpt_module_create_from_filename(_ ByRef filename As String,_ ByVal logfunc As openmpt_log_func = 0,_ ByVal loguser As Any Ptr = 0,_ ByVal ctls As Const openmpt_module_initial_ctl Ptr = 0) As openmpt_module Ptr Return openmpt_module_create_from_filename2(filename, logfunc, loguser, 0, 0, 0, 0, ctls) End Function '* String handling for wrapping and freeing ZStrings returned by libopenmpt Function openmpt_get_zstring(sz As Const ZString Ptr) As String If(sz = 0) Then Return "" Dim As String s = *sz openmpt_free_string(sz) Return s End Function '* \sa openmpt_get_string_ Function openmpt_get_string(ByVal key As Const ZString Ptr) As String Return openmpt_get_zstring(openmpt_get_string_(key)) End Function '* \sa openmpt_error_string_ Function openmpt_error_string (ByVal errorcode As Long) As String Return openmpt_get_zstring(openmpt_error_string_(errorcode)) End Function '* \sa openmpt_module_error_get_last_message_ Function openmpt_module_error_get_last_message (ByVal module As openmpt_module Ptr) As String Return openmpt_get_zstring(openmpt_module_error_get_last_message_(module)) End Function '* \sa openmpt_module_get_metadata_keys_ Function openmpt_module_get_metadata_keys(ByVal module As openmpt_module Ptr) As String Return openmpt_get_zstring(openmpt_module_get_metadata_keys_(module)) End Function '* \sa openmpt_module_get_metadata_ Function openmpt_module_get_metadata(ByVal module As openmpt_module Ptr, ByVal key As Const ZString Ptr) As String Return openmpt_get_zstring(openmpt_module_get_metadata_(module, key)) End Function '* \sa openmpt_module_get_subsong_name_ Function openmpt_module_get_subsong_name(ByVal module As openmpt_module Ptr, ByVal index As Long) As String Return openmpt_get_zstring(openmpt_module_get_subsong_name_(module, index)) End Function '* \sa openmpt_module_get_channel_name_ Function openmpt_module_get_channel_name(ByVal module As openmpt_module Ptr, ByVal index As Long) As String Return openmpt_get_zstring(openmpt_module_get_channel_name_(module, index)) End Function '* \sa openmpt_module_get_order_name_ Function openmpt_module_get_order_name(ByVal module As openmpt_module Ptr, ByVal index As Long) As String Return openmpt_get_zstring(openmpt_module_get_order_name_(module, index)) End Function '* \sa openmpt_module_get_pattern_name_ Function openmpt_module_get_pattern_name(ByVal module As openmpt_module Ptr, ByVal index As Long) As String Return openmpt_get_zstring(openmpt_module_get_pattern_name_(module, index)) End Function '* \sa openmpt_module_get_instrument_name_ Function openmpt_module_get_instrument_name(ByVal module As openmpt_module Ptr, ByVal index As Long) As String Return openmpt_get_zstring(openmpt_module_get_instrument_name_(module, index)) End Function '* \sa openmpt_module_get_sample_name_ Function openmpt_module_get_sample_name(ByVal module As openmpt_module Ptr, ByVal index As Long) As String Return openmpt_get_zstring(openmpt_module_get_sample_name_(module, index)) End Function '* \sa openmpt_module_format_pattern_row_channel_command_ Function openmpt_module_format_pattern_row_channel_command(ByVal module As openmpt_module Ptr, ByVal pattern As Long, ByVal row As Long, ByVal channel As Long, ByVal command_ As Long) As String Return openmpt_get_zstring(openmpt_module_format_pattern_row_channel_command_(module, pattern, row, channel, command_)) End Function '* \sa openmpt_module_highlight_pattern_row_channel_command_ Function openmpt_module_highlight_pattern_row_channel_command(ByVal module As openmpt_module Ptr, ByVal pattern As Long, ByVal row As Long, ByVal channel As Long, ByVal command_ As Long) As String Return openmpt_get_zstring(openmpt_module_highlight_pattern_row_channel_command_(module, pattern, row, channel, command_)) End Function '* \sa openmpt_module_format_pattern_row_channel_ Function openmpt_module_format_pattern_row_channel(ByVal module As openmpt_module Ptr, ByVal pattern As Long, ByVal row As Long, ByVal channel As Long, ByVal width_ As UInteger, ByVal pad As Long) As String Return openmpt_get_zstring(openmpt_module_format_pattern_row_channel_(module, pattern, row, channel, width_, pad)) End Function '* \sa openmpt_module_highlight_pattern_row_channel_ Function openmpt_module_highlight_pattern_row_channel(ByVal module As openmpt_module Ptr, ByVal pattern As Long, ByVal row As Long, ByVal channel As Long, ByVal width_ As UInteger, ByVal pad As Long) As String Return openmpt_get_zstring(openmpt_module_highlight_pattern_row_channel_(module, pattern, row, channel, width_, pad)) End Function '* \sa openmpt_module_get_ctls_ Function openmpt_module_get_ctls(ByVal module As openmpt_module Ptr) As String Return openmpt_get_zstring(openmpt_module_get_ctls_(module)) End Function '* \sa openmpt_module_ctl_get_ Function openmpt_module_ctl_get(ByVal module As openmpt_module Ptr, ByVal ctl As Const ZString Ptr) As String Return openmpt_get_zstring(openmpt_module_ctl_get_(module, ctl)) End Function libopenmpt-0.3.6+release.autotools/libopenmpt/libopenmpt_internal.h0000644000372100037210000000217312762337652022665 00000000000000/* * libopenmpt_internal.h * --------------------- * Purpose: libopenmpt internal interface configuration, overruling the public interface configuration (only used and needed when building libopenmpt) * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #ifndef LIBOPENMPT_INTERNAL_H #define LIBOPENMPT_INTERNAL_H #include "libopenmpt_config.h" #if defined(NO_LIBOPENMPT_C) #undef LIBOPENMPT_API #define LIBOPENMPT_API LIBOPENMPT_API_HELPER_LOCAL #endif #if defined(NO_LIBOPENMPT_CXX) #undef LIBOPENMPT_CXX_API #define LIBOPENMPT_CXX_API LIBOPENMPT_API_HELPER_LOCAL #endif #ifdef __cplusplus #if defined(LIBOPENMPT_BUILD_DLL) || defined(LIBOPENMPT_USE_DLL) #if defined(_MSC_VER) && !defined(_DLL) /* #pragma message( "libopenmpt C++ interface is disabled if libopenmpt is built as a DLL and the runtime is statically linked. This is not supported by microsoft and cannot possibly work. Ever." ) */ #undef LIBOPENMPT_CXX_API #define LIBOPENMPT_CXX_API LIBOPENMPT_API_HELPER_LOCAL #endif #endif #endif #endif /* LIBOPENMPT_INTERNAL_H */ libopenmpt-0.3.6+release.autotools/libopenmpt/libopenmpt_stream_callbacks_fd.h0000644000372100037210000000330112723024551024772 00000000000000/* * libopenmpt_stream_callbacks_fd.h * -------------------------------- * Purpose: libopenmpt public c interface * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #ifndef LIBOPENMPT_STREAM_CALLBACKS_FD_H #define LIBOPENMPT_STREAM_CALLBACKS_FD_H #include "libopenmpt.h" #ifdef _MSC_VER #include #endif #include #include #include #include #ifndef _MSC_VER #include #endif #ifdef __cplusplus extern "C" { #endif /* This stuff has to be in a header file because of possibly different MSVC CRTs which cause problems for fd crossing CRT boundaries. */ static size_t openmpt_stream_fd_read_func( void * stream, void * dst, size_t bytes ) { int fd = 0; #if defined(_MSC_VER) size_t retval = 0; int to_read = 0; int ret_read = 0; #else ssize_t retval = 0; #endif fd = (int)(uintptr_t)stream; if ( fd < 0 ) { return 0; } #if defined(_MSC_VER) retval = 0; while ( bytes > 0 ) { to_read = 0; if ( bytes < (size_t)INT_MAX ) { to_read = (int)bytes; } else { to_read = INT_MAX; } ret_read = _read( fd, dst, to_read ); if ( ret_read <= 0 ) { return retval; } bytes -= ret_read; retval += ret_read; } #else retval = read( fd, dst, bytes ); #endif if ( retval <= 0 ) { return 0; } return retval; } static openmpt_stream_callbacks openmpt_stream_get_fd_callbacks(void) { openmpt_stream_callbacks retval; memset( &retval, 0, sizeof( openmpt_stream_callbacks ) ); retval.read = openmpt_stream_fd_read_func; return retval; } #ifdef __cplusplus } #endif #endif /* LIBOPENMPT_STREAM_CALLBACKS_FD_H */ libopenmpt-0.3.6+release.autotools/libopenmpt/libopenmpt_modplug.c0000644000372100037210000005161313051352114022474 00000000000000/* * libopenmpt_modplug.c * -------------------- * Purpose: libopenmpt emulation of the libmodplug interface * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #ifndef NO_LIBMODPLUG #ifdef LIBOPENMPT_BUILD_DLL #undef LIBOPENMPT_BUILD_DLL #endif #ifdef _MSC_VER #ifndef _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS #endif #endif /* _MSC_VER */ #include "libopenmpt.h" #include #include #include #include #include #include /* define to emulate 0.8.7 API/ABI instead of 0.8.8 API/ABI */ /* #define LIBOPENMPT_MODPLUG_0_8_7 */ #ifdef _MSC_VER /* msvc errors when seeing dllexport declarations after prototypes have been declared in modplug.h */ #define LIBOPENMPT_MODPLUG_API #else /* !_MSC_VER */ #define LIBOPENMPT_MODPLUG_API LIBOPENMPT_API_HELPER_EXPORT #endif /* _MSC_VER */ #ifdef LIBOPENMPT_MODPLUG_0_8_7 #include "libmodplug/modplug_0.8.7.h" #else #include "libmodplug/modplug.h" #endif /* from libmodplug/sndfile.h */ /* header is not c clean */ #define MIXING_ATTENUATION 4 #define MOD_TYPE_NONE 0x0 #define MOD_TYPE_MOD 0x1 #define MOD_TYPE_S3M 0x2 #define MOD_TYPE_XM 0x4 #define MOD_TYPE_MED 0x8 #define MOD_TYPE_MTM 0x10 #define MOD_TYPE_IT 0x20 #define MOD_TYPE_669 0x40 #define MOD_TYPE_ULT 0x80 #define MOD_TYPE_STM 0x100 #define MOD_TYPE_FAR 0x200 #define MOD_TYPE_WAV 0x400 #define MOD_TYPE_AMF 0x800 #define MOD_TYPE_AMS 0x1000 #define MOD_TYPE_DSM 0x2000 #define MOD_TYPE_MDL 0x4000 #define MOD_TYPE_OKT 0x8000 #define MOD_TYPE_MID 0x10000 #define MOD_TYPE_DMF 0x20000 #define MOD_TYPE_PTM 0x40000 #define MOD_TYPE_DBM 0x80000 #define MOD_TYPE_MT2 0x100000 #define MOD_TYPE_AMF0 0x200000 #define MOD_TYPE_PSM 0x400000 #define MOD_TYPE_J2B 0x800000 #define MOD_TYPE_ABC 0x1000000 #define MOD_TYPE_PAT 0x2000000 #define MOD_TYPE_UMX 0x80000000 // Fake type #define BUFFER_COUNT 1024 struct _ModPlugFile { openmpt_module* mod; signed short* buf; signed int* mixerbuf; char* name; char* message; ModPlug_Settings settings; ModPlugMixerProc mixerproc; ModPlugNote** patterns; }; static ModPlug_Settings globalsettings = { MODPLUG_ENABLE_OVERSAMPLING|MODPLUG_ENABLE_NOISE_REDUCTION, 2, 16, 44100, MODPLUG_RESAMPLE_LINEAR, #ifndef LIBOPENMPT_MODPLUG_0_8_7 128, 256, #endif 0, 0, 0, 0, 0, 0, 0 }; static int32_t modplugresamplingmode_to_filterlength(int mode) { if(mode<0){ return 1; } switch(mode){ case MODPLUG_RESAMPLE_NEAREST: return 1; break; case MODPLUG_RESAMPLE_LINEAR: return 2; break; case MODPLUG_RESAMPLE_SPLINE: return 4; break; case MODPLUG_RESAMPLE_FIR: return 8; break; } return 8; } LIBOPENMPT_MODPLUG_API ModPlugFile* ModPlug_Load(const void* data, int size) { ModPlugFile* file = malloc(sizeof(ModPlugFile)); const char* name = NULL; const char* message = NULL; if(!file) return NULL; memset(file,0,sizeof(ModPlugFile)); memcpy(&file->settings,&globalsettings,sizeof(ModPlug_Settings)); file->mod = openmpt_module_create_from_memory2(data,size,NULL,NULL,NULL,NULL,NULL,NULL,NULL); if(!file->mod){ free(file); return NULL; } file->buf = malloc(BUFFER_COUNT*sizeof(signed short)*4); if(!file->buf){ openmpt_module_destroy(file->mod); free(file); return NULL; } openmpt_module_set_repeat_count(file->mod,file->settings.mLoopCount); name = openmpt_module_get_metadata(file->mod,"title"); if(name){ file->name = malloc(strlen(name)+1); if(file->name){ strcpy(file->name,name); } openmpt_free_string(name); name = NULL; }else{ file->name = malloc(strlen("")+1); if(file->name){ strcpy(file->name,""); } } message = openmpt_module_get_metadata(file->mod,"message"); if(message){ file->message = malloc(strlen(message)+1); if(file->message){ strcpy(file->message,message); } openmpt_free_string(message); message = NULL; }else{ file->message = malloc(strlen("")+1); if(file->message){ strcpy(file->message,""); } } #ifndef LIBOPENMPT_MODPLUG_0_8_7 openmpt_module_set_render_param(file->mod,OPENMPT_MODULE_RENDER_STEREOSEPARATION_PERCENT,file->settings.mStereoSeparation*100/128); #endif openmpt_module_set_render_param(file->mod,OPENMPT_MODULE_RENDER_INTERPOLATIONFILTER_LENGTH,modplugresamplingmode_to_filterlength(file->settings.mResamplingMode)); return file; } LIBOPENMPT_MODPLUG_API void ModPlug_Unload(ModPlugFile* file) { int p; if(!file) return; if(file->patterns){ for(p=0;pmod);p++){ if(file->patterns[p]){ free(file->patterns[p]); file->patterns[p] = NULL; } } free(file->patterns); file->patterns = NULL; } if(file->mixerbuf){ free(file->mixerbuf); file->mixerbuf = NULL; } openmpt_module_destroy(file->mod); file->mod = NULL; free(file->name); file->name = NULL; free(file->message); file->message = NULL; free(file->buf); file->buf = NULL; free(file); } LIBOPENMPT_MODPLUG_API int ModPlug_Read(ModPlugFile* file, void* buffer, int size) { int framesize; int framecount; int frames; int rendered; int frame; int channel; int totalrendered; signed short* in; signed int* mixbuf; unsigned char* buf8; signed short* buf16; signed int* buf32; if(!file) return 0; framesize = file->settings.mBits/8*file->settings.mChannels; framecount = size/framesize; buf8 = buffer; buf16 = buffer; buf32 = buffer; totalrendered = 0; while(framecount>0){ frames = framecount; if(frames>BUFFER_COUNT){ frames = BUFFER_COUNT; } if(file->settings.mChannels==1){ rendered = (int)openmpt_module_read_mono(file->mod,file->settings.mFrequency,frames,&file->buf[frames*0]); }else if(file->settings.mChannels==2){ rendered = (int)openmpt_module_read_stereo(file->mod,file->settings.mFrequency,frames,&file->buf[frames*0],&file->buf[frames*1]); }else if(file->settings.mChannels==4){ rendered = (int)openmpt_module_read_quad(file->mod,file->settings.mFrequency,frames,&file->buf[frames*0],&file->buf[frames*1],&file->buf[frames*2],&file->buf[frames*3]); }else{ return 0; } in = file->buf; if(file->mixerproc&&file->mixerbuf){ mixbuf=file->mixerbuf; for(frame=0;framesettings.mChannels;channel++){ *mixbuf = in[frames*channel+frame]<<(32-16-1-MIXING_ATTENUATION); mixbuf++; } } file->mixerproc(file->mixerbuf,file->settings.mChannels*frames,file->settings.mChannels); mixbuf=file->mixerbuf; for(frame=0;framesettings.mChannels;channel++){ in[frames*channel+frame] = *mixbuf>>(32-16-1-MIXING_ATTENUATION); mixbuf++; } } } if(file->settings.mBits==8){ for(frame=0;framesettings.mChannels;channel++){ *buf8 = in[frames*channel+frame]/256+0x80; buf8++; } } }else if(file->settings.mBits==16){ for(frame=0;framesettings.mChannels;channel++){ *buf16 = in[frames*channel+frame]; buf16++; } } }else if(file->settings.mBits==32){ for(frame=0;framesettings.mChannels;channel++){ *buf32 = in[frames*channel+frame] << (32-16-1-MIXING_ATTENUATION); buf32++; } } }else{ return 0; } totalrendered += rendered; framecount -= frames; if(!rendered) break; } memset(((char*)buffer)+totalrendered*framesize,0,size-totalrendered*framesize); return totalrendered*framesize; } LIBOPENMPT_MODPLUG_API const char* ModPlug_GetName(ModPlugFile* file) { if(!file) return NULL; return file->name; } LIBOPENMPT_MODPLUG_API int ModPlug_GetLength(ModPlugFile* file) { if(!file) return 0; return (int)(openmpt_module_get_duration_seconds(file->mod)*1000.0); } LIBOPENMPT_MODPLUG_API void ModPlug_Seek(ModPlugFile* file, int millisecond) { if(!file) return; openmpt_module_set_position_seconds(file->mod,(double)millisecond*0.001); } LIBOPENMPT_MODPLUG_API void ModPlug_GetSettings(ModPlug_Settings* settings) { if(!settings) return; memcpy(settings,&globalsettings,sizeof(ModPlug_Settings)); } LIBOPENMPT_MODPLUG_API void ModPlug_SetSettings(const ModPlug_Settings* settings) { if(!settings) return; memcpy(&globalsettings,settings,sizeof(ModPlug_Settings)); } LIBOPENMPT_MODPLUG_API unsigned int ModPlug_GetMasterVolume(ModPlugFile* file) { int32_t val; if(!file) return 0; val = 0; if(!openmpt_module_get_render_param(file->mod,OPENMPT_MODULE_RENDER_MASTERGAIN_MILLIBEL,&val)) return 128; return (unsigned int)(128.0*pow(10.0,val*0.0005)); } LIBOPENMPT_MODPLUG_API void ModPlug_SetMasterVolume(ModPlugFile* file,unsigned int cvol) { if(!file) return; openmpt_module_set_render_param(file->mod,OPENMPT_MODULE_RENDER_MASTERGAIN_MILLIBEL,(int32_t)(2000.0*log10(cvol/128.0))); } LIBOPENMPT_MODPLUG_API int ModPlug_GetCurrentSpeed(ModPlugFile* file) { if(!file) return 0; return openmpt_module_get_current_speed(file->mod); } LIBOPENMPT_MODPLUG_API int ModPlug_GetCurrentTempo(ModPlugFile* file) { if(!file) return 0; return openmpt_module_get_current_tempo(file->mod); } LIBOPENMPT_MODPLUG_API int ModPlug_GetCurrentOrder(ModPlugFile* file) { if(!file) return 0; return openmpt_module_get_current_order(file->mod); } LIBOPENMPT_MODPLUG_API int ModPlug_GetCurrentPattern(ModPlugFile* file) { if(!file) return 0; return openmpt_module_get_current_pattern(file->mod); } LIBOPENMPT_MODPLUG_API int ModPlug_GetCurrentRow(ModPlugFile* file) { if(!file) return 0; return openmpt_module_get_current_row(file->mod); } LIBOPENMPT_MODPLUG_API int ModPlug_GetPlayingChannels(ModPlugFile* file) { if(!file) return 0; return openmpt_module_get_current_playing_channels(file->mod); } LIBOPENMPT_MODPLUG_API void ModPlug_SeekOrder(ModPlugFile* file,int order) { if(!file) return; openmpt_module_set_position_order_row(file->mod,order,0); } LIBOPENMPT_MODPLUG_API int ModPlug_GetModuleType(ModPlugFile* file) { const char* type; int retval; if(!file) return 0; type = openmpt_module_get_metadata(file->mod,"type"); retval = MOD_TYPE_NONE; if(!type){ return retval; } if(!strcmp(type,"mod")){ retval = MOD_TYPE_MOD; }else if(!strcmp(type,"s3m")){ retval = MOD_TYPE_S3M; }else if(!strcmp(type,"xm")){ retval = MOD_TYPE_XM; }else if(!strcmp(type,"med")){ retval = MOD_TYPE_MED; }else if(!strcmp(type,"mtm")){ retval = MOD_TYPE_MTM; }else if(!strcmp(type,"it")){ retval = MOD_TYPE_IT; }else if(!strcmp(type,"669")){ retval = MOD_TYPE_669; }else if(!strcmp(type,"ult")){ retval = MOD_TYPE_ULT; }else if(!strcmp(type,"stm")){ retval = MOD_TYPE_STM; }else if(!strcmp(type,"far")){ retval = MOD_TYPE_FAR; }else if(!strcmp(type,"s3m")){ retval = MOD_TYPE_WAV; }else if(!strcmp(type,"amf")){ retval = MOD_TYPE_AMF; }else if(!strcmp(type,"ams")){ retval = MOD_TYPE_AMS; }else if(!strcmp(type,"dsm")){ retval = MOD_TYPE_DSM; }else if(!strcmp(type,"mdl")){ retval = MOD_TYPE_MDL; }else if(!strcmp(type,"okt")){ retval = MOD_TYPE_OKT; }else if(!strcmp(type,"mid")){ retval = MOD_TYPE_MID; }else if(!strcmp(type,"dmf")){ retval = MOD_TYPE_DMF; }else if(!strcmp(type,"ptm")){ retval = MOD_TYPE_PTM; }else if(!strcmp(type,"dbm")){ retval = MOD_TYPE_DBM; }else if(!strcmp(type,"mt2")){ retval = MOD_TYPE_MT2; }else if(!strcmp(type,"amf0")){ retval = MOD_TYPE_AMF0; }else if(!strcmp(type,"psm")){ retval = MOD_TYPE_PSM; }else if(!strcmp(type,"j2b")){ retval = MOD_TYPE_J2B; }else if(!strcmp(type,"abc")){ retval = MOD_TYPE_ABC; }else if(!strcmp(type,"pat")){ retval = MOD_TYPE_PAT; }else if(!strcmp(type,"umx")){ retval = MOD_TYPE_UMX; }else{ retval = MOD_TYPE_IT; /* fallback, most complex type */ } openmpt_free_string(type); return retval; } LIBOPENMPT_MODPLUG_API char* ModPlug_GetMessage(ModPlugFile* file) { if(!file) return NULL; return file->message; } LIBOPENMPT_MODPLUG_API unsigned int ModPlug_NumInstruments(ModPlugFile* file) { if(!file) return 0; return openmpt_module_get_num_instruments(file->mod); } LIBOPENMPT_MODPLUG_API unsigned int ModPlug_NumSamples(ModPlugFile* file) { if(!file) return 0; return openmpt_module_get_num_samples(file->mod); } LIBOPENMPT_MODPLUG_API unsigned int ModPlug_NumPatterns(ModPlugFile* file) { if(!file) return 0; return openmpt_module_get_num_patterns(file->mod); } LIBOPENMPT_MODPLUG_API unsigned int ModPlug_NumChannels(ModPlugFile* file) { if(!file) return 0; return openmpt_module_get_num_channels(file->mod); } LIBOPENMPT_MODPLUG_API unsigned int ModPlug_SampleName(ModPlugFile* file, unsigned int qual, char* buff) { const char* str; unsigned int retval; size_t tmpretval; if(!file) return 0; str = openmpt_module_get_sample_name(file->mod,qual-1); if(!str){ if(buff){ *buff = '\0'; } return 0; } tmpretval = strlen(str); if(tmpretval>=INT_MAX){ tmpretval = INT_MAX-1; } retval = (int)tmpretval; if(buff){ strncpy(buff,str,retval+1); } openmpt_free_string(str); return retval; } LIBOPENMPT_MODPLUG_API unsigned int ModPlug_InstrumentName(ModPlugFile* file, unsigned int qual, char* buff) { const char* str; unsigned int retval; size_t tmpretval; if(!file) return 0; str = openmpt_module_get_instrument_name(file->mod,qual-1); if(!str){ if(buff){ *buff = '\0'; } return 0; } tmpretval = strlen(str); if(tmpretval>=INT_MAX){ tmpretval = INT_MAX-1; } retval = (int)tmpretval; if(buff){ strncpy(buff,str,retval+1); } openmpt_free_string(str); return retval; } LIBOPENMPT_MODPLUG_API ModPlugNote* ModPlug_GetPattern(ModPlugFile* file, int pattern, unsigned int* numrows) { int c; int r; int numr; int numc; ModPlugNote note; if(!file) return NULL; if(numrows){ *numrows = openmpt_module_get_pattern_num_rows(file->mod,pattern); } if(pattern<0||pattern>=openmpt_module_get_num_patterns(file->mod)){ return NULL; } if(!file->patterns){ file->patterns = malloc(sizeof(ModPlugNote*)*openmpt_module_get_pattern_num_rows(file->mod,pattern)); if(!file->patterns) return NULL; memset(file->patterns,0,sizeof(ModPlugNote*)*openmpt_module_get_pattern_num_rows(file->mod,pattern)); } if(!file->patterns[pattern]){ file->patterns[pattern] = malloc(sizeof(ModPlugNote)*openmpt_module_get_pattern_num_rows(file->mod,pattern)*openmpt_module_get_num_channels(file->mod)); if(!file->patterns[pattern]) return NULL; memset(file->patterns[pattern],0,sizeof(ModPlugNote)*openmpt_module_get_pattern_num_rows(file->mod,pattern)*openmpt_module_get_num_channels(file->mod)); } numr = openmpt_module_get_pattern_num_rows(file->mod,pattern); numc = openmpt_module_get_num_channels(file->mod); for(r=0;rmod,pattern,r,c,OPENMPT_MODULE_COMMAND_NOTE); note.Instrument = openmpt_module_get_pattern_row_channel_command(file->mod,pattern,r,c,OPENMPT_MODULE_COMMAND_INSTRUMENT); note.VolumeEffect = openmpt_module_get_pattern_row_channel_command(file->mod,pattern,r,c,OPENMPT_MODULE_COMMAND_VOLUMEEFFECT); note.Effect = openmpt_module_get_pattern_row_channel_command(file->mod,pattern,r,c,OPENMPT_MODULE_COMMAND_EFFECT); note.Volume = openmpt_module_get_pattern_row_channel_command(file->mod,pattern,r,c,OPENMPT_MODULE_COMMAND_VOLUME); note.Parameter = openmpt_module_get_pattern_row_channel_command(file->mod,pattern,r,c,OPENMPT_MODULE_COMMAND_PARAMETER); memcpy(&file->patterns[pattern][r*numc+c],¬e,sizeof(ModPlugNote)); } } return file->patterns[pattern]; } LIBOPENMPT_MODPLUG_API void ModPlug_InitMixerCallback(ModPlugFile* file,ModPlugMixerProc proc) { if(!file) return; if(!file->mixerbuf){ file->mixerbuf = malloc(BUFFER_COUNT*sizeof(signed int)*4); } file->mixerproc = proc; } LIBOPENMPT_MODPLUG_API void ModPlug_UnloadMixerCallback(ModPlugFile* file) { if(!file) return; file->mixerproc = NULL; if(file->mixerbuf){ free(file->mixerbuf); file->mixerbuf = NULL; } } LIBOPENMPT_MODPLUG_API char ModPlug_ExportS3M(ModPlugFile* file, const char* filepath) { (void)file; /* not implemented */ fprintf(stderr,"libopenmpt-modplug: error: ModPlug_ExportS3M(%s) not implemented.\n",filepath); return 0; } LIBOPENMPT_MODPLUG_API char ModPlug_ExportXM(ModPlugFile* file, const char* filepath) { (void)file; /* not implemented */ fprintf(stderr,"libopenmpt-modplug: error: ModPlug_ExportXM(%s) not implemented.\n",filepath); return 0; } LIBOPENMPT_MODPLUG_API char ModPlug_ExportMOD(ModPlugFile* file, const char* filepath) { (void)file; /* not implemented */ fprintf(stderr,"libopenmpt-modplug: error: ModPlug_ExportMOD(%s) not implemented.\n",filepath); return 0; } LIBOPENMPT_MODPLUG_API char ModPlug_ExportIT(ModPlugFile* file, const char* filepath) { (void)file; /* not implemented */ fprintf(stderr,"libopenmpt-modplug: error: ModPlug_ExportIT(%s) not implemented.\n",filepath); return 0; } #ifdef _MSC_VER #ifdef _M_IX86 #pragma comment(linker, "/EXPORT:ModPlug_Load=_ModPlug_Load") #pragma comment(linker, "/EXPORT:ModPlug_Unload=_ModPlug_Unload") #pragma comment(linker, "/EXPORT:ModPlug_Read=_ModPlug_Read") #pragma comment(linker, "/EXPORT:ModPlug_GetName=_ModPlug_GetName") #pragma comment(linker, "/EXPORT:ModPlug_GetLength=_ModPlug_GetLength") #pragma comment(linker, "/EXPORT:ModPlug_Seek=_ModPlug_Seek") #pragma comment(linker, "/EXPORT:ModPlug_GetSettings=_ModPlug_GetSettings") #pragma comment(linker, "/EXPORT:ModPlug_SetSettings=_ModPlug_SetSettings") #pragma comment(linker, "/EXPORT:ModPlug_GetMasterVolume=_ModPlug_GetMasterVolume") #pragma comment(linker, "/EXPORT:ModPlug_SetMasterVolume=_ModPlug_SetMasterVolume") #pragma comment(linker, "/EXPORT:ModPlug_GetCurrentSpeed=_ModPlug_GetCurrentSpeed") #pragma comment(linker, "/EXPORT:ModPlug_GetCurrentTempo=_ModPlug_GetCurrentTempo") #pragma comment(linker, "/EXPORT:ModPlug_GetCurrentOrder=_ModPlug_GetCurrentOrder") #pragma comment(linker, "/EXPORT:ModPlug_GetCurrentPattern=_ModPlug_GetCurrentPattern") #pragma comment(linker, "/EXPORT:ModPlug_GetCurrentRow=_ModPlug_GetCurrentRow") #pragma comment(linker, "/EXPORT:ModPlug_GetPlayingChannels=_ModPlug_GetPlayingChannels") #pragma comment(linker, "/EXPORT:ModPlug_SeekOrder=_ModPlug_SeekOrder") #pragma comment(linker, "/EXPORT:ModPlug_GetModuleType=_ModPlug_GetModuleType") #pragma comment(linker, "/EXPORT:ModPlug_GetMessage=_ModPlug_GetMessage") #pragma comment(linker, "/EXPORT:ModPlug_NumInstruments=_ModPlug_NumInstruments") #pragma comment(linker, "/EXPORT:ModPlug_NumSamples=_ModPlug_NumSamples") #pragma comment(linker, "/EXPORT:ModPlug_NumPatterns=_ModPlug_NumPatterns") #pragma comment(linker, "/EXPORT:ModPlug_NumChannels=_ModPlug_NumChannels") #pragma comment(linker, "/EXPORT:ModPlug_SampleName=_ModPlug_SampleName") #pragma comment(linker, "/EXPORT:ModPlug_InstrumentName=_ModPlug_InstrumentName") #pragma comment(linker, "/EXPORT:ModPlug_GetPattern=_ModPlug_GetPattern") #pragma comment(linker, "/EXPORT:ModPlug_InitMixerCallback=_ModPlug_InitMixerCallback") #pragma comment(linker, "/EXPORT:ModPlug_UnloadMixerCallback=_ModPlug_UnloadMixerCallback") #pragma comment(linker, "/EXPORT:ModPlug_ExportS3M=_ModPlug_ExportS3M") #pragma comment(linker, "/EXPORT:ModPlug_ExportXM=_ModPlug_ExportXM") #pragma comment(linker, "/EXPORT:ModPlug_ExportMOD=_ModPlug_ExportMOD") #pragma comment(linker, "/EXPORT:ModPlug_ExportIT=_ModPlug_ExportIT") #else /* !_M_IX86 */ #pragma comment(linker, "/EXPORT:ModPlug_Load") #pragma comment(linker, "/EXPORT:ModPlug_Unload") #pragma comment(linker, "/EXPORT:ModPlug_Read") #pragma comment(linker, "/EXPORT:ModPlug_GetName") #pragma comment(linker, "/EXPORT:ModPlug_GetLength") #pragma comment(linker, "/EXPORT:ModPlug_Seek") #pragma comment(linker, "/EXPORT:ModPlug_GetSettings") #pragma comment(linker, "/EXPORT:ModPlug_SetSettings") #pragma comment(linker, "/EXPORT:ModPlug_GetMasterVolume") #pragma comment(linker, "/EXPORT:ModPlug_SetMasterVolume") #pragma comment(linker, "/EXPORT:ModPlug_GetCurrentSpeed") #pragma comment(linker, "/EXPORT:ModPlug_GetCurrentTempo") #pragma comment(linker, "/EXPORT:ModPlug_GetCurrentOrder") #pragma comment(linker, "/EXPORT:ModPlug_GetCurrentPattern") #pragma comment(linker, "/EXPORT:ModPlug_GetCurrentRow") #pragma comment(linker, "/EXPORT:ModPlug_GetPlayingChannels") #pragma comment(linker, "/EXPORT:ModPlug_SeekOrder") #pragma comment(linker, "/EXPORT:ModPlug_GetModuleType") #pragma comment(linker, "/EXPORT:ModPlug_GetMessage") #pragma comment(linker, "/EXPORT:ModPlug_NumInstruments") #pragma comment(linker, "/EXPORT:ModPlug_NumSamples") #pragma comment(linker, "/EXPORT:ModPlug_NumPatterns") #pragma comment(linker, "/EXPORT:ModPlug_NumChannels") #pragma comment(linker, "/EXPORT:ModPlug_SampleName") #pragma comment(linker, "/EXPORT:ModPlug_InstrumentName") #pragma comment(linker, "/EXPORT:ModPlug_GetPattern") #pragma comment(linker, "/EXPORT:ModPlug_InitMixerCallback") #pragma comment(linker, "/EXPORT:ModPlug_UnloadMixerCallback") #pragma comment(linker, "/EXPORT:ModPlug_ExportS3M") #pragma comment(linker, "/EXPORT:ModPlug_ExportXM") #pragma comment(linker, "/EXPORT:ModPlug_ExportMOD") #pragma comment(linker, "/EXPORT:ModPlug_ExportIT") #endif /* _M_IX86 */ #endif /* _MSC_VER */ #endif /* NO_LIBMODPLUG */ libopenmpt-0.3.6+release.autotools/libopenmpt/libopenmpt_ext_impl.hpp0000644000372100037210000000613613124003512023207 00000000000000/* * libopenmpt_ext_impl.hpp * ----------------------- * Purpose: libopenmpt extensions - implementation header * Notes : * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #ifndef LIBOPENMPT_EXT_IMPL_HPP #define LIBOPENMPT_EXT_IMPL_HPP #include "libopenmpt_internal.h" #include "libopenmpt_impl.hpp" #include "libopenmpt_ext.hpp" using namespace OpenMPT; namespace openmpt { class module_ext_impl : public module_impl , public ext::pattern_vis , public ext::interactive /* add stuff here */ { public: module_ext_impl( callback_stream_wrapper stream, std::unique_ptr log, const std::map< std::string, std::string > & ctls ); module_ext_impl( std::istream & stream, std::unique_ptr log, const std::map< std::string, std::string > & ctls ); module_ext_impl( const std::vector & data, std::unique_ptr log, const std::map< std::string, std::string > & ctls ); module_ext_impl( const std::vector & data, std::unique_ptr log, const std::map< std::string, std::string > & ctls ); module_ext_impl( const std::uint8_t * data, std::size_t size, std::unique_ptr log, const std::map< std::string, std::string > & ctls ); module_ext_impl( const char * data, std::size_t size, std::unique_ptr log, const std::map< std::string, std::string > & ctls ); module_ext_impl( const void * data, std::size_t size, std::unique_ptr log, const std::map< std::string, std::string > & ctls ); private: /* add stuff here */ private: void ctor(); public: ~module_ext_impl(); public: void * get_interface( const std::string & interface_id ); // pattern_vis virtual effect_type get_pattern_row_channel_volume_effect_type( std::int32_t pattern, std::int32_t row, std::int32_t channel ) const; virtual effect_type get_pattern_row_channel_effect_type( std::int32_t pattern, std::int32_t row, std::int32_t channel ) const; // interactive virtual void set_current_speed( std::int32_t speed ); virtual void set_current_tempo( std::int32_t tempo ); virtual void set_tempo_factor( double factor ); virtual double get_tempo_factor( ) const; virtual void set_pitch_factor( double factor ); virtual double get_pitch_factor( ) const; virtual void set_global_volume( double volume ); virtual double get_global_volume( ) const; virtual void set_channel_volume( std::int32_t channel, double volume ); virtual double get_channel_volume( std::int32_t channel ) const; virtual void set_channel_mute_status( std::int32_t channel, bool mute ); virtual bool get_channel_mute_status( std::int32_t channel ) const; virtual void set_instrument_mute_status( std::int32_t instrument, bool mute ); virtual bool get_instrument_mute_status( std::int32_t instrument ) const; virtual std::int32_t play_note( std::int32_t instrument, std::int32_t note, double volume, double panning ); virtual void stop_note( std::int32_t channel ); /* add stuff here */ }; // class module_ext_impl } // namespace openmpt #endif // LIBOPENMPT_EXT_IMPL_HPP libopenmpt-0.3.6+release.autotools/libopenmpt/libopenmpt_config.h0000644000372100037210000001367713223644151022315 00000000000000/* * libopenmpt_config.h * ------------------- * Purpose: libopenmpt public interface configuration * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #ifndef LIBOPENMPT_CONFIG_H #define LIBOPENMPT_CONFIG_H /*! \defgroup libopenmpt libopenmpt */ /*! \addtogroup libopenmpt @{ */ /* provoke warnings if already defined */ #define LIBOPENMPT_API #undef LIBOPENMPT_API #define LIBOPENMPT_CXX_API #undef LIBOPENMPT_CXX_API /*! \brief Defined if libopenmpt/libopenmpt_stream_callbacks_buffer.h exists. */ #define LIBOPENMPT_STREAM_CALLBACKS_BUFFER /*! \brief Defined if libopenmpt/libopenmpt_stream_callbacks_fd.h exists. * \since 0.3 * \remarks * Use the following to check for availability: * \code * #include * #if defined(LIBOPENMPT_STREAM_CALLBACKS_FD) || ((OPENMPT_API_VERSION_MAJOR == 0) && ((OPENMPT_API_VERSION_MINOR == 2) || (OPENMPT_API_VERSION_MINOR == 1))) * #include * #endif * \endcode */ #define LIBOPENMPT_STREAM_CALLBACKS_FD /*! \brief Defined if libopenmpt/libopenmpt_stream_callbacks_file.h exists. * \since 0.3 * \remarks * Use the following to check for availability: * \code * #include * #if defined(LIBOPENMPT_STREAM_CALLBACKS_FILE) || ((OPENMPT_API_VERSION_MAJOR == 0) && ((OPENMPT_API_VERSION_MINOR == 2) || (OPENMPT_API_VERSION_MINOR == 1))) * #include * #endif * \endcode */ #define LIBOPENMPT_STREAM_CALLBACKS_FILE #if defined(__DOXYGEN__) #define LIBOPENMPT_API_HELPER_EXPORT #define LIBOPENMPT_API_HELPER_IMPORT #define LIBOPENMPT_API_HELPER_PUBLIC #define LIBOPENMPT_API_HELPER_LOCAL #elif defined(_MSC_VER) #define LIBOPENMPT_API_HELPER_EXPORT __declspec(dllexport) #define LIBOPENMPT_API_HELPER_IMPORT __declspec(dllimport) #define LIBOPENMPT_API_HELPER_PUBLIC #define LIBOPENMPT_API_HELPER_LOCAL #elif defined(__EMSCRIPTEN__) #define LIBOPENMPT_API_HELPER_EXPORT __attribute__((visibility("default"))) __attribute__((used)) #define LIBOPENMPT_API_HELPER_IMPORT __attribute__((visibility("default"))) __attribute__((used)) #define LIBOPENMPT_API_HELPER_PUBLIC __attribute__((visibility("default"))) __attribute__((used)) #define LIBOPENMPT_API_HELPER_LOCAL __attribute__((visibility("hidden"))) #elif (defined(__GNUC__) || defined(__clang__)) && defined(_WIN32) #define LIBOPENMPT_API_HELPER_EXPORT __declspec(dllexport) #define LIBOPENMPT_API_HELPER_IMPORT __declspec(dllimport) #define LIBOPENMPT_API_HELPER_PUBLIC __attribute__((visibility("default"))) #define LIBOPENMPT_API_HELPER_LOCAL __attribute__((visibility("hidden"))) #elif defined(__GNUC__) || defined(__clang__) #define LIBOPENMPT_API_HELPER_EXPORT __attribute__((visibility("default"))) #define LIBOPENMPT_API_HELPER_IMPORT __attribute__((visibility("default"))) #define LIBOPENMPT_API_HELPER_PUBLIC __attribute__((visibility("default"))) #define LIBOPENMPT_API_HELPER_LOCAL __attribute__((visibility("hidden"))) #elif defined(_WIN32) #define LIBOPENMPT_API_HELPER_EXPORT __declspec(dllexport) #define LIBOPENMPT_API_HELPER_IMPORT __declspec(dllimport) #define LIBOPENMPT_API_HELPER_PUBLIC #define LIBOPENMPT_API_HELPER_LOCAL #else #define LIBOPENMPT_API_HELPER_EXPORT #define LIBOPENMPT_API_HELPER_IMPORT #define LIBOPENMPT_API_HELPER_PUBLIC #define LIBOPENMPT_API_HELPER_LOCAL #endif #if defined(LIBOPENMPT_BUILD_DLL) #define LIBOPENMPT_API LIBOPENMPT_API_HELPER_EXPORT #elif defined(LIBOPENMPT_USE_DLL) #define LIBOPENMPT_API LIBOPENMPT_API_HELPER_IMPORT #else #define LIBOPENMPT_API LIBOPENMPT_API_HELPER_PUBLIC #endif #ifdef __cplusplus #define LIBOPENMPT_CXX_API LIBOPENMPT_API #if defined(LIBOPENMPT_USE_DLL) #if defined(_MSC_VER) && !defined(_DLL) #error "C++ interface is disabled if libopenmpt is built as a DLL and the runtime is statically linked. This is not supported by microsoft and cannot possibly work. Ever." #undef LIBOPENMPT_CXX_API #define LIBOPENMPT_CXX_API LIBOPENMPT_API_HELPER_LOCAL #endif #endif #if defined(__EMSCRIPTEN__) /* Only the C API is supported for emscripten. Disable the C++ API. */ #undef LIBOPENMPT_CXX_API #define LIBOPENMPT_CXX_API LIBOPENMPT_API_HELPER_LOCAL #endif #endif /*! @} */ /* C */ #if !defined(LIBOPENMPT_NO_DEPRECATE) #if defined(__clang__) #define LIBOPENMPT_DEPRECATED __attribute__((deprecated)) #elif defined(__GNUC__) #define LIBOPENMPT_DEPRECATED __attribute__((deprecated)) #elif defined(_MSC_VER) #define LIBOPENMPT_DEPRECATED __declspec(deprecated) #else #define LIBOPENMPT_DEPRECATED #endif #endif #ifndef __cplusplus #if !defined(LIBOPENMPT_NO_DEPRECATE) LIBOPENMPT_DEPRECATED static const int LIBOPENMPT_DEPRECATED_STRING_CONSTANT = 0; #define LIBOPENMPT_DEPRECATED_STRING( str ) ( LIBOPENMPT_DEPRECATED_STRING_CONSTANT ? ( str ) : ( str ) ) #else #define LIBOPENMPT_DEPRECATED_STRING( str ) str #endif #endif /* C++ */ #ifdef __cplusplus #ifndef LIBOPENMPT_ASSUME_CPLUSPLUS_DEPRECATED /* handle known broken compilers here by defining LIBOPENMPT_ASSUME_CPLUSPLUS_DEPRECATED appropriately */ #endif #if defined(LIBOPENMPT_ASSUME_CPLUSPLUS) #ifndef LIBOPENMPT_ASSUME_CPLUSPLUS_DEPRECATED #define LIBOPENMPT_ASSUME_CPLUSPLUS_DEPRECATED LIBOPENMPT_ASSUME_CPLUSPLUS #endif #endif #if !defined(LIBOPENMPT_NO_DEPRECATE) #if defined(LIBOPENMPT_ASSUME_CPLUSPLUS_DEPRECATED) #if (LIBOPENMPT_ASSUME_CPLUSPLUS_DEPRECATED >= 201402L) #define LIBOPENMPT_ATTR_DEPRECATED [[deprecated]] #undef LIBOPENMPT_DEPRECATED #define LIBOPENMPT_DEPRECATED #else #define LIBOPENMPT_ATTR_DEPRECATED #endif #elif (__cplusplus >= 201402L) #define LIBOPENMPT_ATTR_DEPRECATED [[deprecated]] #undef LIBOPENMPT_DEPRECATED #define LIBOPENMPT_DEPRECATED #else #define LIBOPENMPT_ATTR_DEPRECATED #endif #else #undef LIBOPENMPT_DEPRECATED #define LIBOPENMPT_DEPRECATED #define LIBOPENMPT_ATTR_DEPRECATED #endif #endif #include "libopenmpt_version.h" #endif /* LIBOPENMPT_CONFIG_H */ libopenmpt-0.3.6+release.autotools/man/0000755000372100037210000000000013235362226015115 500000000000000libopenmpt-0.3.6+release.autotools/man/openmpt123.10000644000372100037210000001002713235362207017026 00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. .TH OPENMPT123 "1" "February 2018" "openmpt123 v0.3.6" "User Commands" .SH NAME openmpt123 - command line module music player based on libopenmpt .SH SYNOPSIS .B openmpt123 [\fI\,options\/\fR] [\fI\,--\/\fR] \fI\,file1 \/\fR[\fI\,file2\/\fR] ... .SH DESCRIPTION openmpt123 plays module music files. .SH OPTIONS .TP \fB\-h\fR, \fB\-\-help\fR Show help .TP \fB\-\-help\-keyboard\fR Show keyboard hotkeys in ui mode .TP \fB\-q\fR, \fB\-\-quiet\fR Suppress non\-error screen output .TP \fB\-v\fR, \fB\-\-verbose\fR Show more screen output .TP \fB\-\-version\fR Show version information and exit .TP \fB\-\-short\-version\fR Show version number and nothing else .TP \fB\-\-long\-version\fR Show long version information and exit .TP \fB\-\-credits\fR Show elaborate contributors list .TP \fB\-\-license\fR Show license .TP \fB\-\-probe\fR Probe each file whether it is a supported file format .TP \fB\-\-info\fR Display information about each file .TP \fB\-\-ui\fR Interactively play each file .TP \fB\-\-batch\fR Play each file .TP \fB\-\-render\fR Render each file to individual PCM data files .TP \fB\-\-terminal\-width\fR n Assume terminal is n characters wide [default: 72] .TP \fB\-\-terminal\-height\fR n Assume terminal is n characters high [default: 23] .TP \fB\-\-[no\-]progress\fR Show playback progress [default: 0] .TP \fB\-\-[no\-]meters\fR Show peak meters [default: 0] .TP \fB\-\-[no\-]channel\-meters\fR Show channel peak meters (EXPERIMENTAL) [default: 0] .TP \fB\-\-[no\-]pattern\fR Show pattern (EXPERIMENTAL) [default: 0] .TP \fB\-\-[no\-]details\fR Show song details [default: 1] .TP \fB\-\-[no\-]message\fR Show song message [default: 0] .TP \fB\-\-update\fR n Set output update interval to n ms [default: \fB\-1]\fR .TP \fB\-\-samplerate\fR n Set samplerate to n Hz [default: 48000] .TP \fB\-\-channels\fR n use n [1,2,4] output channels [default: 2] .TP \fB\-\-[no\-]float\fR Output 32bit floating point instead of 16bit integer [default: 1] .TP \fB\-\-gain\fR n Set output gain to n dB [default: 0] .TP \fB\-\-stereo\fR n Set stereo separation to n % [default: 100] .TP \fB\-\-filter\fR n Set interpolation filter taps to n [1,2,4,8] [default: 8] .TP \fB\-\-ramping\fR n Set volume ramping strength n [0..5] [default: \fB\-1]\fR .TP \fB\-\-tempo\fR f Set tempo factor f [default: 1] .TP \fB\-\-pitch\fR f Set pitch factor f [default: 1] .TP \fB\-\-dither\fR n Dither type to use (if applicable for selected output format): [0=off,1=auto,2=0.5bit,3=1bit] [default: 1] .TP \fB\-\-playlist\fR file Load playlist from file .TP \fB\-\-[no\-]randomize\fR Randomize playlist [default: 0] .TP \fB\-\-[no\-]shuffle\fR Shuffle through playlist [default: 0] .TP \fB\-\-[no\-]restart\fR Restart playlist when finished [default: 0] .TP \fB\-\-subsong\fR n Select subsong n (\fB\-1\fR means play all subsongs consecutively) [default: \fB\-1]\fR .TP \fB\-\-repeat\fR n Repeat song n times (\fB\-1\fR means forever) [default: 0] .TP \fB\-\-seek\fR n Seek to n seconds on start [default: 0] .TP \fB\-\-end\-time\fR n Play until position is n seconds (0 means until the end) [default: 0] .TP \fB\-\-ctl\fR c=v Set libopenmpt ctl c to value v .TP \fB\-\-driver\fR n Set output driver [default: default], .TP \fB\-\-device\fR n Set output device [default: default], use \fB\-\-device\fR help to show available devices .TP \fB\-\-buffer\fR n Set output buffer size to n ms [default: \fB\-1]\fR .TP \fB\-\-period\fR n Set output period size to n ms [default: \fB\-1]\fR .TP \fB\-\-stdout\fR Write raw audio data to stdout [default: 0] .TP \fB\-\-output\-type\fR t Use output format t when writing to a individual PCM files (only applies to \fB\-\-render\fR mode) [default: wav] .TP \fB\-o\fR, \fB\-\-output\fR f Write PCM output to file f instead of streaming to audio device (only applies to \fB\-\-ui\fR and \fB\-\-batch\fR modes) [default: ] .TP \fB\-\-force\fR Force overwriting of output file [default: 0] .TP \fB\-\-\fR Interpret further arguments as filenames .SH COPYRIGHT Copyright \(co 2013\-2018 OpenMPT developers libopenmpt-0.3.6+release.autotools/soundlib/0000755000372100037210000000000013235362226016161 500000000000000libopenmpt-0.3.6+release.autotools/soundlib/Snd_defs.h0000644000372100037210000006446113153344423020010 00000000000000/* * Snd_Defs.h * ---------- * Purpose: Basic definitions of data types, enums, etc. for the playback engine core. * Notes : (currently none) * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "../common/typedefs.h" #include "../common/FlagSet.h" OPENMPT_NAMESPACE_BEGIN typedef uint32 ROWINDEX; const ROWINDEX ROWINDEX_INVALID = uint32_max; typedef uint16 CHANNELINDEX; const CHANNELINDEX CHANNELINDEX_INVALID = uint16_max; typedef uint16 ORDERINDEX; const ORDERINDEX ORDERINDEX_INVALID = uint16_max; const ORDERINDEX ORDERINDEX_MAX = uint16_max - 1; typedef uint16 PATTERNINDEX; const PATTERNINDEX PATTERNINDEX_INVALID = uint16_max; typedef uint8 PLUGINDEX; const PLUGINDEX PLUGINDEX_INVALID = uint8_max; typedef uint16 SAMPLEINDEX; const SAMPLEINDEX SAMPLEINDEX_INVALID = uint16_max; typedef uint16 INSTRUMENTINDEX; const INSTRUMENTINDEX INSTRUMENTINDEX_INVALID = uint16_max; typedef uint8 SEQUENCEINDEX; const SEQUENCEINDEX SEQUENCEINDEX_INVALID = uint8_max; typedef uint32 SmpLength; const SmpLength MAX_SAMPLE_LENGTH = 0x10000000; // Sample length in *frames* // Note: Sample size in bytes can be more than this (= 256 MB). const ROWINDEX MAX_PATTERN_ROWS = 1024; const ORDERINDEX MAX_ORDERS = ORDERINDEX_MAX + 1; const PATTERNINDEX MAX_PATTERNS = 4000; const SAMPLEINDEX MAX_SAMPLES = 4000; const INSTRUMENTINDEX MAX_INSTRUMENTS = 256; const PLUGINDEX MAX_MIXPLUGINS = 250; const SEQUENCEINDEX MAX_SEQUENCES = 50; const CHANNELINDEX MAX_BASECHANNELS = 127; // Maximum pattern channels. const CHANNELINDEX MAX_CHANNELS = 256; // Maximum number of mixing channels. #define FREQ_FRACBITS 4 // Number of fractional bits in return value of CSoundFile::GetFreqFromPeriod() // String lengths (including trailing null char) #define MAX_SAMPLENAME 32 #define MAX_SAMPLEFILENAME 22 #define MAX_INSTRUMENTNAME 32 #define MAX_INSTRUMENTFILENAME 32 #define MAX_PATTERNNAME 32 #define MAX_CHANNELNAME 20 enum MODTYPE { MOD_TYPE_NONE = 0x00, MOD_TYPE_MOD = 0x01, MOD_TYPE_S3M = 0x02, MOD_TYPE_XM = 0x04, MOD_TYPE_MED = 0x08, MOD_TYPE_MTM = 0x10, MOD_TYPE_IT = 0x20, MOD_TYPE_669 = 0x40, MOD_TYPE_ULT = 0x80, MOD_TYPE_STM = 0x100, MOD_TYPE_FAR = 0x200, MOD_TYPE_DTM = 0x400, MOD_TYPE_AMF = 0x800, MOD_TYPE_AMS = 0x1000, MOD_TYPE_DSM = 0x2000, MOD_TYPE_MDL = 0x4000, MOD_TYPE_OKT = 0x8000, MOD_TYPE_MID = 0x10000, MOD_TYPE_DMF = 0x20000, MOD_TYPE_PTM = 0x40000, MOD_TYPE_DBM = 0x80000, MOD_TYPE_MT2 = 0x100000, MOD_TYPE_AMF0 = 0x200000, MOD_TYPE_PSM = 0x400000, MOD_TYPE_J2B = 0x800000, MOD_TYPE_MPT = 0x1000000, MOD_TYPE_IMF = 0x2000000, MOD_TYPE_AMS2 = 0x4000000, MOD_TYPE_DIGI = 0x8000000, MOD_TYPE_STP = 0x10000000, MOD_TYPE_PLM = 0x20000000, MOD_TYPE_SFX = 0x40000000, }; DECLARE_FLAGSET(MODTYPE) enum MODCONTAINERTYPE { MOD_CONTAINERTYPE_NONE = 0x0, MOD_CONTAINERTYPE_MO3 = 0x1, MOD_CONTAINERTYPE_GDM = 0x2, MOD_CONTAINERTYPE_UMX = 0x3, MOD_CONTAINERTYPE_XPK = 0x4, MOD_CONTAINERTYPE_PP20 = 0x5, MOD_CONTAINERTYPE_MMCMP= 0x6, MOD_CONTAINERTYPE_WAV = 0x7, // WAV as module MOD_CONTAINERTYPE_UAX = 0x8, // Unreal sample set as module }; // Module channel / sample flags enum ChannelFlags { // Sample Flags CHN_16BIT = 0x01, // 16-bit sample CHN_LOOP = 0x02, // looped sample CHN_PINGPONGLOOP = 0x04, // bidi-looped sample CHN_SUSTAINLOOP = 0x08, // sample with sustain loop CHN_PINGPONGSUSTAIN = 0x10, // sample with bidi sustain loop CHN_PANNING = 0x20, // sample with forced panning CHN_STEREO = 0x40, // stereo sample CHN_REVERSE = 0x80, // start sample playback from sample / loop end (Velvet Studio feature) - this is intentionally the same flag as CHN_PINGPONGFLAG. // Channel Flags CHN_PINGPONGFLAG = 0x80, // when flag is on, sample is processed backwards CHN_MUTE = 0x100, // muted channel CHN_KEYOFF = 0x200, // exit sustain CHN_NOTEFADE = 0x400, // fade note (instrument mode) CHN_SURROUND = 0x800, // use surround channel CHN_WRAPPED_LOOP = 0x1000, // loop just wrapped around to loop start (required for correct interpolation around loop points) CHN_AMIGAFILTER = 0x2000, // Apply Amiga low-pass filter CHN_FILTER = 0x4000, // Apply resonant filter on sample CHN_VOLUMERAMP = 0x8000, // Apply volume ramping CHN_VIBRATO = 0x10000, // Apply vibrato CHN_TREMOLO = 0x20000, // Apply tremolo //CHN_PANBRELLO = 0x40000, // Apply panbrello CHN_PORTAMENTO = 0x80000, // Apply portamento CHN_GLISSANDO = 0x100000, // Glissando (force portamento to semitones) mode CHN_FASTVOLRAMP = 0x200000, // Force usage of global ramping settings instead of ramping over the complete render buffer length CHN_EXTRALOUD = 0x400000, // Force sample to play at 0dB CHN_REVERB = 0x800000, // Apply reverb on this channel CHN_NOREVERB = 0x1000000, // Disable reverb on this channel CHN_SOLO = 0x2000000, // solo channel -> CODE#0012 -> DESC="midi keyboard split" -! NEW_FEATURE#0012 CHN_NOFX = 0x4000000, // dry channel -> CODE#0015 -> DESC="channels management dlg" -! NEW_FEATURE#0015 CHN_SYNCMUTE = 0x8000000, // keep sample sync on mute // Sample flags (only present in ModSample::uFlags, may overlap with CHN_CHANNELFLAGS) SMP_MODIFIED = 0x1000, // Sample data has been edited in the tracker SMP_KEEPONDISK = 0x2000, // Sample is not saved to file, data is restored from original sample file SMP_NODEFAULTVOLUME = 0x4000, // Ignore default volume setting }; DECLARE_FLAGSET(ChannelFlags) #define CHN_SAMPLEFLAGS (CHN_16BIT | CHN_LOOP | CHN_PINGPONGLOOP | CHN_SUSTAINLOOP | CHN_PINGPONGSUSTAIN | CHN_PANNING | CHN_STEREO | CHN_PINGPONGFLAG | CHN_REVERSE) #define CHN_CHANNELFLAGS (~CHN_SAMPLEFLAGS) // Sample flags fit into the first 16 bits, and with the current memory layout, storing them as a 16-bit integer packs struct ModSample nicely. typedef FlagSet SampleFlags; // Instrument envelope-specific flags enum EnvelopeFlags { ENV_ENABLED = 0x01, // env is enabled ENV_LOOP = 0x02, // env loop ENV_SUSTAIN = 0x04, // env sustain ENV_CARRY = 0x08, // env carry ENV_FILTER = 0x10, // filter env enabled (this has to be combined with ENV_ENABLED in the pitch envelope's flags) }; DECLARE_FLAGSET(EnvelopeFlags) // Envelope value boundaries #define ENVELOPE_MIN 0 // Vertical min value of a point #define ENVELOPE_MID 32 // Vertical middle line #define ENVELOPE_MAX 64 // Vertical max value of a point #define MAX_ENVPOINTS 240 // Maximum length of each instrument envelope // Instrument-specific flags enum InstrumentFlags { INS_SETPANNING = 0x01, // Panning enabled INS_MUTE = 0x02, // Instrument is muted }; DECLARE_FLAGSET(InstrumentFlags) // envelope types in instrument editor enum EnvelopeType { ENV_VOLUME = 0, ENV_PANNING, ENV_PITCH, ENV_MAXTYPES }; // Filter Modes #define FLTMODE_UNCHANGED 0xFF #define FLTMODE_LOWPASS 0 #define FLTMODE_HIGHPASS 1 // NNA types (New Note Action) #define NNA_NOTECUT 0 #define NNA_CONTINUE 1 #define NNA_NOTEOFF 2 #define NNA_NOTEFADE 3 // DCT types (Duplicate Check Types) #define DCT_NONE 0 #define DCT_NOTE 1 #define DCT_SAMPLE 2 #define DCT_INSTRUMENT 3 #define DCT_PLUGIN 4 // DNA types (Duplicate Note Action) #define DNA_NOTECUT 0 #define DNA_NOTEOFF 1 #define DNA_NOTEFADE 2 // Module flags - contains both song configuration and playback state... Use SONG_FILE_FLAGS and SONG_PLAY_FLAGS distinguish between the two. enum SongFlags { //SONG_EMBEDMIDICFG = 0x0001, // Embed macros in file SONG_FASTVOLSLIDES = 0x0002, // Old Scream Tracker 3.0 volume slides SONG_ITOLDEFFECTS = 0x0004, // Old Impulse Tracker effect implementations SONG_ITCOMPATGXX = 0x0008, // IT "Compatible Gxx" (IT's flag to behave more like other trackers w/r/t portamento effects) SONG_LINEARSLIDES = 0x0010, // Linear slides vs. Amiga slides SONG_PATTERNLOOP = 0x0020, // Loop current pattern (pattern editor) SONG_STEP = 0x0040, // Song is in "step" mode (pattern editor) SONG_PAUSED = 0x0080, // Song is paused (no tick processing, just rendering audio) SONG_FADINGSONG = 0x0100, // Song is fading out SONG_ENDREACHED = 0x0200, // Song is finished //SONG_GLOBALFADE = 0x0400, // Song is fading out //SONG_CPUVERYHIGH = 0x0800, // High CPU usage SONG_FIRSTTICK = 0x1000, // Is set when the current tick is the first tick of the row SONG_MPTFILTERMODE = 0x2000, // Local filter mode (reset filter on each note) SONG_SURROUNDPAN = 0x4000, // Pan in the rear channels SONG_EXFILTERRANGE = 0x8000, // Cutoff Filter has double frequency range (up to ~10Khz) SONG_AMIGALIMITS = 0x10000, // Enforce amiga frequency limits SONG_S3MOLDVIBRATO = 0x20000, // ScreamTracker 2 vibrato in S3M files //SONG_ITPEMBEDIH = 0x40000, // Embed instrument headers in project file SONG_BREAKTOROW = 0x80000, // Break to row command encountered (internal flag, do not touch) SONG_POSJUMP = 0x100000, // Position jump encountered (internal flag, do not touch) SONG_PT_MODE = 0x200000, // ProTracker 1/2 playback mode SONG_PLAYALLSONGS = 0x400000, // Play all subsongs consecutively (libopenmpt) SONG_ISAMIGA = 0x800000, // Is an Amiga module and thus qualifies to be played using the Paula BLEP resampler }; DECLARE_FLAGSET(SongFlags) #define SONG_FILE_FLAGS (SONG_FASTVOLSLIDES|SONG_ITOLDEFFECTS|SONG_ITCOMPATGXX|SONG_LINEARSLIDES|SONG_EXFILTERRANGE|SONG_AMIGALIMITS|SONG_S3MOLDVIBRATO|SONG_PT_MODE|SONG_ISAMIGA) #define SONG_PLAY_FLAGS (~SONG_FILE_FLAGS) // Global Options (Renderer) #ifndef NO_AGC #define SNDDSP_AGC 0x40 // automatic gain control #endif // ~NO_AGC #ifndef NO_DSP #define SNDDSP_MEGABASS 0x02 // bass expansion #define SNDDSP_SURROUND 0x08 // surround mix #endif // NO_DSP #ifndef NO_REVERB #define SNDDSP_REVERB 0x20 // apply reverb #endif // NO_REVERB #ifndef NO_EQ #define SNDDSP_EQ 0x80 // apply EQ #endif // NO_EQ #define SNDMIX_SOFTPANNING 0x10 // soft panning mode (this is forced with mixmode RC3 and later) // Misc Flags (can safely be turned on or off) #define SNDMIX_MAXDEFAULTPAN 0x80000 // Used by the MOD loader (currently unused) #define SNDMIX_MUTECHNMODE 0x100000 // Notes are not played on muted channels #define MAX_GLOBAL_VOLUME 256u // Resampling modes enum ResamplingMode { // ATTENTION: Do not change ANY of these values, as they get written out to files in per instrument interpolation settings // and old files have these exact values in them which should not change meaning. SRCMODE_NEAREST = 0, SRCMODE_LINEAR = 1, SRCMODE_SPLINE = 2, SRCMODE_POLYPHASE = 3, SRCMODE_FIRFILTER = 4, SRCMODE_DEFAULT = 5, SRCMODE_AMIGA = 0xFF, // Not explicitely user-selectable }; static inline bool IsKnownResamplingMode(int mode) { return (mode >= 0) && (mode < SRCMODE_DEFAULT); } // Release node defines #define ENV_RELEASE_NODE_UNSET 0xFF #define NOT_YET_RELEASED (-1) STATIC_ASSERT(ENV_RELEASE_NODE_UNSET > MAX_ENVPOINTS); enum PluginPriority { ChannelOnly, InstrumentOnly, PrioritiseInstrument, PrioritiseChannel, }; enum PluginMutePriority { EvenIfMuted, RespectMutes, }; //Plugin velocity handling options enum PLUGVELOCITYHANDLING { PLUGIN_VELOCITYHANDLING_CHANNEL = 0, PLUGIN_VELOCITYHANDLING_VOLUME }; //Plugin volumecommand handling options enum PLUGVOLUMEHANDLING { PLUGIN_VOLUMEHANDLING_MIDI = 0, PLUGIN_VOLUMEHANDLING_DRYWET, PLUGIN_VOLUMEHANDLING_IGNORE, PLUGIN_VOLUMEHANDLING_CUSTOM, PLUGIN_VOLUMEHANDLING_MAX, }; enum MidiChannel { MidiNoChannel = 0, MidiFirstChannel = 1, MidiLastChannel = 16, MidiMappedChannel = 17, }; // Vibrato Types enum VibratoType { VIB_SINE = 0, VIB_SQUARE, VIB_RAMP_UP, VIB_RAMP_DOWN, VIB_RANDOM }; // Tracker-specific playback behaviour // Note: The index of every flag has to be fixed, so do not remove flags. Always add new flags at the end! enum PlayBehaviour { MSF_COMPATIBLE_PLAY, // No-op - only used during loading (Old general compatibility flag for IT/MPT/XM) kMPTOldSwingBehaviour, // MPT 1.16 swing behaviour (IT/MPT, deprecated) kMIDICCBugEmulation, // Emulate broken volume MIDI CC behaviour (IT/MPT/XM, deprecated) kOldMIDIPitchBends, // Old VST MIDI pitch bend behaviour (IT/MPT/XM, deprecated) kFT2VolumeRamping, // Smooth volume ramping like in FT2 (XM) kMODVBlankTiming, // F21 and above set speed instead of tempo kSlidesAtSpeed1, // Execute normal slides at speed 1 as if they were fine slides kHertzInLinearMode, // Compute note frequency in hertz rather than periods kTempoClamp, // Clamp tempo to 32-255 range. kPerChannelGlobalVolSlide, // Global volume slide memory is per-channel kPanOverride, // Panning commands override surround and random pan variation kITInstrWithoutNote, // Avoid instrument handling if there is no note kITVolColFinePortamento, // Volume column portamento never does fine portamento kITArpeggio, // IT arpeggio algorithm kITOutOfRangeDelay, // Out-of-range delay command behaviour in IT kITPortaMemoryShare, // Gxx shares memory with Exx and Fxx kITPatternLoopTargetReset, // After finishing a pattern loop, set the pattern loop target to the next row kITFT2PatternLoop, // Nested pattern loop behaviour kITPingPongNoReset, // Don't reset ping pong direction with instrument numbers kITEnvelopeReset, // IT envelope reset behaviour kITClearOldNoteAfterCut, // Forget the previous note after cutting it kITVibratoTremoloPanbrello, // More IT-like Hxx / hx, Rxx, Yxx and autovibrato handling, including more precise LUTs kITTremor, // Ixx behaves like in IT kITRetrigger, // Qxx behaves like in IT kITMultiSampleBehaviour, // Properly update C-5 frequency when changing in multisampled instrument kITPortaTargetReached, // Clear portamento target after it has been reached kITPatternLoopBreak, // Don't reset loop count on pattern break. kITOffset, // IT-style Oxx edge case handling kITSwingBehaviour, // IT's swing behaviour kITNNAReset, // NNA is reset on every note change, not every instrument change kITSCxStopsSample, // SCx really stops the sample and does not just mute it kITEnvelopePositionHandling, // IT-style envelope position advance + enable/disable behaviour kITPortamentoInstrument, // No sample changes during portamento with Compatible Gxx enabled, instrument envelope reset with portamento kITPingPongMode, // Don't repeat last sample point in ping pong loop, like IT's software mixer kITRealNoteMapping, // Use triggered note rather than translated note for PPS and other effects kITHighOffsetNoRetrig, // SAx should not apply an offset effect to a note next to it kITFilterBehaviour, // User IT's filter coefficients (unless extended filter range is used) kITNoSurroundPan, // Panning and surround are mutually exclusive kITShortSampleRetrig, // Don't retrigger already stopped channels kITPortaNoNote, // Don't apply any portamento if no previous note is playing kITDontResetNoteOffOnPorta, // Only reset note-off status on portamento in IT Compatible Gxx mode kITVolColMemory, // IT volume column effects share their memory with the effect column kITPortamentoSwapResetsPos, // Portamento with sample swap plays the new sample from the beginning kITEmptyNoteMapSlot, // IT ignores instrument note map entries with no note completely kITFirstTickHandling, // IT-style first tick handling kITSampleAndHoldPanbrello, // IT-style sample&hold panbrello waveform kITClearPortaTarget, // New notes reset portamento target in IT kITPanbrelloHold, // Don't reset panbrello effect until next note or panning effect kITPanningReset, // Sample and instrument panning is only applied on note change, not instrument change kITPatternLoopWithJumps, // Bxx on the same row as SBx terminates the loop in IT kITInstrWithNoteOff, // Instrument number with note-off recalls default volume kFT2Arpeggio, // FT2 arpeggio algorithm kFT2Retrigger, // Rxx behaves like in FT2 kFT2VolColVibrato, // Vibrato depth in volume column does not actually execute the vibrato effect kFT2PortaNoNote, // Don't play portamento-ed note if no previous note is playing kFT2KeyOff, // FT2-style Kxx handling kFT2PanSlide, // Volume-column pan slides should be handled like fine slides kFT2OffsetOutOfRange, // FT2-style 9xx edge case handling kFT2RestrictXCommand, // Don't allow MPT extensions to Xxx command in XM kFT2RetrigWithNoteDelay, // Retrigger envelopes if there is a note delay with no note kFT2SetPanEnvPos, // Lxx only sets the pan env position if the volume envelope's sustain flag is set kFT2PortaIgnoreInstr, // Portamento plus instrument number applies the volume settings of the new sample, but not the new sample itself. kFT2VolColMemory, // No volume column memory in FT2 kFT2LoopE60Restart, // Next pattern starts on the same row as the last E60 command kFT2ProcessSilentChannels, // Keep processing silent channels for later 3xx pickup kFT2ReloadSampleSettings, // Reload sample settings even if a note-off is placed next to an instrument number kFT2PortaDelay, // Portamento with note delay next to it is ignored in FT2 kFT2Transpose, // Out-of-range transposed notes in FT2 kFT2PatternLoopWithJumps, // Bxx or Dxx on the same row as E6x terminates the loop in FT2 kFT2PortaTargetNoReset, // Portamento target is not reset with new notes in FT2 kFT2EnvelopeEscape, // FT2 sustain point at end of envelope kFT2Tremor, // Txx behaves like in FT2 kFT2OutOfRangeDelay, // Out-of-range delay command behaviour in FT2 kFT2Periods, // Use FT2's broken period handling kFT2PanWithDelayedNoteOff, // Pan command with delayed note-off kFT2VolColDelay, // FT2-style volume column handling if there is a note delay kFT2FinetunePrecision, // Only take the upper 4 bits of sample finetune. kST3NoMutedChannels, // Don't process any effects on muted S3M channels kST3EffectMemory, // Most effects share the same memory in ST3 kST3PortaSampleChange, // Portamento plus instrument number applies the volume settings of the new sample, but not the new sample itself. kST3VibratoMemory, // Do not remember vibrato type in effect memory kST3LimitPeriod, // Cut note instead of limiting final period (ModPlug Tracker style) KST3PortaAfterArpeggio, // Portamento after arpeggio continues at the note where the arpeggio left off kMODOneShotLoops, // Allow ProTracker-like oneshot loops kMODIgnorePanning, // Do not process any panning commands kMODSampleSwap, // On-the-fly sample swapping kFT2NoteOffFlags, // Set and reset the correct fade/key-off flags with note-off and instrument number after note-off kITMultiSampleInstrumentNumber, // After portamento to different sample within multi-sampled instrument, lone instrument numbers in patterns always recall the new sample's default settings kRowDelayWithNoteDelay, // Retrigger note delays on every reptition of a row kFT2TremoloRampWaveform, // FT2-compatible tremolo ramp down / triangle waveform kFT2PortaUpDownMemory, // Portamento up and down have separate memory kMODOutOfRangeNoteDelay, // ProTracker behaviour for out-of-range note delays kMODTempoOnSecondTick, // ProTracker sets tempo after the first tick // Add new play behaviours here. kMaxPlayBehaviours, }; // Tempo swing determines how much every row in modern tempo mode contributes to a beat. class TempoSwing : public std::vector { public: enum { Unity = 1u << 24 }; // Normalize the tempo swing coefficients so that they add up to exactly the specified tempo again void Normalize(); void resize(size_type newSize, value_type val = Unity) { std::vector::resize(newSize, val); Normalize(); } static void Serialize(std::ostream &oStrm, const TempoSwing &swing); static void Deserialize(std::istream &iStrm, TempoSwing &swing, const size_t); }; // Sample position and sample position increment value struct SamplePosition { typedef int64 value_t; typedef uint64 unsigned_value_t; protected: value_t v; public: static const uint32 fractMax = 0xFFFFFFFFu; static MPT_FORCEINLINE uint32 GetFractMax() { return fractMax; } SamplePosition() : v(0) { } explicit SamplePosition(value_t pos) : v(pos) { } SamplePosition(int32 intPart, uint32 fractPart) : v((static_cast(intPart) * (1ll<<32)) | fractPart) { } static SamplePosition Ratio(uint32 dividend, uint32 divisor) { return SamplePosition((static_cast(dividend) << 32) / divisor); } static SamplePosition FromDouble(double pos) { return SamplePosition(static_cast(pos * 4294967296.0)); } // Set integer and fractional part MPT_FORCEINLINE SamplePosition &Set(int32 intPart, uint32 fractPart = 0) { v = (static_cast(intPart) << 32) | fractPart; return *this; } // Set integer part, keep fractional part MPT_FORCEINLINE SamplePosition &SetInt(int32 intPart) { v = (static_cast(intPart) << 32) | GetFract(); return *this; } // Get integer part (as sample length / position) MPT_FORCEINLINE SmpLength GetUInt() const { return static_cast(static_cast(v) >> 32); } // Get integer part MPT_FORCEINLINE int32 GetInt() const { return static_cast(static_cast(v) >> 32); } // Get fractional part MPT_FORCEINLINE uint32 GetFract() const { return static_cast(v); } // Get the inverted fractional part MPT_FORCEINLINE SamplePosition GetInvertedFract() const { return SamplePosition(0x100000000ll - GetFract()); } // Get the raw fixed-point value MPT_FORCEINLINE int64 GetRaw() const { return v; } // Negate the current value MPT_FORCEINLINE SamplePosition &Negate() { v = -v; return *this; } // Multiply and divide by given integer scalars MPT_FORCEINLINE SamplePosition &MulDiv(uint32 mul, uint32 div) { v = (v * mul) / div; return *this; } // Removes the integer part, only keeping fractions MPT_FORCEINLINE SamplePosition &RemoveInt() { v &= fractMax; return *this; } // Check if value is 1.0 MPT_FORCEINLINE bool IsUnity() const { return v == 0x100000000ll; } // Check if value is 0 MPT_FORCEINLINE bool IsZero() const { return v == 0; } // Check if value is > 0 MPT_FORCEINLINE bool IsPositive() const { return v > 0; } // Check if value is < 0 MPT_FORCEINLINE bool IsNegative() const { return v < 0; } // Addition / subtraction of another fixed-point number SamplePosition operator+ (const SamplePosition &other) const { return SamplePosition(v + other.v); } SamplePosition operator- (const SamplePosition &other) const { return SamplePosition(v - other.v); } void operator+= (const SamplePosition &other) { v += other.v; } void operator-= (const SamplePosition &other) { v -= other.v; } // Multiplication with integer scalar template SamplePosition operator* (T other) const { return SamplePosition(static_cast(v * other)); } template void operator*= (T other) { v = static_cast(v *other); } // Division by other fractional point number; returns scalar value_t operator/ (SamplePosition other) const { return v / other.v; } // Division by scalar; returns fractional point number SamplePosition operator/ (int div) const { return SamplePosition(v / div); } bool operator== (const SamplePosition &other) const { return v == other.v; } bool operator!= (const SamplePosition &other) const { return v != other.v; } bool operator<= (const SamplePosition &other) const { return v <= other.v; } bool operator>= (const SamplePosition &other) const { return v >= other.v; } bool operator< (const SamplePosition &other) const { return v < other.v; } bool operator> (const SamplePosition &other) const { return v > other.v; } }; // Aaaand another fixed-point type, e.g. used for fractional tempos // Note that this doesn't use classical bit shifting for the fixed point part. // This is mostly for the clarity of stored values and to be able to represent any value .0000 to .9999 properly. // For easier debugging, use the Debugger Visualizers available in build/vs/debug/ // to easily display the stored values. template struct FPInt { protected: T v; MPT_CONSTEXPR11_FUN FPInt(T rawValue) : v(rawValue) { } public: static const size_t fractFact = FFact; typedef T store_t; MPT_CONSTEXPR11_FUN FPInt() : v(0) { } MPT_CONSTEXPR11_FUN FPInt(const FPInt &other) : v(other.v) { } MPT_CONSTEXPR11_FUN FPInt(T intPart, T fractPart) : v((intPart * fractFact) + (fractPart % fractFact)) { } explicit MPT_CONSTEXPR11_FUN FPInt(float f) : v(static_cast(f * float(fractFact))) { } explicit MPT_CONSTEXPR11_FUN FPInt(double f) : v(static_cast(f * double(fractFact))) { } // Set integer and fractional part MPT_CONSTEXPR14_FUN FPInt &Set(T intPart, T fractPart = 0) { v = (intPart * fractFact) + (fractPart % fractFact); return *this; } // Set raw internal representation directly MPT_CONSTEXPR14_FUN FPInt &SetRaw(T value) { v = value; return *this; } // Retrieve the integer part of the stored value MPT_CONSTEXPR11_FUN T GetInt() const { return v / fractFact; } // Retrieve the fractional part of the stored value MPT_CONSTEXPR11_FUN T GetFract() const { return v % fractFact; } // Retrieve the raw internal representation of the stored value MPT_CONSTEXPR11_FUN T GetRaw() const { return v; } // Formats the stored value as a floating-point value MPT_CONSTEXPR11_FUN double ToDouble() const { return v / double(fractFact); } MPT_CONSTEXPR11_FUN FPInt operator+ (const FPInt &other) const { return FPInt(v + other.v); } MPT_CONSTEXPR11_FUN FPInt operator- (const FPInt &other) const { return FPInt(v - other.v); } MPT_CONSTEXPR14_FUN FPInt operator+= (const FPInt &other) { v += other.v; return *this; } MPT_CONSTEXPR14_FUN FPInt operator-= (const FPInt &other) { v -= other.v; return *this; } MPT_CONSTEXPR11_FUN bool operator== (const FPInt &other) const { return v == other.v; } MPT_CONSTEXPR11_FUN bool operator!= (const FPInt &other) const { return v != other.v; } MPT_CONSTEXPR11_FUN bool operator<= (const FPInt &other) const { return v <= other.v; } MPT_CONSTEXPR11_FUN bool operator>= (const FPInt &other) const { return v >= other.v; } MPT_CONSTEXPR11_FUN bool operator< (const FPInt &other) const { return v < other.v; } MPT_CONSTEXPR11_FUN bool operator> (const FPInt &other) const { return v > other.v; } }; typedef FPInt<10000, uint32> TEMPO; OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/MixerSettings.cpp0000644000372100037210000000251612342405040021404 00000000000000/* * MixerSettings.cpp * ----------------- * Purpose: A struct containing settings for the mixer of soundlib. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "MixerSettings.h" #include "Snd_defs.h" #include "../common/misc_util.h" OPENMPT_NAMESPACE_BEGIN MixerSettings::MixerSettings() { // SNDMIX: These are global flags for playback control m_nStereoSeparation = 128; m_nMaxMixChannels = MAX_CHANNELS; DSPMask = 0; MixerFlags = 0; // Mixing Configuration gnChannels = 2; gdwMixingFreq = 44100; m_nPreAmp = 128; VolumeRampUpMicroseconds = 363; // 16 @44100 VolumeRampDownMicroseconds = 952; // 42 @44100 } int32 MixerSettings::GetVolumeRampUpSamples() const { return Util::muldivr(VolumeRampUpMicroseconds, gdwMixingFreq, 1000000); } int32 MixerSettings::GetVolumeRampDownSamples() const { return Util::muldivr(VolumeRampDownMicroseconds, gdwMixingFreq, 1000000); } void MixerSettings::SetVolumeRampUpSamples(int32 rampUpSamples) { VolumeRampUpMicroseconds = Util::muldivr(rampUpSamples, 1000000, gdwMixingFreq); } void MixerSettings::SetVolumeRampDownSamples(int32 rampDownSamples) { VolumeRampDownMicroseconds = Util::muldivr(rampDownSamples, 1000000, gdwMixingFreq); } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Load_669.cpp0000644000372100037210000002003313161656666020102 00000000000000/* * Load_669.cpp * ------------ * Purpose: 669 Composer / UNIS 669 module loader * Notes : This is better than Schism's 669 loader :) * (some of this code is "heavily inspired" by Storlek's code from Schism Tracker, and improvements have been made where necessary.) * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" OPENMPT_NAMESPACE_BEGIN struct _669FileHeader { char magic[2]; // 'if' (0x6669, ha ha) or 'JN' char songMessage[108]; // Song Message uint8 samples; // number of samples (1-64) uint8 patterns; // number of patterns (1-128) uint8 restartPos; uint8 orders[128]; uint8 tempoList[128]; uint8 breaks[128]; }; MPT_BINARY_STRUCT(_669FileHeader, 497) struct _669Sample { char filename[13]; uint32le length; uint32le loopStart; uint32le loopEnd; // Convert a 669 sample header to OpenMPT's internal sample header. void ConvertToMPT(ModSample &mptSmp) const { mptSmp.Initialize(); mptSmp.nC5Speed = 8363; mptSmp.nLength = length; mptSmp.nLoopStart = loopStart; mptSmp.nLoopEnd = loopEnd; if(mptSmp.nLoopEnd > mptSmp.nLength && mptSmp.nLoopStart == 0) { mptSmp.nLoopEnd = 0; } if(mptSmp.nLoopEnd != 0) { mptSmp.uFlags = CHN_LOOP; mptSmp.SanitizeLoops(); } } }; MPT_BINARY_STRUCT(_669Sample, 25) static bool ValidateHeader(const _669FileHeader &fileHeader) { if((std::memcmp(fileHeader.magic, "if", 2) && std::memcmp(fileHeader.magic, "JN", 2)) || fileHeader.samples > 64 || fileHeader.restartPos >= 128 || fileHeader.patterns > 128) { return false; } for(std::size_t i = 0; i < CountOf(fileHeader.breaks); i++) { if(fileHeader.orders[i] >= 128 && fileHeader.orders[i] < 0xFE) { return false; } if(fileHeader.orders[i] < 128 && fileHeader.tempoList[i] == 0) { return false; } if(fileHeader.breaks[i] >= 64) { return false; } } return true; } static uint64 GetHeaderMinimumAdditionalSize(const _669FileHeader &fileHeader) { return fileHeader.samples * sizeof(_669Sample) + fileHeader.patterns * 1536u; } CSoundFile::ProbeResult CSoundFile::ProbeFileHeader669(MemoryFileReader file, const uint64 *pfilesize) { _669FileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return ProbeWantMoreData; } if(!ValidateHeader(fileHeader)) { return ProbeFailure; } return ProbeAdditionalSize(file, pfilesize, GetHeaderMinimumAdditionalSize(fileHeader)); } bool CSoundFile::Read669(FileReader &file, ModLoadingFlags loadFlags) { _669FileHeader fileHeader; file.Rewind(); if(!file.ReadStruct(fileHeader)) { return false; } if(!ValidateHeader(fileHeader)) { return false; } if(loadFlags == onlyVerifyHeader) { return true; } if(!file.CanRead(mpt::saturate_cast(GetHeaderMinimumAdditionalSize(fileHeader)))) { return false; } InitializeGlobals(MOD_TYPE_669); m_nMinPeriod = 28 << 2; m_nMaxPeriod = 1712 << 3; m_nDefaultTempo.Set(78); m_nDefaultSpeed = 4; m_nChannels = 8; #ifdef MODPLUG_TRACEKR // 669 uses frequencies rather than periods, so linear slides mode will sound better in the higher octaves. m_SongFlags.set(SONG_LINEARSLIDES); #endif // MODPLUG_TRACKER if(!memcmp(fileHeader.magic, "if", 2)) m_madeWithTracker = MPT_USTRING("Composer 669"); else m_madeWithTracker = MPT_USTRING("UNIS 669"); m_nSamples = fileHeader.samples; for(SAMPLEINDEX smp = 1; smp <= m_nSamples; smp++) { _669Sample sampleHeader; file.ReadStruct(sampleHeader); // Since 669 files have very unfortunate magic bytes ("if") and can // hardly be validated, reject any file with far too big samples. if(sampleHeader.length >= 0x4000000) return false; sampleHeader.ConvertToMPT(Samples[smp]); mpt::String::Read(m_szNames[smp], sampleHeader.filename); } // Copy first song message line into song title mpt::String::Read(m_songName, fileHeader.songMessage, 36); // Song Message m_songMessage.ReadFixedLineLength(mpt::byte_cast(fileHeader.songMessage), 108, 36, 0); // Reading Orders ReadOrderFromArray(Order(), fileHeader.orders, MPT_ARRAY_COUNT(fileHeader.orders), 0xFF, 0xFE); if(Order()[fileHeader.restartPos] < fileHeader.patterns) Order().SetRestartPos(fileHeader.restartPos); // Set up panning for(CHANNELINDEX chn = 0; chn < 8; chn++) { ChnSettings[chn].Reset(); ChnSettings[chn].nPan = (chn & 1) ? 0xD0 : 0x30; } // Reading Patterns Patterns.ResizeArray(fileHeader.patterns); for(PATTERNINDEX pat = 0; pat < fileHeader.patterns; pat++) { if(!(loadFlags & loadPatternData) || !Patterns.Insert(pat, 64)) { file.Skip(64 * 8 * 3); continue; } const ModCommand::COMMAND effTrans[] = { CMD_PORTAMENTOUP, // Slide up (param * 80) Hz on every tick CMD_PORTAMENTODOWN, // Slide down (param * 80) Hz on every tick CMD_TONEPORTAMENTO, // Slide to note by (param * 40) Hz on every tick CMD_S3MCMDEX, // Add (param * 80) Hz to sample frequency CMD_VIBRATO, // Add (param * 669) Hz on every other tick CMD_SPEED, // Set ticks per row CMD_PANNINGSLIDE, // Extended UNIS 669 effect CMD_RETRIG, // Extended UNIS 669 effect }; uint8 effect[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; for(ROWINDEX row = 0; row < 64; row++) { PatternRow m = Patterns[pat].GetRow(row); for(CHANNELINDEX chn = 0; chn < 8; chn++, m++) { uint8 data[3]; file.ReadArray(data); uint8 note = data[0] >> 2; uint8 instr = ((data[0] & 0x03) << 4) | (data[1] >> 4); uint8 vol = data[1] & 0x0F; if(data[0] < 0xFE) { m->note = note + 36 + NOTE_MIN; m->instr = instr + 1; effect[chn] = 0xFF; } if(data[0] <= 0xFE) { m->volcmd = VOLCMD_VOLUME; m->vol = ((vol * 64 + 8) / 15); } if(data[2] != 0xFF) { effect[chn] = data[2]; } if((data[2] & 0x0F) == 0 && data[2] != 0x30) { // A param value of 0 resets the effect. effect[chn] = 0xFF; } if(effect[chn] == 0xFF) { continue; } m->param = effect[chn] & 0x0F; uint8 command = effect[chn] >> 4; if(command < static_cast(CountOf(effTrans))) { m->command = effTrans[command]; } else { m->command = CMD_NONE; continue; } // Fix some commands switch(command) { case 3: // D - frequency adjust #ifdef MODPLUG_TRACKER // Since we convert to S3M, the finetune command will not quite do what we intend to do (it can adjust the frequency upwards and downwards), so try to approximate it using a fine slide. m->command = CMD_PORTAMENTOUP; m->param |= 0xF0; #else m->param |= 0x20; #endif effect[chn] = 0xFF; break; case 4: // E - frequency vibrato - almost like an arpeggio, but does not arpeggiate by a given note but by a frequency amount. #ifdef MODPLUG_TRACKER m->command = CMD_ARPEGGIO; #endif m->param |= (m->param << 4); break; case 5: // F - set tempo // TODO: param 0 is a "super fast tempo" in Unis 669 mode (?) effect[chn] = 0xFF; break; case 6: // G - subcommands (extended) switch(m->param) { case 0: // balance fine slide left m->param = 0x4F; break; case 1: // balance fine slide right m->param = 0xF4; break; default: m->command = CMD_NONE; } break; } } } // Write pattern break if(fileHeader.breaks[pat] < 63) { Patterns[pat].WriteEffect(EffectWriter(CMD_PATTERNBREAK, 0).Row(fileHeader.breaks[pat]).RetryNextRow()); } // And of course the speed... Patterns[pat].WriteEffect(EffectWriter(CMD_SPEED, fileHeader.tempoList[pat]).RetryNextRow()); } if(loadFlags & loadSampleData) { // Reading Samples const SampleIO sampleIO( SampleIO::_8bit, SampleIO::mono, SampleIO::littleEndian, SampleIO::unsignedPCM); for(SAMPLEINDEX n = 1; n <= m_nSamples; n++) { sampleIO.ReadSample(Samples[n], file); } } return true; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/ModSample.cpp0000644000372100037210000002301513235103136020460 00000000000000/* * ModSample.h * ----------- * Purpose: Module Sample header class and helpers * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Sndfile.h" #include "ModSample.h" #include "modsmp_ctrl.h" #include OPENMPT_NAMESPACE_BEGIN // Translate sample properties between two given formats. void ModSample::Convert(MODTYPE fromType, MODTYPE toType) { // Convert between frequency and transpose values if necessary. if((!(toType & (MOD_TYPE_MOD | MOD_TYPE_XM))) && (fromType & (MOD_TYPE_MOD | MOD_TYPE_XM))) { TransposeToFrequency(); RelativeTone = 0; nFineTune = 0; // TransposeToFrequency assumes NTSC middle-C frequency like FT2, but we play MODs with PAL middle-C! if(fromType == MOD_TYPE_MOD) nC5Speed = Util::muldivr_unsigned(nC5Speed, 8272, 8363); } else if((toType & (MOD_TYPE_MOD | MOD_TYPE_XM)) && (!(fromType & (MOD_TYPE_MOD | MOD_TYPE_XM)))) { // FrequencyToTranspose assumes NTSC middle-C frequency like FT2, but we play MODs with PAL middle-C! if(toType == MOD_TYPE_MOD) nC5Speed = Util::muldivr_unsigned(nC5Speed, 8363, 8272); FrequencyToTranspose(); } // No ping-pong loop, panning and auto-vibrato for MOD / S3M samples if(toType & (MOD_TYPE_MOD | MOD_TYPE_S3M)) { uFlags.reset(CHN_PINGPONGLOOP | CHN_PANNING); nVibDepth = 0; nVibRate = 0; nVibSweep = 0; nVibType = VIB_SINE; RelativeTone = 0; } // No global volume sustain loops for MOD/S3M/XM if(toType & (MOD_TYPE_MOD | MOD_TYPE_XM | MOD_TYPE_S3M)) { nGlobalVol = 64; // Sustain loops - convert to normal loops if(uFlags[CHN_SUSTAINLOOP]) { // We probably overwrite a normal loop here, but since sustain loops are evaluated before normal loops, this is just correct. nLoopStart = nSustainStart; nLoopEnd = nSustainEnd; uFlags.set(CHN_LOOP); uFlags.set(CHN_PINGPONGLOOP, uFlags[CHN_PINGPONGSUSTAIN]); } nSustainStart = nSustainEnd = 0; uFlags.reset(CHN_SUSTAINLOOP|CHN_PINGPONGSUSTAIN); } // All XM samples have default panning, and XM's autovibrato settings are rather limited. if(toType & MOD_TYPE_XM) { if(!uFlags[CHN_PANNING]) { uFlags.set(CHN_PANNING); nPan = 128; } LimitMax(nVibDepth, uint8(15)); LimitMax(nVibRate, uint8(63)); } // Autovibrato sweep setting is inverse in XM (0 = "no sweep") and IT (0 = "no vibrato") if(((fromType & MOD_TYPE_XM) && (toType & (MOD_TYPE_IT | MOD_TYPE_MPT))) || ((toType & MOD_TYPE_XM) && (fromType & (MOD_TYPE_IT | MOD_TYPE_MPT)))) { if(nVibRate != 0 && nVibDepth != 0) { if(nVibSweep != 0) nVibSweep = mpt::saturate_cast(Util::muldivr_unsigned(nVibDepth, 256, nVibSweep)); else nVibSweep = 255; } } // Convert incompatible autovibrato types if(toType == MOD_TYPE_IT && nVibType == VIB_RAMP_UP) { nVibType = VIB_RAMP_DOWN; } else if(toType == MOD_TYPE_XM && nVibType == VIB_RANDOM) { nVibType = VIB_SINE; } // No external samples in formats other than MPTM. if(toType != MOD_TYPE_MPT) { uFlags.reset(SMP_KEEPONDISK); } } // Initialize sample slot with default values. void ModSample::Initialize(MODTYPE type) { nLength = 0; nLoopStart = nLoopEnd = 0; nSustainStart = nSustainEnd = 0; nC5Speed = 8363; nPan = 128; nVolume = 256; nGlobalVol = 64; uFlags.reset(CHN_PANNING | CHN_SUSTAINLOOP | CHN_LOOP | CHN_PINGPONGLOOP | CHN_PINGPONGSUSTAIN | SMP_MODIFIED | SMP_KEEPONDISK); if(type == MOD_TYPE_XM) { uFlags.set(CHN_PANNING); } RelativeTone = 0; nFineTune = 0; nVibType = VIB_SINE; nVibSweep = 0; nVibDepth = 0; nVibRate = 0; rootNote = 0; filename[0] = '\0'; // Default cues compatible with old-style volume column offset for(int i = 0; i < 9; i++) { cues[i] = (i + 1) << 11; } } // Returns sample rate of the sample. uint32 ModSample::GetSampleRate(const MODTYPE type) const { uint32 rate; if(CSoundFile::UseFinetuneAndTranspose(type)) rate = TransposeToFrequency(RelativeTone, nFineTune); else rate = nC5Speed; // TransposeToFrequency assumes NTSC middle-C frequency like FT2, but we play MODs with PAL middle-C! if(type == MOD_TYPE_MOD) rate = Util::muldivr_unsigned(rate, 8272, 8363); return (rate > 0) ? rate : 8363; } // Allocate sample based on a ModSample's properties. // Returns number of bytes allocated, 0 on failure. size_t ModSample::AllocateSample() { FreeSample(); if((pSample = AllocateSample(nLength, GetBytesPerSample())) == nullptr) { return 0; } else { return GetSampleSizeInBytes(); } } // Allocate sample memory. On sucess, a pointer to the silenced sample buffer is returned. On failure, nullptr is returned. // numSamples must contain the sample length, bytesPerSample the size of a sampling point multiplied with the number of channels. void *ModSample::AllocateSample(SmpLength numSamples, size_t bytesPerSample) { const size_t allocSize = GetRealSampleBufferSize(numSamples, bytesPerSample); if(allocSize != 0) { char *p = new (std::nothrow) char[allocSize]; if(p != nullptr) { memset(p, 0, allocSize); return p + (InterpolationMaxLookahead * MaxSamplingPointSize); } } return nullptr; } // Compute sample buffer size in bytes, including any overhead introduced by pre-computed loops and such. Returns 0 if sample is too big. size_t ModSample::GetRealSampleBufferSize(SmpLength numSamples, size_t bytesPerSample) { // Number of required lookahead samples: // * 1x InterpolationMaxLookahead samples before the actual sample start. This is set to MaxSamplingPointSize due to the way AllocateSample/FreeSample currently work. // * 1x InterpolationMaxLookahead samples of silence after the sample end (if normal loop end == sample end, this can be optimized out). // * 2x InterpolationMaxLookahead before the loop point (because we start at InterpolationMaxLookahead before the loop point and will look backwards from there as well) // * 2x InterpolationMaxLookahead after the loop point (for wrap-around) // * 4x InterpolationMaxLookahead for the sustain loop (same as the two points above) const SmpLength maxSize = Util::MaxValueOfType(numSamples); const SmpLength lookaheadBufferSize = (MaxSamplingPointSize + 1 + 4 + 4) * InterpolationMaxLookahead; if(numSamples == 0 || numSamples > MAX_SAMPLE_LENGTH || lookaheadBufferSize > maxSize - numSamples) { return 0; } numSamples += lookaheadBufferSize; if(maxSize / bytesPerSample < numSamples) { return 0; } return numSamples * bytesPerSample; } void ModSample::FreeSample() { FreeSample(pSample); pSample = nullptr; } void ModSample::FreeSample(void *samplePtr) { if(samplePtr) { delete[] (((char *)samplePtr) - (InterpolationMaxLookahead * MaxSamplingPointSize)); } } // Set loop points and update loop wrap-around buffer void ModSample::SetLoop(SmpLength start, SmpLength end, bool enable, bool pingpong, CSoundFile &sndFile) { nLoopStart = start; nLoopEnd = end; LimitMax(nLoopEnd, nLength); if(nLoopStart < nLoopEnd) { uFlags.set(CHN_LOOP, enable); uFlags.set(CHN_PINGPONGLOOP, pingpong && enable); } else { nLoopStart = nLoopEnd = 0; uFlags.reset(CHN_LOOP | CHN_PINGPONGLOOP); } PrecomputeLoops(sndFile, true); } // Set sustain loop points and update loop wrap-around buffer void ModSample::SetSustainLoop(SmpLength start, SmpLength end, bool enable, bool pingpong, CSoundFile &sndFile) { nSustainStart = start; nSustainEnd = end; LimitMax(nLoopEnd, nLength); if(nSustainStart < nSustainEnd) { uFlags.set(CHN_SUSTAINLOOP, enable); uFlags.set(CHN_PINGPONGSUSTAIN, pingpong && enable); } else { nSustainStart = nSustainEnd = 0; uFlags.reset(CHN_SUSTAINLOOP | CHN_PINGPONGSUSTAIN); } PrecomputeLoops(sndFile, true); } void ModSample::PrecomputeLoops(CSoundFile &sndFile, bool updateChannels) { ctrlSmp::PrecomputeLoops(*this, sndFile, updateChannels); } // Remove loop points if they're invalid. void ModSample::SanitizeLoops() { LimitMax(nSustainEnd, nLength); LimitMax(nLoopEnd, nLength); if(nSustainStart >= nSustainEnd) { nSustainStart = nSustainEnd = 0; uFlags.reset(CHN_SUSTAINLOOP | CHN_PINGPONGSUSTAIN); } if(nLoopStart >= nLoopEnd) { nLoopStart = nLoopEnd = 0; uFlags.reset(CHN_LOOP | CHN_PINGPONGLOOP); } } ///////////////////////////////////////////////////////////// // Transpose <-> Frequency conversions uint32 ModSample::TransposeToFrequency(int transpose, int finetune) { return Util::Round(std::pow(2.0, (transpose * 128.0 + finetune) * (1.0 / (12.0 * 128.0))) * 8363.0); } void ModSample::TransposeToFrequency() { nC5Speed = TransposeToFrequency(RelativeTone, nFineTune); } // Return tranpose.finetune as 25.7 fixed point value. int ModSample::FrequencyToTranspose(uint32 freq) { return Util::Round(std::log(freq * (1.0 / 8363.0)) * (12.0 * 128.0 * (1.0 / M_LN2))); } void ModSample::FrequencyToTranspose() { int f2t; if(nC5Speed) f2t = FrequencyToTranspose(nC5Speed); else f2t = 0; int transpose = f2t >> 7; int finetune = f2t & 0x7F; //0x7F == 111 1111 if(finetune > 80) // XXX Why is this 80? { transpose++; finetune -= 128; } Limit(transpose, -127, 128); RelativeTone = static_cast(transpose); nFineTune = static_cast(finetune); } // Transpose the sample by amount specified in octaves (i.e. amount=1 transposes one octave up) void ModSample::Transpose(double amount) { nC5Speed = Util::Round(nC5Speed * std::pow(2.0, amount)); } // Check if the sample's cue points are the default cue point set. bool ModSample::HasCustomCuePoints() const { for(SmpLength i = 0; i < CountOf(cues); i++) { if(cues[i] != (i + 1) << 11) return true; } return false; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/SampleFormatMP3.cpp0000644000372100037210000002115413226427601021521 00000000000000/* * SampleFormatMP3.cpp * ------------------- * Purpose: MP3 sample import. * Notes : * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Sndfile.h" #ifndef MODPLUG_NO_FILESAVE #include "../common/mptFileIO.h" #endif #include "../common/misc_util.h" #include "Tagging.h" #include "Loaders.h" #include "ChunkReader.h" #include "modsmp_ctrl.h" #include "../soundbase/SampleFormatConverters.h" #include "../soundbase/SampleFormatCopy.h" #include "../soundlib/ModSampleCopy.h" #include "../common/ComponentManager.h" #ifdef MPT_ENABLE_MP3_SAMPLES #include "MPEGFrame.h" #endif // MPT_ENABLE_MP3_SAMPLES #if defined(MPT_WITH_MINIMP3) extern "C" { #include } #endif // MPT_WITH_MINIMP3 // mpg123 must be last because of mpg123 large file support insanity #if defined(MPT_WITH_MPG123) #include #include #include #include #endif OPENMPT_NAMESPACE_BEGIN /////////////////////////////////////////////////////////////////////////////////////////////////// // MP3 Samples #if defined(MPT_WITH_MPG123) #if MPT_COMPILER_MSVCCLANGC2 typedef _off_t mpg123_off_t; #else // !MPT_COMPILER_MSVCCLANGC2 typedef off_t mpg123_off_t; #endif // MPT_COMPILER_MSVCCLANGC2 typedef size_t mpg123_size_t; typedef ssize_t mpg123_ssize_t; class ComponentMPG123 #if defined(MPT_ENABLE_MPG123_DELAYLOAD) : public ComponentBundledDLL #else : public ComponentBuiltin #endif { MPT_DECLARE_COMPONENT_MEMBERS public: static mpg123_ssize_t FileReaderRead(void *fp, void *buf, mpg123_size_t count) { FileReader &file = *static_cast(fp); size_t readBytes = std::min(count, static_cast(file.BytesLeft())); file.ReadRaw(static_cast(buf), readBytes); return readBytes; } static mpg123_off_t FileReaderLSeek(void *fp, mpg123_off_t offset, int whence) { FileReader &file = *static_cast(fp); FileReader::off_t oldpos = file.GetPosition(); if(whence == SEEK_CUR) file.Seek(file.GetPosition() + offset); else if(whence == SEEK_END) file.Seek(file.GetLength() + offset); else file.Seek(offset); MPT_MAYBE_CONSTANT_IF(!Util::TypeCanHoldValue(file.GetPosition())) { file.Seek(oldpos); return static_cast(-1); } return static_cast(file.GetPosition()); } public: ComponentMPG123() #if defined(MPT_ENABLE_MPG123_DELAYLOAD) : ComponentBundledDLL(MPT_PATHSTRING("openmpt-mpg123")) #else : ComponentBuiltin() #endif { return; } bool DoInitialize() { #if defined(MPT_ENABLE_MPG123_DELAYLOAD) if(!ComponentBundledDLL::DoInitialize()) { return false; } #endif if(mpg123_init() != 0) { return false; } return true; } virtual ~ComponentMPG123() { if(IsAvailable()) { mpg123_exit(); } } }; MPT_REGISTERED_COMPONENT(ComponentMPG123, "Mpg123") #endif // MPT_WITH_MPG123 bool CSoundFile::ReadMP3Sample(SAMPLEINDEX sample, FileReader &file, bool mo3Decode) { #if defined(MPT_WITH_MPG123) || defined(MPT_WITH_MINIMP3) // Check file for validity, or else mpg123 will happily munch many files that start looking vaguely resemble an MPEG stream mid-file. file.Rewind(); while(file.CanRead(4)) { uint8 magic[3]; file.ReadArray(magic); if(!memcmp(magic, "ID3", 3)) { // Skip ID3 tags uint8 header[7]; file.ReadArray(header); uint32 size = 0; for(int i = 3; i < 7; i++) { if(header[i] & 0x80) return false; size = (size << 7) | header[i]; } file.Skip(size); } else if(!memcmp(magic, "APE", 3) && file.ReadMagic("TAGEX")) { // Skip APE tags uint32 size = file.ReadUint32LE(); file.Skip(16 + size); } else if(!memcmp(magic, "\x00\x00\x00", 3) || !memcmp(magic, "\xFF\x00\x00", 3)) { // Some MP3 files are padded with zeroes... } else if(magic[0] == 0) { // This might be some padding, followed by an MPEG header, so try again. file.SkipBack(2); } else if(MPEGFrame::IsMPEGHeader(magic)) { // This is what we want! break; } else { // This, on the other hand, isn't. return false; } } #endif // MPT_WITH_MPG123 || MPT_WITH_MINIMP3 #if defined(MPT_WITH_MPG123) ComponentHandle mpg123; if(!IsComponentAvailable(mpg123)) { return false; } mpg123_handle *mh; int err; if((mh = mpg123_new(0, &err)) == nullptr) { return false; } file.Rewind(); long rate; int nchannels, encoding; SmpLength length; // Set up decoder... if(mpg123_param(mh, MPG123_ADD_FLAGS, MPG123_QUIET, 0.0)) { mpg123_delete(mh); return false; } if(mpg123_replace_reader_handle(mh, ComponentMPG123::FileReaderRead, ComponentMPG123::FileReaderLSeek, 0)) { mpg123_delete(mh); return false; } if(mpg123_open_handle(mh, &file)) { mpg123_delete(mh); return false; } if(mpg123_scan(mh)) { mpg123_delete(mh); return false; } if(mpg123_getformat(mh, &rate, &nchannels, &encoding)) { mpg123_delete(mh); return false; } if(!nchannels || nchannels > 2 || (encoding & (MPG123_ENC_16 | MPG123_ENC_SIGNED)) != (MPG123_ENC_16 | MPG123_ENC_SIGNED)) { mpg123_delete(mh); return false; } length = mpg123_length(mh); if(length == 0) { mpg123_delete(mh); return false; } DestroySampleThreadsafe(sample); if(!mo3Decode) { strcpy(m_szNames[sample], ""); Samples[sample].Initialize(); Samples[sample].nC5Speed = rate; } Samples[sample].nLength = length; Samples[sample].uFlags.set(CHN_16BIT); Samples[sample].uFlags.set(CHN_STEREO, nchannels == 2); Samples[sample].AllocateSample(); if(Samples[sample].pSample != nullptr) { mpg123_size_t ndecoded = 0; mpg123_read(mh, static_cast(Samples[sample].pSample), Samples[sample].GetSampleSizeInBytes(), &ndecoded); } mpg123_delete(mh); if(!mo3Decode) { Samples[sample].Convert(MOD_TYPE_IT, GetType()); Samples[sample].PrecomputeLoops(*this, false); } return Samples[sample].pSample != nullptr; #elif defined(MPT_WITH_MINIMP3) file.Rewind(); FileReader::PinnedRawDataView rawDataView = file.GetPinnedRawDataView(); int64 bytes_left = rawDataView.size(); const uint8 *stream_pos = mpt::byte_cast(rawDataView.data()); std::vector raw_sample_data; mp3_decoder_t *mp3 = mp3_create(); int rate = 0; int channels = 0; mp3_info_t info; int frame_size = 0; do { int16 sample_buf[MP3_MAX_SAMPLES_PER_FRAME]; frame_size = mp3_decode(mp3, const_cast(stream_pos), mpt::saturate_cast(bytes_left), sample_buf, &info); // workaround lack of const qualifier in mp3_decode (all internal functions have the required const correctness) if(rate != 0 && rate != info.sample_rate) break; // inconsistent stream if(channels != 0 && channels != info.channels) break; // inconsistent stream rate = info.sample_rate; channels = info.channels; if(rate <= 0) break; // broken stream if(channels != 1 && channels != 2) break; // broken stream stream_pos += frame_size; bytes_left -= frame_size; if(info.audio_bytes >= 0) { try { raw_sample_data.insert(raw_sample_data.end(), sample_buf, sample_buf + (info.audio_bytes / sizeof(int16))); } MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e) { MPT_EXCEPTION_DELETE_OUT_OF_MEMORY(e); break; } } } while((bytes_left >= 0) && (frame_size > 0)); mp3_free(mp3); if(rate == 0 || channels == 0 || raw_sample_data.empty()) { return false; } DestroySampleThreadsafe(sample); if(!mo3Decode) { strcpy(m_szNames[sample], ""); Samples[sample].Initialize(); Samples[sample].nC5Speed = rate; } Samples[sample].nLength = mpt::saturate_cast(raw_sample_data.size() / channels); Samples[sample].uFlags.set(CHN_16BIT); Samples[sample].uFlags.set(CHN_STEREO, channels == 2); Samples[sample].AllocateSample(); if(Samples[sample].pSample != nullptr) { std::copy(raw_sample_data.begin(), raw_sample_data.end(), Samples[sample].pSample16); } if(!mo3Decode) { Samples[sample].Convert(MOD_TYPE_IT, GetType()); Samples[sample].PrecomputeLoops(*this, false); } return Samples[sample].pSample != nullptr; #else MPT_UNREFERENCED_PARAMETER(sample); MPT_UNREFERENCED_PARAMETER(file); MPT_UNREFERENCED_PARAMETER(mo3Decode); #endif // MPT_WITH_MPG123 || MPT_WITH_MINIMP3 return false; } bool CSoundFile::CanReadMP3() { bool result = false; #if defined(MPT_WITH_MPG123) if(!result) { ComponentHandle mpg123; if(IsComponentAvailable(mpg123)) { result = true; } } #endif #if defined(MPT_WITH_MINIMP3) if(!result) { result = true; } #endif #if defined(MPT_WITH_MEDIAFOUNDATION) if(!result) { if(CanReadMediaFoundation()) { result = true; } } #endif return result; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/SampleIO.h0000644000372100037210000002070613161656666017744 00000000000000/* * SampleIO.h * ---------- * Purpose: Central code for reading and writing samples. Create your SampleIO object and have a go at the ReadSample and WriteSample functions! * Notes : Not all combinations of possible sample format combinations are implemented, especially for WriteSample. * Using the existing generic sample conversion functors in SampleFormatConverters.h, it should be quite easy to extend the code, though. * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "../common/FileReaderFwd.h" OPENMPT_NAMESPACE_BEGIN struct ModSample; // Sample import / export formats class SampleIO { protected: typedef uint32 format_type; format_type format; // Internal bitmasks enum Offsets { bitOffset = 0, channelOffset = 8, endianOffset = 16, encodingOffset = 24, bitMask = 0xFF << bitOffset, channelMask = 0xFF << channelOffset, endianMask = 0xFF << endianOffset, encodingMask = 0x7F << encodingOffset, // 0xff will overflow signed 32bit int, which is the base type for an enum that fits, causing warnings when shifted }; public: // Bits per sample enum Bitdepth { _8bit = 8, _16bit = 16, _24bit = 24, _32bit = 32, _64bit = 64, }; // Number of channels + channel format enum Channels { mono = 0, stereoInterleaved, // LRLRLR... stereoSplit, // LLL...RRR... }; // Sample byte order enum Endianness { littleEndian = 0, bigEndian = 1, }; // Sample encoding enum Encoding { signedPCM = 0, // Integer PCM, signed unsignedPCM, // Integer PCM, unsigned deltaPCM, // Integer PCM, delta-encoded floatPCM, // Floating point PCM IT214, // Impulse Tracker 2.14 compressed IT215, // Impulse Tracker 2.15 compressed AMS, // AMS / Velvet Studio packed DMF, // DMF Huffman compression MDL, // MDL Huffman compression PTM8Dto16, // PTM 8-Bit delta value -> 16-Bit sample PCM7to8, // 8-Bit sample data with unused high bit ADPCM, // 4-Bit ADPCM-packed MT2, // MadTracker 2 stereo delta encoding floatPCM15, // Floating point PCM with 2^15 full scale floatPCM23, // Floating point PCM with 2^23 full scale floatPCMnormalize, // Floating point PCM and data will be normalized while reading signedPCMnormalize, // Integer PCM and data will be normalized while reading uLaw, // 8-to-16 bit G.711 u-law compression aLaw, // 8-to-16 bit G.711 a-law compression }; SampleIO(Bitdepth bits = _8bit, Channels channels = mono, Endianness endianness = littleEndian, Encoding encoding = signedPCM) { format = (bits << bitOffset) | (channels << channelOffset) | (endianness << endianOffset) | (encoding << encodingOffset); } SampleIO(const SampleIO &other) : format(other.format) { } bool operator== (const SampleIO &other) const { return format == other.format; } bool operator!= (const SampleIO &other) const { return !(*this == other); } void operator|= (Bitdepth bits) { format = (format & ~bitMask) | (bits << bitOffset); } void operator|= (Channels channels) { format = (format & ~channelMask) | (channels << channelOffset); } void operator|= (Endianness endianness) { format = (format & ~endianMask) | (endianness << endianOffset); } void operator|= (Encoding encoding) { format = (format & ~encodingMask) | (encoding << encodingOffset); } static inline Endianness GetNativeEndianness() { const mpt::endian_type endian = mpt::endian(); MPT_ASSERT((endian == mpt::endian_little) || (endian == mpt::endian_big)); Endianness result = littleEndian; MPT_MAYBE_CONSTANT_IF(endian == mpt::endian_little) { result = littleEndian; } MPT_MAYBE_CONSTANT_IF(endian == mpt::endian_big) { result = bigEndian; } return result; } void MayNormalize() { if(GetBitDepth() == 24 || GetBitDepth() == 32) { if(GetEncoding() == SampleIO::signedPCM) { (*this) |= SampleIO::signedPCMnormalize; } else if(GetEncoding() == SampleIO::floatPCM) { (*this) |= SampleIO::floatPCMnormalize; } } } // Return 0 in case of variable-length encoded samples. uint8 GetEncodedBitsPerSample() const { uint8 result = 0; switch(GetEncoding()) { case signedPCM:// Integer PCM, signed result = GetBitDepth(); break; case unsignedPCM://Integer PCM, unsigned result = GetBitDepth(); break; case deltaPCM:// Integer PCM, delta-encoded result = GetBitDepth(); break; case floatPCM:// Floating point PCM result = GetBitDepth(); break; case IT214:// Impulse Tracker 2.14 compressed result = 0; // variable-length compressed break; case IT215:// Impulse Tracker 2.15 compressed result = 0; // variable-length compressed break; case AMS:// AMS / Velvet Studio packed result = 0; // variable-length compressed break; case DMF:// DMF Huffman compression result = 0; // variable-length compressed break; case MDL:// MDL Huffman compression result = 0; // variable-length compressed break; case PTM8Dto16:// PTM 8-Bit delta value -> 16-Bit sample result = 16; break; case PCM7to8:// 8-Bit sample data with unused high bit result = 8; break; case ADPCM:// 4-Bit ADPCM-packed result = 4; break; case MT2:// MadTracker 2 stereo delta encoding result = GetBitDepth(); break; case floatPCM15:// Floating point PCM with 2^15 full scale result = GetBitDepth(); break; case floatPCM23:// Floating point PCM with 2^23 full scale result = GetBitDepth(); break; case floatPCMnormalize:// Floating point PCM and data will be normalized while reading result = GetBitDepth(); break; case signedPCMnormalize:// Integer PCM and data will be normalized while reading result = GetBitDepth(); break; case uLaw:// G.711 u-law result = 8; break; case aLaw:// G.711 a-law result = 8; break; } return result; } // Return the static header size additional to the raw encoded sample data. std::size_t GetEncodedHeaderSize() const { std::size_t result = 0; if(GetEncoding() == ADPCM) { result = 16; } return result; } // Returns true if the encoded size cannot be calculated apriori from the encoding format and the sample length. bool IsVariableLengthEncoded() const { return GetEncodedBitsPerSample() == 0; } bool UsesFileReaderForDecoding() const { if(GetEncoding() == IT214 || GetEncoding() == IT215) { // IT compressed samples use FileReader interface and thus do not need to call GetPinnedRawDataView() return true; } if(GetEncoding() == AMS || GetEncoding() == MDL) { return true; } return false; } // Get bits per sample uint8 GetBitDepth() const { return static_cast((format & bitMask) >> bitOffset); } // Get channel layout Channels GetChannelFormat() const { return static_cast((format & channelMask) >> channelOffset); } // Get number of channels uint8 GetNumChannels() const { return GetChannelFormat() == mono ? 1u : 2u; } // Get sample byte order Endianness GetEndianness() const { return static_cast((format & endianMask) >> endianOffset); } // Get sample format / encoding Encoding GetEncoding() const { return static_cast((format & encodingMask) >> encodingOffset); } // Returns the encoded size of the sample. In case of variable-length encoding returns 0. std::size_t CalculateEncodedSize(SmpLength length) const { if(IsVariableLengthEncoded()) { return 0; } if(GetEncodedBitsPerSample() % 8 != 0) { MPT_ASSERT(GetEncoding() == ADPCM && GetEncodedBitsPerSample() == 4); return GetEncodedHeaderSize() + (((length + 1) / 2) * GetNumChannels()); // round up } return GetEncodedHeaderSize() + (length * (GetEncodedBitsPerSample()/8) * GetNumChannels()); } // Read a sample from memory size_t ReadSample(ModSample &sample, FileReader &file) const; #ifndef MODPLUG_NO_FILESAVE // Optionally write a sample to file size_t WriteSample(std::ostream *f, const ModSample &sample, SmpLength maxSamples = 0) const; // Write a sample to file size_t WriteSample(std::ostream &f, const ModSample &sample, SmpLength maxSamples = 0) const; // Write a sample to file size_t WriteSample(FILE *f, const ModSample &sample, SmpLength maxSamples = 0) const; #endif // MODPLUG_NO_FILESAVE }; OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/SampleFormatMediaFoundation.cpp0000644000372100037210000003270013161656666024204 00000000000000/* * SampleFormatMediaSoundation.cpp * ------------------------------- * Purpose: MediaFoundation sample import. * Notes : * Authors: Joern Heusipp * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Sndfile.h" #ifndef MODPLUG_NO_FILESAVE #include "../common/mptFileIO.h" #endif #include "../common/misc_util.h" #include "Tagging.h" #include "Loaders.h" #include "ChunkReader.h" #include "modsmp_ctrl.h" #include "../soundbase/SampleFormatConverters.h" #include "../soundbase/SampleFormatCopy.h" #include "../soundlib/ModSampleCopy.h" #include "../common/ComponentManager.h" #if defined(MPT_WITH_MEDIAFOUNDATION) #include #include #include #include #include #include #endif // MPT_WITH_MEDIAFOUNDATION OPENMPT_NAMESPACE_BEGIN #if defined(MPT_WITH_MEDIAFOUNDATION) template static void mptMFSafeRelease(T **ppT) { if(*ppT) { (*ppT)->Release(); *ppT = NULL; } } #define MPT_MF_CHECKED(x) MPT_DO { \ HRESULT hr = (x); \ if(!SUCCEEDED(hr)) \ { \ goto fail; \ } \ } MPT_WHILE_0 // Implementing IMFByteStream is apparently not enough to stream raw bytes // data to MediaFoundation. // Additionally, one has to also implement a custom IMFAsyncResult for the // BeginRead/EndRead interface which allows transferring the number of read // bytes around. // To make things even worse, MediaFoundation fails to detect some AAC and MPEG // files if a non-file-based or read-only stream is used for opening. // The only sane option which remains if we do not have an on-disk filename // available: // 1 - write a temporary file // 2 - close it // 3 - open it using MediaFoundation. // We use FILE_ATTRIBUTE_TEMPORARY which will try to keep the file data in // memory just like regular allocated memory and reduce the overhead basically // to memcpy. static FileTags ReadMFMetadata(IMFMediaSource *mediaSource) { FileTags tags; IMFPresentationDescriptor *presentationDescriptor = NULL; DWORD streams = 0; IMFMetadataProvider *metadataProvider = NULL; IMFMetadata *metadata = NULL; PROPVARIANT varPropNames; PropVariantInit(&varPropNames); MPT_MF_CHECKED(mediaSource->CreatePresentationDescriptor(&presentationDescriptor)); MPT_MF_CHECKED(presentationDescriptor->GetStreamDescriptorCount(&streams)); MPT_MF_CHECKED(MFGetService(mediaSource, MF_METADATA_PROVIDER_SERVICE, IID_IMFMetadataProvider, (void**)&metadataProvider)); MPT_MF_CHECKED(metadataProvider->GetMFMetadata(presentationDescriptor, 0, 0, &metadata)); MPT_MF_CHECKED(metadata->GetAllPropertyNames(&varPropNames)); for(DWORD propIndex = 0; propIndex < varPropNames.calpwstr.cElems; ++propIndex) { PROPVARIANT propVal; PropVariantInit(&propVal); LPWSTR propName = varPropNames.calpwstr.pElems[propIndex]; if(S_OK != metadata->GetProperty(propName, &propVal)) { PropVariantClear(&propVal); break; } std::wstring stringVal; std::vector wcharVal(256); #if !MPT_OS_WINDOWS_WINRT // WTF, no PropVariantToString() in WinRT for(;;) { HRESULT hrToString = PropVariantToString(propVal, wcharVal.data(), mpt::saturate_cast(wcharVal.size())); if(hrToString == S_OK) { stringVal = wcharVal.data(); break; } else if(hrToString == ERROR_INSUFFICIENT_BUFFER) { wcharVal.resize(wcharVal.size() * 2); } else { break; } } #endif // !MPT_OS_WINDOWS_WINRT PropVariantClear(&propVal); if(stringVal.length() > 0) { if(propName == std::wstring(L"Author")) tags.artist = mpt::ToUnicode(stringVal); if(propName == std::wstring(L"Title")) tags.title = mpt::ToUnicode(stringVal); if(propName == std::wstring(L"WM/AlbumTitle")) tags.album = mpt::ToUnicode(stringVal); if(propName == std::wstring(L"WM/Track")) tags.trackno = mpt::ToUnicode(stringVal); if(propName == std::wstring(L"WM/Year")) tags.year = mpt::ToUnicode(stringVal); if(propName == std::wstring(L"WM/Genre")) tags.genre = mpt::ToUnicode(stringVal); } } fail: PropVariantClear(&varPropNames); mptMFSafeRelease(&metadata); mptMFSafeRelease(&metadataProvider); mptMFSafeRelease(&presentationDescriptor); return tags; } class ComponentMediaFoundation : public ComponentLibrary { MPT_DECLARE_COMPONENT_MEMBERS public: ComponentMediaFoundation() : ComponentLibrary(ComponentTypeSystem) { return; } virtual bool DoInitialize() { if(!mpt::Windows::Version::Current().IsAtLeast(mpt::Windows::Version::Win7)) { return false; } #if !MPT_OS_WINDOWS_WINRT if(!(true && AddLibrary("mf", mpt::LibraryPath::System(MPT_PATHSTRING("mf"))) && AddLibrary("mfplat", mpt::LibraryPath::System(MPT_PATHSTRING("mfplat"))) && AddLibrary("mfreadwrite", mpt::LibraryPath::System(MPT_PATHSTRING("mfreadwrite"))) && AddLibrary("propsys", mpt::LibraryPath::System(MPT_PATHSTRING("propsys"))) )) { return false; } #endif // !MPT_OS_WINDOWS_WINRT if(!SUCCEEDED(MFStartup(MF_VERSION))) { return false; } return true; } virtual ~ComponentMediaFoundation() { if(IsAvailable()) { MFShutdown(); } } }; MPT_REGISTERED_COMPONENT(ComponentMediaFoundation, "MediaFoundation") #endif // MPT_WITH_MEDIAFOUNDATION #ifdef MODPLUG_TRACKER std::vector CSoundFile::GetMediaFoundationFileTypes() { std::vector result; #if defined(MPT_WITH_MEDIAFOUNDATION) ComponentHandle mf; if(!IsComponentAvailable(mf)) { return result; } std::map guidMap; HKEY hkHandlers = NULL; LSTATUS regResult = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows Media Foundation\\ByteStreamHandlers", 0, KEY_READ, &hkHandlers); if(regResult != ERROR_SUCCESS) { return result; } for(DWORD handlerIndex = 0; ; ++handlerIndex) { WCHAR handlerTypeBuf[256]; MemsetZero(handlerTypeBuf); regResult = RegEnumKeyW(hkHandlers, handlerIndex, handlerTypeBuf, 256); if(regResult != ERROR_SUCCESS) { break; } std::wstring handlerType = handlerTypeBuf; if(handlerType.length() < 1) { continue; } HKEY hkHandler = NULL; regResult = RegOpenKeyExW(hkHandlers, handlerTypeBuf, 0, KEY_READ, &hkHandler); if(regResult != ERROR_SUCCESS) { continue; } for(DWORD valueIndex = 0; ; ++valueIndex) { WCHAR valueNameBuf[16384]; MemsetZero(valueNameBuf); DWORD valueNameBufLen = 16384; DWORD valueType = 0; BYTE valueData[16384]; MemsetZero(valueData); DWORD valueDataLen = 16384; regResult = RegEnumValueW(hkHandler, valueIndex, valueNameBuf, &valueNameBufLen, NULL, &valueType, valueData, &valueDataLen); if(regResult != ERROR_SUCCESS) { break; } if(valueNameBufLen <= 0 || valueType != REG_SZ || valueDataLen <= 0) { continue; } std::wstring guid = std::wstring(valueNameBuf); mpt::ustring description = mpt::ToUnicode(std::wstring(reinterpret_cast(valueData))); description = mpt::String::Replace(description, MPT_USTRING("Byte Stream Handler"), MPT_USTRING("Files")); description = mpt::String::Replace(description, MPT_USTRING("ByteStreamHandler"), MPT_USTRING("Files")); guidMap[guid] .ShortName(MPT_USTRING("mf")) .Description(description) ; if(handlerType[0] == L'.') { guidMap[guid].AddExtension(mpt::PathString::FromWide(handlerType.substr(1))); } else { guidMap[guid].AddMimeType(mpt::ToCharset(mpt::CharsetASCII, handlerType)); } } RegCloseKey(hkHandler); hkHandler = NULL; } RegCloseKey(hkHandlers); hkHandlers = NULL; for(const auto &it : guidMap) { result.push_back(it.second); } #endif // MPT_WITH_MEDIAFOUNDATION return result; } #endif // MODPLUG_TRACKER bool CSoundFile::ReadMediaFoundationSample(SAMPLEINDEX sample, FileReader &file, bool mo3Decode) { #if !defined(MPT_WITH_MEDIAFOUNDATION) MPT_UNREFERENCED_PARAMETER(sample); MPT_UNREFERENCED_PARAMETER(file); MPT_UNREFERENCED_PARAMETER(mo3Decode); return false; #else ComponentHandle mf; if(!IsComponentAvailable(mf)) { return false; } file.Rewind(); // When using MF to decode MP3 samples in MO3 files, we need the mp3 file extension // for some of them or otherwise MF refuses to recognize them. mpt::PathString tmpfileExtension = (mo3Decode ? MPT_PATHSTRING("mp3") : MPT_PATHSTRING("tmp")); OnDiskFileWrapper diskfile(file, tmpfileExtension); if(!diskfile.IsValid()) { return false; } bool result = false; std::vector rawData; FileTags tags; std::string sampleName; IMFSourceResolver *sourceResolver = NULL; MF_OBJECT_TYPE objectType = MF_OBJECT_INVALID; IUnknown *unknownMediaSource = NULL; IMFMediaSource *mediaSource = NULL; IMFSourceReader *sourceReader = NULL; IMFMediaType *uncompressedAudioType = NULL; IMFMediaType *partialType = NULL; UINT32 numChannels = 0; UINT32 samplesPerSecond = 0; UINT32 bitsPerSample = 0; IMFSample *mfSample = NULL; DWORD mfSampleFlags = 0; IMFMediaBuffer *buffer = NULL; SmpLength length = 0; MPT_MF_CHECKED(MFCreateSourceResolver(&sourceResolver)); MPT_MF_CHECKED(sourceResolver->CreateObjectFromURL(diskfile.GetFilename().AsNative().c_str(), MF_RESOLUTION_MEDIASOURCE | MF_RESOLUTION_CONTENT_DOES_NOT_HAVE_TO_MATCH_EXTENSION_OR_MIME_TYPE | MF_RESOLUTION_READ, NULL, &objectType, &unknownMediaSource)); if(objectType != MF_OBJECT_MEDIASOURCE) goto fail; MPT_MF_CHECKED(unknownMediaSource->QueryInterface(&mediaSource)); tags = ReadMFMetadata(mediaSource); MPT_MF_CHECKED(MFCreateSourceReaderFromMediaSource(mediaSource, NULL, &sourceReader)); MPT_MF_CHECKED(MFCreateMediaType(&partialType)); MPT_MF_CHECKED(partialType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio)); MPT_MF_CHECKED(partialType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_PCM)); MPT_MF_CHECKED(sourceReader->SetCurrentMediaType((DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM, NULL, partialType)); MPT_MF_CHECKED(sourceReader->GetCurrentMediaType((DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM, &uncompressedAudioType)); MPT_MF_CHECKED(sourceReader->SetStreamSelection((DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM, TRUE)); MPT_MF_CHECKED(uncompressedAudioType->GetUINT32(MF_MT_AUDIO_NUM_CHANNELS, &numChannels)); MPT_MF_CHECKED(uncompressedAudioType->GetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, &samplesPerSecond)); MPT_MF_CHECKED(uncompressedAudioType->GetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, &bitsPerSample)); if(numChannels <= 0 || numChannels > 2) goto fail; if(samplesPerSecond <= 0) goto fail; if(bitsPerSample != 8 && bitsPerSample != 16 && bitsPerSample != 24 && bitsPerSample != 32) goto fail; for(;;) { mfSampleFlags = 0; MPT_MF_CHECKED(sourceReader->ReadSample((DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, NULL, &mfSampleFlags, NULL, &mfSample)); if(mfSampleFlags & MF_SOURCE_READERF_CURRENTMEDIATYPECHANGED) { break; } if(mfSampleFlags & MF_SOURCE_READERF_ENDOFSTREAM) { break; } MPT_MF_CHECKED(mfSample->ConvertToContiguousBuffer(&buffer)); { BYTE *data = NULL; DWORD dataSize = 0; MPT_MF_CHECKED(buffer->Lock(&data, NULL, &dataSize)); rawData.insert(rawData.end(), mpt::byte_cast(data), mpt::byte_cast(data + dataSize)); MPT_MF_CHECKED(buffer->Unlock()); } mptMFSafeRelease(&buffer); mptMFSafeRelease(&mfSample); } mptMFSafeRelease(&uncompressedAudioType); mptMFSafeRelease(&partialType); mptMFSafeRelease(&sourceReader); sampleName = mpt::ToCharset(GetCharsetInternal(), GetSampleNameFromTags(tags)); if(rawData.size() / numChannels / (bitsPerSample / 8) > MAX_SAMPLE_LENGTH) { result = false; goto fail; } length = static_cast(rawData.size() / numChannels / (bitsPerSample/8)); DestroySampleThreadsafe(sample); if(!mo3Decode) { mpt::String::Copy(m_szNames[sample], sampleName); Samples[sample].Initialize(); Samples[sample].nC5Speed = samplesPerSecond; } Samples[sample].nLength = length; Samples[sample].uFlags.set(CHN_16BIT, bitsPerSample >= 16); Samples[sample].uFlags.set(CHN_STEREO, numChannels == 2); Samples[sample].AllocateSample(); if(Samples[sample].pSample == nullptr) { result = false; goto fail; } if(bitsPerSample == 24) { if(numChannels == 2) { CopyStereoInterleavedSample, SC::DecodeInt24<0, littleEndian24> > >(Samples[sample], rawData.data(), rawData.size()); } else { CopyMonoSample, SC::DecodeInt24<0, littleEndian24> > >(Samples[sample], rawData.data(), rawData.size()); } } else if(bitsPerSample == 32) { if(numChannels == 2) { CopyStereoInterleavedSample, SC::DecodeInt32<0, littleEndian32> > >(Samples[sample], rawData.data(), rawData.size()); } else { CopyMonoSample, SC::DecodeInt32<0, littleEndian32> > >(Samples[sample], rawData.data(), rawData.size()); } } else { // just copy std::copy(rawData.data(), rawData.data() + rawData.size(), mpt::void_cast(Samples[sample].pSample)); } result = true; fail: mptMFSafeRelease(&buffer); mptMFSafeRelease(&mfSample); mptMFSafeRelease(&uncompressedAudioType); mptMFSafeRelease(&partialType); mptMFSafeRelease(&sourceReader); mptMFSafeRelease(&mediaSource); mptMFSafeRelease(&unknownMediaSource); mptMFSafeRelease(&sourceResolver); return result; #endif } bool CSoundFile::CanReadMediaFoundation() { bool result = false; #if defined(MPT_WITH_MEDIAFOUNDATION) if(!result) { ComponentHandle mf; if(IsComponentAvailable(mf)) { result = true; } } #endif return result; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Load_stm.cpp0000644000372100037210000002326013233626144020352 00000000000000/* * Load_stm.cpp * ------------ * Purpose: STM (ScreamTracker 2) module loader * Notes : (currently none) * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" OPENMPT_NAMESPACE_BEGIN // STM sample header struct struct STMSampleHeader { char filename[12]; // Can't have long comments - just filename comments :) uint8le zero; uint8le disk; // A blast from the past uint16le offset; // 20-bit offset in file (lower 4 bits are zero) uint16le length; // Sample length uint16le loopStart; // Loop start point uint16le loopEnd; // Loop end point uint8le volume; // Volume uint8le reserved2; uint16le sampleRate; uint8le reserved3[6]; // Convert an STM sample header to OpenMPT's internal sample header. void ConvertToMPT(ModSample &mptSmp) const { mptSmp.Initialize(); mpt::String::Read(mptSmp.filename, filename); mptSmp.nC5Speed = sampleRate; mptSmp.nVolume = std::min(volume, 64) * 4; mptSmp.nLength = length; mptSmp.nLoopStart = loopStart; mptSmp.nLoopEnd = loopEnd; if(mptSmp.nLength < 2) mptSmp.nLength = 0; if(mptSmp.nLoopStart < mptSmp.nLength && mptSmp.nLoopEnd > mptSmp.nLoopStart && mptSmp.nLoopEnd != 0xFFFF) { mptSmp.uFlags = CHN_LOOP; mptSmp.nLoopEnd = std::min(mptSmp.nLoopEnd, mptSmp.nLength); } } }; MPT_BINARY_STRUCT(STMSampleHeader, 32) // STM file header struct STMFileHeader { char songname[20]; char trackername[8]; // !Scream! for ST 2.xx uint8 dosEof; // 0x1A uint8 filetype; // 1=song, 2=module (only 2 is supported, of course) :) uint8 verMajor; uint8 verMinor; uint8 initTempo; // Ticks per row. Keep in mind that effects are only updated on every 16th tick. uint8 numPatterns; // number of patterns uint8 globalVolume; uint8 reserved[13]; }; MPT_BINARY_STRUCT(STMFileHeader, 48) static bool ValidateHeader(const STMFileHeader &fileHeader) { // NOTE: Historically the magic byte check used to be case-insensitive. // Other libraries (mikmod, xmp, Milkyplay) don't do this. // ScreamTracker 2 and 3 do not care about the content of the magic bytes at all. // After reviewing all STM files on ModLand and ModArchive, it was found that the // case-insensitive comparison is most likely not necessary for any files in the wild. if(fileHeader.filetype != 2 || (fileHeader.dosEof != 0x1A && fileHeader.dosEof != 2) // ST2 ignores this, ST3 doesn't. putup10.stm / putup11.stm have dosEof = 2. || fileHeader.verMajor != 2 || fileHeader.verMinor > 21 // ST3 only accepts 0, 10, 20 and 21 || fileHeader.globalVolume > 64 || (std::memcmp(fileHeader.trackername, "!Scream!", 8) && std::memcmp(fileHeader.trackername, "BMOD2STM", 8) && std::memcmp(fileHeader.trackername, "WUZAMOD!", 8)) ) { return false; } return true; } static uint64 GetHeaderMinimumAdditionalSize(const STMFileHeader &fileHeader) { return 31 * sizeof(STMSampleHeader) + (fileHeader.verMinor == 0 ? 64 : 128) + fileHeader.numPatterns * 64 * 4; } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderSTM(MemoryFileReader file, const uint64 *pfilesize) { STMFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return ProbeWantMoreData; } if(!ValidateHeader(fileHeader)) { return ProbeFailure; } return ProbeAdditionalSize(file, pfilesize, GetHeaderMinimumAdditionalSize(fileHeader)); } bool CSoundFile::ReadSTM(FileReader &file, ModLoadingFlags loadFlags) { file.Rewind(); STMFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return false; } if(!ValidateHeader(fileHeader)) { return false; } if(!file.CanRead(mpt::saturate_cast(GetHeaderMinimumAdditionalSize(fileHeader)))) { return false; } if(loadFlags == onlyVerifyHeader) { return true; } InitializeGlobals(MOD_TYPE_STM); mpt::String::Read(m_songName, fileHeader.songname); // Read STM header m_madeWithTracker = mpt::format(MPT_USTRING("Scream Tracker %1.%2"))(fileHeader.verMajor, mpt::ufmt::dec0<2>(fileHeader.verMinor)); m_nSamples = 31; m_nChannels = 4; m_nMinPeriod = 64; m_nMaxPeriod = 0x7FFF; uint8 initTempo = fileHeader.initTempo; if(fileHeader.verMinor < 21) initTempo = ((initTempo / 10u) << 4u) + initTempo % 10u; if(initTempo == 0) initTempo = 0x60; m_nDefaultTempo = ConvertST2Tempo(initTempo); m_nDefaultSpeed = initTempo >> 4; if(fileHeader.verMinor > 10) m_nDefaultGlobalVolume = fileHeader.globalVolume * 4u; // Setting up channels for(CHANNELINDEX chn = 0; chn < 4; chn++) { ChnSettings[chn].Reset(); ChnSettings[chn].nPan = (chn & 1) ? 0x40 : 0xC0; } // Read samples uint16 sampleOffsets[31]; for(SAMPLEINDEX smp = 1; smp <= 31; smp++) { STMSampleHeader sampleHeader; file.ReadStruct(sampleHeader); if(sampleHeader.zero != 0 && sampleHeader.zero != 46) // putup10.stm has zero = 46 return false; sampleHeader.ConvertToMPT(Samples[smp]); mpt::String::Read(m_szNames[smp], sampleHeader.filename); sampleOffsets[smp - 1] = sampleHeader.offset; } // Read order list ReadOrderFromFile(Order(), file, fileHeader.verMinor == 0 ? 64 : 128); for(auto &pat : Order()) { if(pat == 99 || pat == 255) // 99 is regular, sometimes a single 255 entry can be found too pat = Order.GetInvalidPatIndex(); else if(pat > 99) return false; } if(loadFlags & loadPatternData) Patterns.ResizeArray(fileHeader.numPatterns); for(PATTERNINDEX pat = 0; pat < fileHeader.numPatterns; pat++) { if(!(loadFlags & loadPatternData) || !Patterns.Insert(pat, 64)) { for(int i = 0; i < 64 * 4; i++) { uint8 note = file.ReadUint8(); if(note < 0xFB || note > 0xFD) file.Skip(3); } continue; } auto m = Patterns[pat].begin(); ORDERINDEX breakPos = ORDERINDEX_INVALID; ROWINDEX breakRow = 63; // Candidate row for inserting pattern break for(int i = 0; i < 64 * 4; i++, m++) { uint8 note = file.ReadUint8(), insvol, volcmd, cmdinf; switch(note) { case 0xFB: note = insvol = volcmd = cmdinf = 0x00; break; case 0xFC: continue; case 0xFD: m->note = NOTE_NOTECUT; continue; default: insvol = file.ReadUint8(); volcmd = file.ReadUint8(); cmdinf = file.ReadUint8(); break; } if(note == 0xFE) m->note = NOTE_NOTECUT; else if(note < 0x60) m->note = (note >> 4) * 12 + (note & 0x0F) + 36 + NOTE_MIN; m->instr = insvol >> 3; if(m->instr > 31) { m->instr = 0; } uint8 vol = (insvol & 0x07) | ((volcmd & 0xF0) >> 1); if(vol <= 64) { m->volcmd = VOLCMD_VOLUME; m->vol = vol; } static const EffectCommand stmEffects[] = { CMD_NONE, CMD_SPEED, CMD_POSITIONJUMP, CMD_PATTERNBREAK, // .ABC CMD_VOLUMESLIDE, CMD_PORTAMENTODOWN, CMD_PORTAMENTOUP, CMD_TONEPORTAMENTO, // DEFG CMD_VIBRATO, CMD_TREMOR, CMD_ARPEGGIO, CMD_NONE, // HIJK CMD_NONE, CMD_NONE, CMD_NONE, CMD_NONE, // LMNO // KLMNO can be entered in the editor but don't do anything }; m->command = stmEffects[volcmd & 0x0F]; m->param = cmdinf; switch(m->command) { case CMD_VOLUMESLIDE: // Lower nibble always has precedence, and there are no fine slides. if(m->param & 0x0F) m->param &= 0x0F; else m->param &= 0xF0; break; case CMD_PATTERNBREAK: m->param = (m->param & 0xF0) * 10 + (m->param & 0x0F); if(breakRow > m->param) { breakRow = m->param; } break; case CMD_POSITIONJUMP: // This effect is also very weird. // Bxx doesn't appear to cause an immediate break -- it merely // sets the next order for when the pattern ends (either by // playing it all the way through, or via Cxx effect) breakPos = m->param; breakRow = 63; m->command = CMD_NONE; break; case CMD_TREMOR: // this actually does something with zero values, and has no // effect memory. which makes SENSE for old-effects tremor, // but ST3 went and screwed it all up by adding an effect // memory and IT followed that, and those are much more popular // than STM so we kind of have to live with this effect being // broken... oh well. not a big loss. break; case CMD_SPEED: if(fileHeader.verMinor < 21) { m->param = ((m->param / 10u) << 4u) + m->param % 10u; } #ifdef MODPLUG_TRACKER // ST2 has a very weird tempo mode where the length of a tick depends both // on the ticks per row and a scaling factor. This is probably the closest // we can get with S3M-like semantics. m->param >>= 4; #endif // MODPLUG_TRACKER MPT_FALLTHROUGH; default: // Anything not listed above is a no-op if there's no value. // (ST2 doesn't have effect memory) if(!m->param) { m->command = CMD_NONE; } break; } } if(breakPos != ORDERINDEX_INVALID) { Patterns[pat].WriteEffect(EffectWriter(CMD_POSITIONJUMP, static_cast(breakPos)).Row(breakRow).RetryPreviousRow()); } } // Reading Samples if(loadFlags & loadSampleData) { const SampleIO sampleIO( SampleIO::_8bit, SampleIO::mono, SampleIO::littleEndian, SampleIO::signedPCM); for(SAMPLEINDEX smp = 1; smp <= 31; smp++) { ModSample &sample = Samples[smp]; // ST2 just plays random noise for samples with a default volume of 0 if(sample.nLength && sample.nVolume > 0) { FileReader::off_t sampleOffset = sampleOffsets[smp - 1] << 4; // acidlamb.stm has some bogus samples with sample offsets past EOF if(sampleOffset > sizeof(STMFileHeader) && file.Seek(sampleOffset)) { sampleIO.ReadSample(sample, file); } } } } return true; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Dither.cpp0000644000372100037210000001404213161656666020041 00000000000000/* * Dither.cpp * ---------- * Purpose: Dithering when converting to lower resolution sample formats. * Notes : (currently none) * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Dither.h" #include "Mixer.h" #include "../common/misc_util.h" OPENMPT_NAMESPACE_BEGIN ////////////////////////////////////////////////////////////////////////// // Noise Shaping (Dithering) mpt::ustring Dither::GetModeName(DitherMode mode) { switch(mode) { case DitherNone : return MPT_USTRING("no" ); break; case DitherDefault: return MPT_USTRING("default"); break; case DitherModPlug: return MPT_USTRING("0.5 bit"); break; case DitherSimple : return MPT_USTRING("1 bit" ); break; default : return MPT_USTRING("" ); break; } } #if MPT_COMPILER_MSVC #pragma warning(disable:4731) // ebp modified #endif #ifdef ENABLE_X86 void X86_Dither(int *pBuffer, uint32 nSamples, uint32 nBits, DitherModPlugState *state) { if(nBits + MIXING_ATTENUATION + 1 >= 32) //if(nBits>16) { return; } static int gDitherA_global, gDitherB_global; int gDitherA = state ? state->rng_a : gDitherA_global; int gDitherB = state ? state->rng_b : gDitherB_global; _asm { mov esi, pBuffer // esi = pBuffer+i mov eax, nSamples // ebp = i mov ecx, nBits // ecx = number of bits of noise mov edi, gDitherA // Noise generation mov ebx, gDitherB add ecx, MIXING_ATTENUATION+1 push ebp mov ebp, eax noiseloop: rol edi, 1 mov eax, dword ptr [esi] xor edi, 0x10204080 add esi, 4 lea edi, [ebx*4+edi+0x78649E7D] mov edx, edi rol edx, 16 lea edx, [edx*4+edx] add ebx, edx mov edx, ebx sar edx, cl add eax, edx dec ebp mov dword ptr [esi-4], eax jnz noiseloop pop ebp mov gDitherA, edi mov gDitherB, ebx } if(state) state->rng_a = gDitherA; else gDitherA_global = gDitherA; if(state) state->rng_b = gDitherB; else gDitherB_global = gDitherB; } #endif // ENABLE_X86 static MPT_FORCEINLINE int32 dither_rand(uint32 &a, uint32 &b) { a = (a << 1) | (a >> 31); a ^= 0x10204080u; a += 0x78649E7Du + (b * 4); b += ((a << 16 ) | (a >> 16)) * 5; return static_cast(b); } static void C_Dither(int *pBuffer, std::size_t count, uint32 nBits, DitherModPlugState *state) { if(nBits + MIXING_ATTENUATION + 1 >= 32) //if(nBits>16) { return; } static uint32 global_a = 0; static uint32 global_b = 0; uint32 a = state ? state->rng_a : global_a; uint32 b = state ? state->rng_b : global_b; while(count--) { *pBuffer += dither_rand(a, b) >> (nBits + MIXING_ATTENUATION + 1); pBuffer++; } if(state) state->rng_a = a; else global_a = a; if(state) state->rng_b = b; else global_b = b; } static void Dither_ModPlug(int *pBuffer, std::size_t count, std::size_t channels, uint32 nBits, DitherModPlugState &state) { #ifdef ENABLE_X86 X86_Dither(pBuffer, count * channels, nBits, &state); #else // !ENABLE_X86 C_Dither(pBuffer, count * channels, nBits, &state); #endif // ENABLE_X86 } template struct Dither_SimpleTemplate { MPT_NOINLINE void operator () (int *mixbuffer, std::size_t count, DitherSimpleState &state, mpt::fast_prng &prng) { STATIC_ASSERT(sizeof(int) == 4); const int rshift = (32-targetbits) - MIXING_ATTENUATION; MPT_CONSTANT_IF(rshift <= 0) { // nothing to dither return; } const int round_mask = ~((1<(prng, noise_bits) + mpt::random(prng, noise_bits)) >> 1; } else { unoise = mpt::random(prng, noise_bits); } int noise = static_cast(unoise) - noise_bias; // un-bias int val = *mixbuffer; MPT_CONSTANT_IF(shaped) { val += (s.error[channel] >> 1); } int rounded = (val + noise + round_offset) & round_mask;; s.error[channel] = val - rounded; *mixbuffer = rounded; mixbuffer++; } } state = s; } }; static void Dither_Simple(int *mixbuffer, std::size_t count, std::size_t channels, int bits, DitherSimpleState &state, mpt::fast_prng &prng) { switch(bits) { case 8: switch(channels) { case 1: Dither_SimpleTemplate<8,1>()(mixbuffer, count, state, prng); break; case 2: Dither_SimpleTemplate<8,2>()(mixbuffer, count, state, prng); break; case 4: Dither_SimpleTemplate<8,4>()(mixbuffer, count, state, prng); break; } break; case 16: switch(channels) { case 1: Dither_SimpleTemplate<16,1>()(mixbuffer, count, state, prng); break; case 2: Dither_SimpleTemplate<16,2>()(mixbuffer, count, state, prng); break; case 4: Dither_SimpleTemplate<16,4>()(mixbuffer, count, state, prng); break; } break; case 24: switch(channels) { case 1: Dither_SimpleTemplate<24,1>()(mixbuffer, count, state, prng); break; case 2: Dither_SimpleTemplate<24,2>()(mixbuffer, count, state, prng); break; case 4: Dither_SimpleTemplate<24,4>()(mixbuffer, count, state, prng); break; } break; } } void Dither::Reset() { state.Reset(); } void Dither::SetMode(DitherMode mode_) { mode = mode_; } DitherMode Dither::GetMode() const { return mode; } void Dither::Process(int *mixbuffer, std::size_t count, std::size_t channels, int bits) { switch(mode) { case DitherNone: // nothing break; case DitherModPlug: Dither_ModPlug(mixbuffer, count, channels, bits, state.modplug); break; case DitherSimple: Dither_Simple(mixbuffer, count, channels, bits, state.simple, state.prng); break; case DitherDefault: default: Dither_ModPlug(mixbuffer, count, channels, bits, state.modplug); break; } } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Snd_flt.cpp0000644000372100037210000001110413161656666020207 00000000000000/* * snd_flt.cpp * ----------- * Purpose: Calculation of resonant filter coefficients. * Notes : Extended filter range was introduced in MPT 1.12 and went up to 8652 Hz. * MPT 1.16 upped this to the current 10670 Hz. * We have no way of telling whether a file was made with MPT 1.12 or 1.16 though. * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Sndfile.h" #include "Tables.h" #include "../common/misc_util.h" OPENMPT_NAMESPACE_BEGIN // AWE32: cutoff = reg[0-255] * 31.25 + 100 -> [100Hz-8060Hz] // EMU10K1 docs: cutoff = reg[0-127]*62+100 uint8 CSoundFile::FrequencyToCutOff(double frequency) const { // IT Cutoff is computed as cutoff = 110 * 2 ^ (0.25 + x/y), where x is the cutoff and y defines the filter range. // Reversed, this gives us x = (log2(cutoff / 110) - 0.25) * y. // <==========> Rewrite as x = (log2(cutoff) - log2(110) - 0.25) * y. // <==========> Rewrite as x = (ln(cutoff) - ln(110) - 0.25*ln(2)) * y/ln(2). // <4.8737671609324025> double cutoff = (std::log(frequency) - 4.8737671609324025) * (m_SongFlags[SONG_EXFILTERRANGE] ? (20.0 / M_LN2) : (24.0 / M_LN2)); Limit(cutoff, 0.0, 127.0); return Util::Round(cutoff); } uint32 CSoundFile::CutOffToFrequency(uint32 nCutOff, int flt_modifier) const { MPT_ASSERT(nCutOff < 128); float Fc = 110.0f * std::pow(2.0f, 0.25f + ((float)(nCutOff * (flt_modifier + 256))) / (m_SongFlags[SONG_EXFILTERRANGE] ? 20.0f * 512.0f : 24.0f * 512.0f)); int freq = Util::Round(Fc); Limit(freq, 120, 20000); if (freq * 2 > (int)m_MixerSettings.gdwMixingFreq) freq = m_MixerSettings.gdwMixingFreq / 2; return static_cast(freq); } // Simple 2-poles resonant filter void CSoundFile::SetupChannelFilter(ModChannel *pChn, bool bReset, int flt_modifier) const { int cutoff = (int)pChn->nCutOff + (int)pChn->nCutSwing; int resonance = (int)(pChn->nResonance & 0x7F) + (int)pChn->nResSwing; Limit(cutoff, 0, 127); Limit(resonance, 0, 127); if(!m_playBehaviour[kMPTOldSwingBehaviour]) { pChn->nCutOff = (uint8)cutoff; pChn->nCutSwing = 0; pChn->nResonance = (uint8)resonance; pChn->nResSwing = 0; } // flt_modifier is in [-256, 256], so cutoff is in [0, 127 * 2] after this calculation. const int computedCutoff = cutoff * (flt_modifier + 256) / 256; // Filtering is only ever done in IT if either cutoff is not full or if resonance is set. if(m_playBehaviour[kITFilterBehaviour] && resonance == 0 && computedCutoff >= 254) { if(pChn->rowCommand.IsNote() && !pChn->rowCommand.IsPortamento() && !pChn->nMasterChn && m_SongFlags[SONG_FIRSTTICK]) { // Z7F next to a note disables the filter, however in other cases this should not happen. // Test cases: filter-reset.it, filter-reset-carry.it, filter-nna.it pChn->dwFlags.reset(CHN_FILTER); } return; } pChn->dwFlags.set(CHN_FILTER); // 2 * damping factor const float dmpfac = std::pow(10.0f, -resonance * ((24.0f / 128.0f) / 20.0f)); const float fc = CutOffToFrequency(cutoff, flt_modifier) * (2.0f * (float)M_PI); float d, e; if(m_playBehaviour[kITFilterBehaviour] && !m_SongFlags[SONG_EXFILTERRANGE]) { const float r = m_MixerSettings.gdwMixingFreq / fc; d = dmpfac * r + dmpfac - 1.0f; e = r * r; } else { const float r = fc / m_MixerSettings.gdwMixingFreq; d = (1.0f - 2.0f * dmpfac) * r; LimitMax(d, 2.0f); d = (2.0f * dmpfac - d) / r; e = 1.0f / (r * r); } float fg = 1.0f / (1.0f + d + e); float fb0 = (d + e + e) / (1 + d + e); float fb1 = -e / (1.0f + d + e); #if defined(MPT_INTMIXER) #define FILTER_CONVERT(x) Util::Round((x) * (1 << MIXING_FILTER_PRECISION)) #else #define FILTER_CONVERT(x) (x) #endif switch(pChn->nFilterMode) { case FLTMODE_HIGHPASS: pChn->nFilter_A0 = FILTER_CONVERT(1.0f - fg); pChn->nFilter_B0 = FILTER_CONVERT(fb0); pChn->nFilter_B1 = FILTER_CONVERT(fb1); #ifdef MPT_INTMIXER pChn->nFilter_HP = -1; #else pChn->nFilter_HP = 1.0f; #endif // MPT_INTMIXER break; default: pChn->nFilter_A0 = FILTER_CONVERT(fg); pChn->nFilter_B0 = FILTER_CONVERT(fb0); pChn->nFilter_B1 = FILTER_CONVERT(fb1); #ifdef MPT_INTMIXER if(pChn->nFilter_A0 == 0) pChn->nFilter_A0 = 1; // Prevent silence at low filter cutoff and very high sampling rate pChn->nFilter_HP = 0; #else pChn->nFilter_HP = 0; #endif // MPT_INTMIXER break; } #undef FILTER_CONVERT if (bReset) { pChn->nFilter_Y[0][0] = pChn->nFilter_Y[0][1] = 0; pChn->nFilter_Y[1][0] = pChn->nFilter_Y[1][1] = 0; } } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/SampleFormatVorbis.cpp0000644000372100037210000002156213161656666022406 00000000000000/* * SampleFormatVorbis.cpp * ---------------------- * Purpose: Vorbis sample import * Notes : * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Sndfile.h" #ifndef MODPLUG_NO_FILESAVE #include "../common/mptFileIO.h" #endif #include "../common/misc_util.h" #include "Tagging.h" #include "Loaders.h" #include "ChunkReader.h" #include "modsmp_ctrl.h" #include "../soundbase/SampleFormatConverters.h" #include "../soundbase/SampleFormatCopy.h" #include "../soundlib/ModSampleCopy.h" //#include "../common/mptCRC.h" #include "OggStream.h" #ifdef MPT_WITH_OGG #include #endif // MPT_WITH_OGG #if defined(MPT_WITH_VORBIS) #include #endif #if defined(MPT_WITH_VORBISFILE) #include #endif #ifdef MPT_WITH_STBVORBIS #include #endif // MPT_WITH_STBVORBIS OPENMPT_NAMESPACE_BEGIN //////////////////////////////////////////////////////////////////////////////// // Vorbis #if defined(MPT_WITH_VORBISFILE) static size_t VorbisfileFilereaderRead(void *ptr, size_t size, size_t nmemb, void *datasource) { FileReader &file = *reinterpret_cast(datasource); return file.ReadRaw(mpt::void_cast(ptr), size * nmemb) / size; } static int VorbisfileFilereaderSeek(void *datasource, ogg_int64_t offset, int whence) { FileReader &file = *reinterpret_cast(datasource); switch(whence) { case SEEK_SET: { if(!Util::TypeCanHoldValue(offset)) { return -1; } return file.Seek(mpt::saturate_cast(offset)) ? 0 : -1; } break; case SEEK_CUR: { if(offset < 0) { if(offset == std::numeric_limits::min()) { return -1; } if(!Util::TypeCanHoldValue(0-offset)) { return -1; } return file.SkipBack(mpt::saturate_cast(0 - offset)) ? 0 : -1; } else { if(!Util::TypeCanHoldValue(offset)) { return -1; } return file.Skip(mpt::saturate_cast(offset)) ? 0 : -1; } } break; case SEEK_END: { if(!Util::TypeCanHoldValue(offset)) { return -1; } if(!Util::TypeCanHoldValue(file.GetLength() + offset)) { return -1; } return file.Seek(mpt::saturate_cast(file.GetLength() + offset)) ? 0 : -1; } break; default: return -1; } } static long VorbisfileFilereaderTell(void *datasource) { FileReader &file = *reinterpret_cast(datasource); MPT_MAYBE_CONSTANT_IF(!Util::TypeCanHoldValue(file.GetPosition())) { return -1; } return static_cast(file.GetPosition()); } #if defined(MPT_WITH_VORBIS) static mpt::ustring UStringFromVorbis(const char *str) { return str ? mpt::ToUnicode(mpt::CharsetUTF8, str) : mpt::ustring(); } #endif // MPT_WITH_VORBIS static FileTags GetVorbisFileTags(OggVorbis_File &vf) { FileTags tags; #if defined(MPT_WITH_VORBIS) vorbis_comment *vc = ov_comment(&vf, -1); if(!vc) { return tags; } tags.encoder = UStringFromVorbis(vorbis_comment_query(vc, "ENCODER", 0)); tags.title = UStringFromVorbis(vorbis_comment_query(vc, "TITLE", 0)); tags.comments = UStringFromVorbis(vorbis_comment_query(vc, "DESCRIPTION", 0)); tags.bpm = UStringFromVorbis(vorbis_comment_query(vc, "BPM", 0)); // non-standard tags.artist = UStringFromVorbis(vorbis_comment_query(vc, "ARTIST", 0)); tags.album = UStringFromVorbis(vorbis_comment_query(vc, "ALBUM", 0)); tags.trackno = UStringFromVorbis(vorbis_comment_query(vc, "TRACKNUMBER", 0)); tags.year = UStringFromVorbis(vorbis_comment_query(vc, "DATE", 0)); tags.url = UStringFromVorbis(vorbis_comment_query(vc, "CONTACT", 0)); tags.genre = UStringFromVorbis(vorbis_comment_query(vc, "GENRE", 0)); #else // !MPT_WITH_VORBIS MPT_UNREFERENCED_PARAMETER(vf); #endif // MPT_WITH_VORBIS return tags; } #endif // MPT_WITH_VORBISFILE bool CSoundFile::ReadVorbisSample(SAMPLEINDEX sample, FileReader &file) { #if defined(MPT_WITH_VORBISFILE) || defined(MPT_WITH_STBVORBIS) file.Rewind(); int rate = 0; int channels = 0; std::vector raw_sample_data; std::string sampleName; #endif // VORBIS #if defined(MPT_WITH_VORBISFILE) bool unsupportedSample = false; ov_callbacks callbacks = { &VorbisfileFilereaderRead, &VorbisfileFilereaderSeek, NULL, &VorbisfileFilereaderTell }; OggVorbis_File vf; MemsetZero(vf); if(ov_open_callbacks(&file, &vf, NULL, 0, callbacks) == 0) { if(ov_streams(&vf) == 1) { // we do not support chained vorbis samples vorbis_info *vi = ov_info(&vf, -1); if(vi && vi->rate > 0 && vi->channels > 0) { sampleName = mpt::ToCharset(GetCharsetInternal(), GetSampleNameFromTags(GetVorbisFileTags(vf))); rate = vi->rate; channels = vi->channels; std::size_t offset = 0; int current_section = 0; long decodedSamples = 0; bool eof = false; while(!eof) { float **output = nullptr; long ret = ov_read_float(&vf, &output, 1024, ¤t_section); if(ret == 0) { eof = true; } else if(ret < 0) { // stream error, just try to continue } else { decodedSamples = ret; if(decodedSamples > 0 && (channels == 1 || channels == 2)) { raw_sample_data.resize(raw_sample_data.size() + (channels * decodedSamples)); for(int chn = 0; chn < channels; chn++) { CopyChannelToInterleaved >(&(raw_sample_data[0]) + offset * channels, output[chn], channels, decodedSamples, chn); } offset += decodedSamples; } } } } else { unsupportedSample = true; } } else { unsupportedSample = true; } ov_clear(&vf); } else { unsupportedSample = true; } if(unsupportedSample) { return false; } #elif defined(MPT_WITH_STBVORBIS) // NOTE/TODO: stb_vorbis does not handle inferred negative PCM sample position // at stream start. (See // ). This // means that, for remuxed and re-aligned/cutted (at stream start) Vorbis // files, stb_vorbis will include superfluous samples at the beginning. FileReader::PinnedRawDataView fileView = file.GetPinnedRawDataView(); const mpt::byte* data = fileView.data(); std::size_t dataLeft = fileView.size(); std::size_t offset = 0; int consumed = 0; int error = 0; stb_vorbis *vorb = stb_vorbis_open_pushdata(data, mpt::saturate_cast(dataLeft), &consumed, &error, nullptr); file.Skip(consumed); data += consumed; dataLeft -= consumed; if(!vorb) { return false; } rate = stb_vorbis_get_info(vorb).sample_rate; channels = stb_vorbis_get_info(vorb).channels; if(rate <= 0 || channels <= 0) { return false; } while((error == VORBIS__no_error || (error == VORBIS_need_more_data && dataLeft > 0))) { int frame_channels = 0; int decodedSamples = 0; float **output = nullptr; consumed = stb_vorbis_decode_frame_pushdata(vorb, data, mpt::saturate_cast(dataLeft), &frame_channels, &output, &decodedSamples); file.Skip(consumed); data += consumed; dataLeft -= consumed; LimitMax(frame_channels, channels); if(decodedSamples > 0 && (frame_channels == 1 || frame_channels == 2)) { raw_sample_data.resize(raw_sample_data.size() + (channels * decodedSamples)); for(int chn = 0; chn < frame_channels; chn++) { CopyChannelToInterleaved >(&(raw_sample_data[0]) + offset * channels, output[chn], channels, decodedSamples, chn); } offset += decodedSamples; } error = stb_vorbis_get_error(vorb); } stb_vorbis_close(vorb); #endif // VORBIS #if defined(MPT_WITH_VORBISFILE) || defined(MPT_WITH_STBVORBIS) if(rate <= 0 || channels <= 0 || raw_sample_data.empty()) { return false; } if((raw_sample_data.size() / channels) > MAX_SAMPLE_LENGTH) { return false; } DestroySampleThreadsafe(sample); mpt::String::Copy(m_szNames[sample], sampleName); Samples[sample].Initialize(); Samples[sample].nC5Speed = rate; Samples[sample].nLength = mpt::saturate_cast(raw_sample_data.size() / channels); Samples[sample].uFlags.set(CHN_16BIT); Samples[sample].uFlags.set(CHN_STEREO, channels == 2); if(!Samples[sample].AllocateSample()) { return false; } std::copy(raw_sample_data.begin(), raw_sample_data.end(), Samples[sample].pSample16); Samples[sample].Convert(MOD_TYPE_IT, GetType()); Samples[sample].PrecomputeLoops(*this, false); return true; #else // !VORBIS MPT_UNREFERENCED_PARAMETER(sample); MPT_UNREFERENCED_PARAMETER(file); return false; #endif // VORBIS } bool CSoundFile::CanReadVorbis() { bool result = false; #if defined(MPT_WITH_OGG) && defined(MPT_WITH_VORBIS) && defined(MPT_WITH_VORBISFILE) if(!result) { result = true; } #endif #if defined(MPT_WITH_STBVORBIS) if(!result) { result = true; } #endif return result; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/patternContainer.h0000644000372100037210000001041513161656666021607 00000000000000/* * PatternContainer.h * ------------------ * Purpose: Container class for managing patterns. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "pattern.h" #include OPENMPT_NAMESPACE_BEGIN class CSoundFile; class CPatternContainer { public: CPattern& operator[](const int pat) { return m_Patterns[pat]; } const CPattern& operator[](const int pat) const { return m_Patterns[pat]; } public: CPatternContainer(CSoundFile& sndFile) : m_rSndFile(sndFile) { } // Empty and initialize all patterns. void ClearPatterns(); // Delete all patterns. void DestroyPatterns(); // Insert (default)pattern to given position. If pattern already exists at that position, // ignoring request. Returns true on success, false otherwise. bool Insert(const PATTERNINDEX index, const ROWINDEX rows); // Insert pattern to position with the lowest index, and return that index, PATTERNINDEX_INVALID on failure. // If respectQtyLimits is true, inserting patterns will fail if the resulting pattern index would exceed the current format's pattern quantity limits. PATTERNINDEX InsertAny(const ROWINDEX rows, bool respectQtyLimits = false); // Duplicate an existing pattern. Returns new pattern index on success, or PATTERNINDEX_INVALID on failure. // If respectQtyLimits is true, inserting patterns will fail if the resulting pattern index would exceed the current format's pattern quantity limits. PATTERNINDEX Duplicate(PATTERNINDEX from, bool respectQtyLimits = false); //Remove pattern from given position. Currently it actually makes the pattern //'invisible' - the pattern data is cleared but the actual pattern object won't get removed. void Remove(const PATTERNINDEX index); // Applies function object for modcommands in patterns in given range. // Return: Copy of the function object. template Func ForEachModCommand(PATTERNINDEX nStartPat, PATTERNINDEX nLastPat, Func func); template Func ForEachModCommand(Func func) { return ForEachModCommand(0, Size() - 1, func); } std::vector::iterator begin() { return m_Patterns.begin(); } std::vector::const_iterator begin() const { return m_Patterns.begin(); } std::vector::const_iterator cbegin() const { return m_Patterns.cbegin(); } std::vector::iterator end() { return m_Patterns.end(); } std::vector::const_iterator end() const { return m_Patterns.end(); } std::vector::const_iterator cend() const { return m_Patterns.cend(); } PATTERNINDEX Size() const { return static_cast(m_Patterns.size()); } CSoundFile& GetSoundFile() { return m_rSndFile; } const CSoundFile& GetSoundFile() const { return m_rSndFile; } // Return true if pattern can be accessed with operator[](iPat), false otherwise. bool IsValidIndex(const PATTERNINDEX iPat) const { return (iPat < Size()); } // Return true if IsValidIndex() is true and the corresponding pattern has allocated modcommand array, false otherwise. bool IsValidPat(const PATTERNINDEX iPat) const { return IsValidIndex(iPat) && m_Patterns[iPat].IsValid(); } // Returns true if the pattern is empty, i.e. there are no notes/effects in this pattern bool IsPatternEmpty(const PATTERNINDEX nPat) const; void ResizeArray(const PATTERNINDEX newSize); void OnModTypeChanged(const MODTYPE oldtype); // Returns index of last valid pattern + 1, zero if no such pattern exists. PATTERNINDEX GetNumPatterns() const; // Returns index of highest pattern with pattern named + 1. PATTERNINDEX GetNumNamedPatterns() const; private: std::vector m_Patterns; CSoundFile &m_rSndFile; }; template Func CPatternContainer::ForEachModCommand(PATTERNINDEX nStartPat, PATTERNINDEX nLastPat, Func func) { if (nStartPat > nLastPat || nLastPat >= Size()) return func; for (PATTERNINDEX nPat = nStartPat; nPat <= nLastPat; nPat++) if (m_Patterns[nPat].IsValid()) std::for_each(m_Patterns[nPat].begin(), m_Patterns[nPat].end(), func); return func; } const char FileIdPatterns[] = "mptPc"; void ReadModPatterns(std::istream& iStrm, CPatternContainer& patc, const size_t nSize = 0); void WriteModPatterns(std::ostream& oStrm, const CPatternContainer& patc); OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/UMXTools.cpp0000644000372100037210000001132613161656666020316 00000000000000/* * UMXTools.h * ------------ * Purpose: UMX/UAX (Unreal) helper functions * Notes : None. * Authors: Johannes Schultz (inspired by code from http://wiki.beyondunreal.com/Legacy:Package_File_Format) * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" #include "UMXTools.h" OPENMPT_NAMESPACE_BEGIN // Read compressed unreal integers - similar to MIDI integers, but signed values are possible. template static int32 ReadUMXIndexImpl(Tfile &chunk) { enum { signMask = 0x80, // Highest bit of first byte indicates if value is signed valueMask1 = 0x3F, // Low 6 bits of first byte are actual value continueMask1 = 0x40, // Second-highest bit of first byte indicates if further bytes follow valueMask = 0x7F, // Low 7 bits of following bytes are actual value continueMask = 0x80, // Highest bit of following bytes indicates if further bytes follow }; // Read first byte uint8 b = chunk.ReadUint8(); bool isSigned = (b & signMask) != 0; int32 result = (b & valueMask1); int shift = 6; if(b & continueMask1) { // Read remaining bytes do { b = chunk.ReadUint8(); int32 data = static_cast(b) & valueMask; data <<= shift; result |= data; shift += 7; } while((b & continueMask) != 0 && (shift < 32)); } if(isSigned) { result = -result; } return result; } int32 ReadUMXIndex(FileReader &chunk) { return ReadUMXIndexImpl(chunk); } // Returns true if the given nme exists in the name table. template static bool FindUMXNameTableEntryImpl(TFile &file, const UMXFileHeader &fileHeader, const char *name) { if(!name) { return false; } std::size_t name_len = std::strlen(name); if(name_len == 0) { return false; } bool result = false; const FileReader::off_t oldpos = file.GetPosition(); if(file.Seek(fileHeader.nameOffset)) { for(uint32 i = 0; i < fileHeader.nameCount && file.CanRead(4); i++) { if(fileHeader.packageVersion >= 64) { int32 length = ReadUMXIndexImpl(file); if(length <= 0) { continue; } } bool match = true; std::size_t pos = 0; char c = 0; while((c = file.ReadUint8()) != 0) { c = mpt::ToLowerCaseAscii(c); if(pos < name_len) { match = match && (c == name[pos]); } pos++; } if(pos != name_len) { match = false; } if(match) { result = true; } file.Skip(4); // Object flags } } file.Seek(oldpos); return result; } bool FindUMXNameTableEntry(FileReader &file, const UMXFileHeader &fileHeader, const char *name) { return FindUMXNameTableEntryImpl(file, fileHeader, name); } bool FindUMXNameTableEntryMemory(MemoryFileReader &file, const UMXFileHeader &fileHeader, const char *name) { return FindUMXNameTableEntryImpl(file, fileHeader, name); } // Read an entry from the name table. std::string ReadUMXNameTableEntry(FileReader &chunk, uint16 packageVersion) { std::string name; if(packageVersion >= 64) { // String length int32 length = ReadUMXIndex(chunk); if(length <= 0) { return ""; } name.reserve(length); } // Simple zero-terminated string uint8 chr; while((chr = chunk.ReadUint8()) != 0) { // Convert string to lower case if(chr >= 'A' && chr <= 'Z') { chr = chr - 'A' + 'a'; } name.append(1, static_cast(chr)); } chunk.Skip(4); // Object flags return name; } // Read complete name table. std::vector ReadUMXNameTable(FileReader &file, const UMXFileHeader &fileHeader) { std::vector names; if(!file.Seek(fileHeader.nameOffset)) { return names; } names.reserve(fileHeader.nameCount); for(uint32 i = 0; i < fileHeader.nameCount && file.CanRead(4); i++) { names.push_back(ReadUMXNameTableEntry(file, fileHeader.packageVersion)); } return names; } // Read an entry from the import table. int32 ReadUMXImportTableEntry(FileReader &chunk, uint16 packageVersion) { ReadUMXIndex(chunk); // Class package ReadUMXIndex(chunk); // Class name if(packageVersion >= 60) { chunk.Skip(4); // Package } else { ReadUMXIndex(chunk); // ?? } return ReadUMXIndex(chunk); // Object name (offset into the name table) } // Read an entry from the export table. void ReadUMXExportTableEntry(FileReader &chunk, int32 &objClass, int32 &objOffset, int32 &objSize, int32 &objName, uint16 packageVersion) { objClass = ReadUMXIndex(chunk); // Object class ReadUMXIndex(chunk); // Object parent if(packageVersion >= 60) { chunk.Skip(4); // Internal package / group of the object } objName = ReadUMXIndex(chunk); // Object name (offset into the name table) chunk.Skip(4); // Object flags objSize = ReadUMXIndex(chunk); if(objSize > 0) { objOffset = ReadUMXIndex(chunk); } } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/modsmp_ctrl.h0000644000372100037210000001051513050714405020572 00000000000000/* * ModSmp_Ctrl.h * ------------- * Purpose: Basic sample editing code (resizing, adding silence, normalizing, ...). * Notes : Could be merged with ModSample.h / ModSample.cpp at some point. * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once OPENMPT_NAMESPACE_BEGIN class CSoundFile; struct ModSample; struct ModChannel; OPENMPT_NAMESPACE_END #include "Snd_defs.h" OPENMPT_NAMESPACE_BEGIN namespace ctrlSmp { enum ResetFlag { SmpResetCompo = 1, SmpResetInit, SmpResetVibrato, }; // Insert silence to given location. // Note: Is currently implemented only for inserting silence to the beginning and to the end of the sample. // Return: Length of the new sample. SmpLength InsertSilence(ModSample &smp, const SmpLength nSilenceLength, const SmpLength nStartFrom, CSoundFile &sndFile); // Remove part of a sample [selStart, selEnd[. // Note: Removed memory is not freed. // Return: Length of the new sample. SmpLength RemoveRange(ModSample &smp, SmpLength selStart, SmpLength selEnd, CSoundFile &sndFile); // Change sample size. // Note: If resized sample is bigger, silence will be added to the sample's tail. // Return: Length of the new sample. SmpLength ResizeSample(ModSample &smp, const SmpLength nNewLength, CSoundFile &sndFile); // Replaces sample in 'smp' with given sample and frees the old sample. void ReplaceSample(ModSample &smp, void *pNewSample, const SmpLength nNewLength, CSoundFile &sndFile); // Update loop wrap-around buffers bool PrecomputeLoops(ModSample &smp, CSoundFile &sndFile, bool updateChannels = true); // Propagate loop point changes to player bool UpdateLoopPoints(const ModSample &smp, CSoundFile &sndFile); // Resets samples. void ResetSamples(CSoundFile &sndFile, ResetFlag resetflag, SAMPLEINDEX minSample = SAMPLEINDEX_INVALID, SAMPLEINDEX maxSample = SAMPLEINDEX_INVALID); // Remove DC offset and normalize. // Return: If DC offset was removed, returns original offset value, zero otherwise. float RemoveDCOffset(ModSample &smp, SmpLength iStart, // Start position (for partial DC offset removal). SmpLength iEnd, // End position (for partial DC offset removal). const MODTYPE modtype, // Used to determine whether to adjust global or default volume // to keep volume level the same given the normalization. // Volume adjustment is not done if this param is MOD_TYPE_NONE. CSoundFile &sndFile); // Passed to AdjustEndOfSample. // Amplify / fade sample data bool AmplifySample(ModSample &smp, SmpLength iStart, SmpLength iEnd, CSoundFile &sndFile, double amplifyStart, double amplifyEnd); // Reverse sample data bool ReverseSample(ModSample &smp, SmpLength iStart, SmpLength iEnd, CSoundFile &sndFile); // Virtually unsign sample data bool UnsignSample(ModSample &smp, SmpLength iStart, SmpLength iEnd, CSoundFile &sndFile); // Invert sample data (flip by 180 degrees) bool InvertSample(ModSample &smp, SmpLength iStart, SmpLength iEnd, CSoundFile &sndFile); // Crossfade sample data to create smooth loops bool XFadeSample(ModSample &smp, SmpLength fadeLength, int fadeLaw, bool afterloopFade, bool useSustainLoop, CSoundFile &sndFile); // Silence parts of the sample data bool SilenceSample(ModSample &smp, SmpLength start, SmpLength end, CSoundFile &sndFile); // Modify stereo separation of the sample data. separation is in range [-200, 200] bool StereoSepSample(ModSample &smp, SmpLength start, SmpLength end, double separation, CSoundFile &sndFile); enum StereoToMonoMode { mixChannels, onlyLeft, onlyRight, splitSample, }; // Convert a sample with any number of channels to mono bool ConvertToMono(ModSample &smp, CSoundFile &sndFile, StereoToMonoMode conversionMode); // Convert a mono sample to stereo bool ConvertToStereo(ModSample &smp, CSoundFile &sndFile); // Convert 16-bit sample to 8-bit bool ConvertTo8Bit(ModSample &smp, CSoundFile &sndFile); // Convert 8-bit sample to 16-bit bool ConvertTo16Bit(ModSample &smp, CSoundFile &sndFile); } // Namespace ctrlSmp namespace ctrlChn { // Replaces sample from sound channels by given sample. void ReplaceSample( CSoundFile &sndFile, const ModSample &sample, const void * const pNewSample, const SmpLength nNewLength, FlagSet setFlags, FlagSet resetFlags); } // namespace ctrlChn OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/MixerLoops.cpp0000644000372100037210000004615613161656666020736 00000000000000/* * MixerLoops.cpp * -------------- * Purpose: Utility inner loops for mixer-related functionality. * Notes : * x86 ( AMD/INTEL ) based low level based mixing functions: * This file contains critical code. The basic X86 functions are * defined at the bottom of the file. #define's are used to isolate * the different flavours of functionality: * ENABLE_MMX, ENABLE_3DNOW, ENABLE_SSE flags must be set to * to compile the optimized sections of the code. In both cases the * X86_xxxxxx functions will compile. * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "MixerLoops.h" #include "Sndfile.h" OPENMPT_NAMESPACE_BEGIN //////////////////////////////////////////////////////////////////////////////////// // 3DNow! optimizations #ifdef ENABLE_X86_AMD // Convert integer mix to floating-point static void AMD_StereoMixToFloat(const int32 *pSrc, float *pOut1, float *pOut2, uint32 nCount, const float _i2fc) { _asm { movd mm0, _i2fc mov edx, pSrc mov edi, pOut1 mov ebx, pOut2 mov ecx, nCount punpckldq mm0, mm0 inc ecx shr ecx, 1 mainloop: movq mm1, qword ptr [edx] movq mm2, qword ptr [edx+8] add edi, 8 pi2fd mm1, mm1 pi2fd mm2, mm2 add ebx, 8 pfmul mm1, mm0 pfmul mm2, mm0 add edx, 16 movq mm3, mm1 punpckldq mm3, mm2 punpckhdq mm1, mm2 dec ecx movq qword ptr [edi-8], mm3 movq qword ptr [ebx-8], mm1 jnz mainloop emms } } static void AMD_FloatToStereoMix(const float *pIn1, const float *pIn2, int32 *pOut, uint32 nCount, const float _f2ic) { _asm { movd mm0, _f2ic mov eax, pIn1 mov ebx, pIn2 mov edx, pOut mov ecx, nCount punpckldq mm0, mm0 inc ecx shr ecx, 1 sub edx, 16 mainloop: movq mm1, [eax] movq mm2, [ebx] add edx, 16 movq mm3, mm1 punpckldq mm1, mm2 punpckhdq mm3, mm2 add eax, 8 pfmul mm1, mm0 pfmul mm3, mm0 add ebx, 8 pf2id mm1, mm1 pf2id mm3, mm3 dec ecx movq qword ptr [edx], mm1 movq qword ptr [edx+8], mm3 jnz mainloop emms } } static void AMD_FloatToMonoMix(const float *pIn, int32 *pOut, uint32 nCount, const float _f2ic) { _asm { movd mm0, _f2ic mov eax, pIn mov edx, pOut mov ecx, nCount punpckldq mm0, mm0 add ecx, 3 shr ecx, 2 sub edx, 16 mainloop: movq mm1, [eax] movq mm2, [eax+8] add edx, 16 pfmul mm1, mm0 pfmul mm2, mm0 add eax, 16 pf2id mm1, mm1 pf2id mm2, mm2 dec ecx movq qword ptr [edx], mm1 movq qword ptr [edx+8], mm2 jnz mainloop emms } } static void AMD_MonoMixToFloat(const int32 *pSrc, float *pOut, uint32 nCount, const float _i2fc) { _asm { movd mm0, _i2fc mov eax, pSrc mov edx, pOut mov ecx, nCount punpckldq mm0, mm0 add ecx, 3 shr ecx, 2 sub edx, 16 mainloop: movq mm1, qword ptr [eax] movq mm2, qword ptr [eax+8] add edx, 16 pi2fd mm1, mm1 pi2fd mm2, mm2 add eax, 16 pfmul mm1, mm0 pfmul mm2, mm0 dec ecx movq qword ptr [edx], mm1 movq qword ptr [edx+8], mm2 jnz mainloop emms } } #endif // ENABLE_X86_AMD /////////////////////////////////////////////////////////////////////////////////////// // SSE Optimizations #ifdef ENABLE_SSE2 #include static void SSE2_StereoMixToFloat(const int32 *pSrc, float *pOut1, float *pOut2, uint32 nCount, const float _i2fc) { __m128 i2fc = _mm_load_ps1(&_i2fc); const __m128i *in = reinterpret_cast(pSrc); // We may read beyond the wanted length... this works because we know that we will always work on our buffers of size MIXBUFFERSIZE nCount = (nCount + 3) / 4; do { __m128i i1 = _mm_loadu_si128(in); // Load four integer values, LRLR __m128i i2 = _mm_loadu_si128(in + 1); // Load four integer values, LRLR in += 2; __m128 f1 = _mm_cvtepi32_ps(i1); // Convert to four floats, LRLR __m128 f2 = _mm_cvtepi32_ps(i2); // Convert to four floats, LRLR f1 = _mm_mul_ps(f1, i2fc); // Apply int->float factor f2 = _mm_mul_ps(f2, i2fc); // Apply int->float factor __m128 fl = _mm_shuffle_ps(f1, f2, _MM_SHUFFLE(2, 0, 2, 0)); // LRLR+LRLR => LLLL __m128 fr = _mm_shuffle_ps(f1, f2, _MM_SHUFFLE(3, 1, 3, 1)); // LRLR+LRLR => RRRR _mm_storeu_ps(pOut1, fl); // Store four float values, LLLL _mm_storeu_ps(pOut2, fr); // Store four float values, RRRR pOut1 += 4; pOut2 += 4; } while(--nCount); } static void SSE2_FloatToStereoMix(const float *pIn1, const float *pIn2, int32 *pOut, uint32 nCount, const float _f2ic) { __m128 f2ic = _mm_load_ps1(&_f2ic); __m128i *out = reinterpret_cast<__m128i *>(pOut); // We may read beyond the wanted length... this works because we know that we will always work on our buffers of size MIXBUFFERSIZE nCount = (nCount + 3) / 4; do { __m128 fl = _mm_loadu_ps(pIn1); // Load four float values, LLLL __m128 fr = _mm_loadu_ps(pIn2); // Load four float values, RRRR pIn1 += 4; pIn2 += 4; fl = _mm_mul_ps(fl, f2ic); // Apply int->float factor fr = _mm_mul_ps(fr, f2ic); // Apply int->float factor __m128 f1 = _mm_unpacklo_ps(fl, fr); // LL__+RR__ => LRLR __m128 f2 = _mm_unpackhi_ps(fl, fr); // __LL+__RR => LRLR __m128i i1 =_mm_cvtps_epi32(f1); // Convert to four ints __m128i i2 =_mm_cvtps_epi32(f2); // Convert to four ints _mm_storeu_si128(out, i1); // Store four int values, LRLR _mm_storeu_si128(out + 1, i2); // Store four int values, LRLR out += 2; } while(--nCount); } #endif // ENABLE_SSE2 #ifdef ENABLE_SSE static void SSE_StereoMixToFloat(const int32 *pSrc, float *pOut1, float *pOut2, uint32 nCount, const float _i2fc) { _asm { movss xmm0, _i2fc mov edx, pSrc mov eax, pOut1 mov ebx, pOut2 mov ecx, nCount shufps xmm0, xmm0, 0x00 xorps xmm1, xmm1 xorps xmm2, xmm2 inc ecx shr ecx, 1 mainloop: cvtpi2ps xmm1, [edx] cvtpi2ps xmm2, [edx+8] add eax, 8 add ebx, 8 movlhps xmm1, xmm2 mulps xmm1, xmm0 add edx, 16 shufps xmm1, xmm1, 0xD8 dec ecx movlps qword ptr [eax-8], xmm1 movhps qword ptr [ebx-8], xmm1 jnz mainloop } } static void SSE_MonoMixToFloat(const int32 *pSrc, float *pOut, uint32 nCount, const float _i2fc) { _asm { movss xmm0, _i2fc mov edx, pSrc mov eax, pOut mov ecx, nCount shufps xmm0, xmm0, 0x00 xorps xmm1, xmm1 xorps xmm2, xmm2 add ecx, 3 shr ecx, 2 mainloop: cvtpi2ps xmm1, [edx] cvtpi2ps xmm2, [edx+8] add eax, 16 movlhps xmm1, xmm2 mulps xmm1, xmm0 add edx, 16 dec ecx movups [eax-16], xmm1 jnz mainloop } } #endif // ENABLE_SSE #ifdef ENABLE_X86 // Convert floating-point mix to integer static void X86_FloatToStereoMix(const float *pIn1, const float *pIn2, int32 *pOut, uint32 nCount, const float _f2ic) { _asm { mov esi, pIn1 mov ebx, pIn2 mov edi, pOut mov ecx, nCount fld _f2ic mainloop: fld dword ptr [ebx] add edi, 8 fld dword ptr [esi] add ebx, 4 add esi, 4 fmul st(0), st(2) fistp dword ptr [edi-8] fmul st(0), st(1) fistp dword ptr [edi-4] dec ecx jnz mainloop fstp st(0) } } // Convert integer mix to floating-point static void X86_StereoMixToFloat(const int32 *pSrc, float *pOut1, float *pOut2, uint32 nCount, const float _i2fc) { _asm { mov esi, pSrc mov edi, pOut1 mov ebx, pOut2 mov ecx, nCount fld _i2fc mainloop: fild dword ptr [esi] fild dword ptr [esi+4] add ebx, 4 add edi, 4 fmul st(0), st(2) add esi, 8 fstp dword ptr [ebx-4] fmul st(0), st(1) fstp dword ptr [edi-4] dec ecx jnz mainloop fstp st(0) } } static void X86_FloatToMonoMix(const float *pIn, int32 *pOut, uint32 nCount, const float _f2ic) { _asm { mov edx, pIn mov eax, pOut mov ecx, nCount fld _f2ic sub eax, 4 R2I_Loop: fld DWORD PTR [edx] add eax, 4 fmul ST(0), ST(1) dec ecx lea edx, [edx+4] fistp DWORD PTR [eax] jnz R2I_Loop fstp st(0) } } static void X86_MonoMixToFloat(const int32 *pSrc, float *pOut, uint32 nCount, const float _i2fc) { _asm { mov edx, pOut mov eax, pSrc mov ecx, nCount fld _i2fc sub edx, 4 I2R_Loop: fild DWORD PTR [eax] add edx, 4 fmul ST(0), ST(1) dec ecx lea eax, [eax+4] fstp DWORD PTR [edx] jnz I2R_Loop fstp st(0) } } #endif // ENABLE_X86 static void C_FloatToStereoMix(const float *pIn1, const float *pIn2, int32 *pOut, uint32 nCount, const float _f2ic) { for(uint32 i=0; i=0; i--) { pFrontBuf[i*4+3] = pRearBuf[i*2+1]; pFrontBuf[i*4+2] = pRearBuf[i*2+0]; pFrontBuf[i*4+1] = pFrontBuf[i*2+1]; pFrontBuf[i*4+0] = pFrontBuf[i*2+0]; } } void InterleaveFrontRear(mixsample_t *pFrontBuf, mixsample_t *pRearBuf, uint32 nFrames) { #if defined(ENABLE_X86) && defined(MPT_INTMIXER) X86_InterleaveFrontRear(pFrontBuf, pRearBuf, nFrames); #else C_InterleaveFrontRear(pFrontBuf, pRearBuf, nFrames); #endif } #ifdef ENABLE_X86 static void X86_MonoFromStereo(int32 *pMixBuf, uint32 nSamples) { _asm { mov ecx, nSamples mov esi, pMixBuf mov edi, esi stloop: mov eax, dword ptr [esi] mov edx, dword ptr [esi+4] add edi, 4 add esi, 8 add eax, edx sar eax, 1 dec ecx mov dword ptr [edi-4], eax jnz stloop } } #endif static void C_MonoFromStereo(mixsample_t *pMixBuf, uint32 nSamples) { for(uint32 i=0; i(1.0 / (1 << 20)) // Decay threshold for floating point mixer #ifdef ENABLE_X86 static void X86_StereoFill(int32 *pBuffer, uint32 nSamples, int32 *lpROfs, int32 *lpLOfs) { _asm { mov edi, pBuffer mov ecx, nSamples mov eax, lpROfs mov edx, lpLOfs mov eax, [eax] mov edx, [edx] or ecx, ecx jz fill_loop mov ebx, eax or ebx, edx jz fill_loop ofsloop: mov ebx, eax mov esi, edx neg ebx neg esi sar ebx, 31 sar esi, 31 and ebx, OFSDECAYMASK and esi, OFSDECAYMASK add ebx, eax add esi, edx sar ebx, OFSDECAYSHIFT sar esi, OFSDECAYSHIFT sub eax, ebx sub edx, esi mov ebx, eax or ebx, edx jz fill_loop add edi, 8 dec ecx mov [edi-8], eax mov [edi-4], edx jnz ofsloop fill_loop: mov ebx, ecx and ebx, 3 jz fill4x fill1x: mov [edi], eax mov [edi+4], edx add edi, 8 dec ebx jnz fill1x fill4x: shr ecx, 2 or ecx, ecx jz done fill4xloop: mov [edi], eax mov [edi+4], edx mov [edi+8], eax mov [edi+12], edx add edi, 8*4 dec ecx mov [edi-16], eax mov [edi-12], edx mov [edi-8], eax mov [edi-4], edx jnz fill4xloop done: mov esi, lpROfs mov edi, lpLOfs mov [esi], eax mov [edi], edx } } #endif // c implementation taken from libmodplug static void C_StereoFill(mixsample_t *pBuffer, uint32 nSamples, mixsample_t &rofs, mixsample_t &lofs) { if ((!rofs) && (!lofs)) { InitMixBuffer(pBuffer, nSamples*2); return; } for (uint32 i=0; i 0 ? 255 : -255)) / 256; const mixsample_t x_r = (rofs + (((-rofs) >> (sizeof(mixsample_t) * 8 - 1)) & OFSDECAYMASK)) >> OFSDECAYSHIFT; const mixsample_t x_l = (lofs + (((-lofs) >> (sizeof(mixsample_t) * 8 - 1)) & OFSDECAYMASK)) >> OFSDECAYSHIFT; #else const mixsample_t x_r = rofs * (1.0f / (1 << OFSDECAYSHIFT)); const mixsample_t x_l = lofs * (1.0f / (1 << OFSDECAYSHIFT)); #endif rofs -= x_r; lofs -= x_l; pBuffer[i*2] = x_r; pBuffer[i*2+1] = x_l; } #ifndef MPT_INTMIXER if(fabs(rofs) < OFSTHRESHOLD) rofs = 0; if(fabs(lofs) < OFSTHRESHOLD) lofs = 0; #endif } void StereoFill(mixsample_t *pBuffer, uint32 nSamples, mixsample_t &rofs, mixsample_t &lofs) { #if defined(ENABLE_X86) && defined(MPT_INTMIXER) X86_StereoFill(pBuffer, nSamples, &rofs, &lofs); #else C_StereoFill(pBuffer, nSamples, rofs, lofs); #endif } #ifdef ENABLE_X86 typedef ModChannel ModChannel_; static void X86_EndChannelOfs(ModChannel *pChannel, int32 *pBuffer, uint32 nSamples) { _asm { mov esi, pChannel mov edi, pBuffer mov ecx, nSamples mov eax, dword ptr [esi+ModChannel_.nROfs] mov edx, dword ptr [esi+ModChannel_.nLOfs] or ecx, ecx jz brkloop ofsloop: mov ebx, eax mov esi, edx neg ebx neg esi sar ebx, 31 sar esi, 31 and ebx, OFSDECAYMASK and esi, OFSDECAYMASK add ebx, eax add esi, edx sar ebx, OFSDECAYSHIFT sar esi, OFSDECAYSHIFT sub eax, ebx sub edx, esi mov ebx, eax add dword ptr [edi], eax add dword ptr [edi+4], edx or ebx, edx jz brkloop add edi, 8 dec ecx jnz ofsloop brkloop: mov esi, pChannel mov dword ptr [esi+ModChannel_.nROfs], eax mov dword ptr [esi+ModChannel_.nLOfs], edx } } #endif // c implementation taken from libmodplug static void C_EndChannelOfs(ModChannel &chn, mixsample_t *pBuffer, uint32 nSamples) { mixsample_t rofs = chn.nROfs; mixsample_t lofs = chn.nLOfs; if ((!rofs) && (!lofs)) return; for (uint32 i=0; i> (sizeof(mixsample_t) * 8 - 1)) & OFSDECAYMASK)) >> OFSDECAYSHIFT; const mixsample_t x_l = (lofs + (((-lofs) >> (sizeof(mixsample_t) * 8 - 1)) & OFSDECAYMASK)) >> OFSDECAYSHIFT; #else const mixsample_t x_r = rofs * (1.0f / (1 << OFSDECAYSHIFT)); const mixsample_t x_l = lofs * (1.0f / (1 << OFSDECAYSHIFT)); #endif rofs -= x_r; lofs -= x_l; pBuffer[i*2] += x_r; pBuffer[i*2+1] += x_l; } #ifndef MPT_INTMIXER if(mpt::abs(rofs) < OFSTHRESHOLD) rofs = 0; if(mpt::abs(lofs) < OFSTHRESHOLD) lofs = 0; #endif chn.nROfs = rofs; chn.nLOfs = lofs; } void EndChannelOfs(ModChannel &chn, mixsample_t *pBuffer, uint32 nSamples) { #if defined(ENABLE_X86) && defined(MPT_INTMIXER) X86_EndChannelOfs(&chn, pBuffer, nSamples); #else C_EndChannelOfs(chn, pBuffer, nSamples); #endif } void InterleaveStereo(const mixsample_t * MPT_RESTRICT inputL, const mixsample_t * MPT_RESTRICT inputR, mixsample_t * MPT_RESTRICT output, size_t numSamples) { while(numSamples--) { *(output++) = *(inputL++); *(output++) = *(inputR++); } } void DeinterleaveStereo(const mixsample_t * MPT_RESTRICT input, mixsample_t * MPT_RESTRICT outputL, mixsample_t * MPT_RESTRICT outputR, size_t numSamples) { while(numSamples--) { *(outputL++) = *(input++); *(outputR++) = *(input++); } } #ifndef MODPLUG_TRACKER void ApplyGain(int32 *soundBuffer, std::size_t channels, std::size_t countChunk, int32 gainFactor16_16) { if(gainFactor16_16 == (1<<16)) { // nothing to do, gain == +/- 0dB return; } // no clipping prevention is done here int32 * buf = soundBuffer; for(std::size_t i=0; i Frequency conversions static uint32 TransposeToFrequency(int transpose, int finetune = 0); void TransposeToFrequency(); static int FrequencyToTranspose(uint32 freq); void FrequencyToTranspose(); // Transpose the sample by amount specified in octaves (i.e. amount=1 transposes one octave up) void Transpose(double amount); // Check if the sample's cue points are the default cue point set. bool HasCustomCuePoints() const; }; OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/WAVTools.cpp0000644000372100037210000004005613161656666020304 00000000000000/* * WAVTools.cpp * ------------ * Purpose: Definition of WAV file structures and helper functions * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" #include "WAVTools.h" #include "Tagging.h" #ifndef MODPLUG_NO_FILESAVE #include "../common/mptFileIO.h" #endif OPENMPT_NAMESPACE_BEGIN /////////////////////////////////////////////////////////// // WAV Reading WAVReader::WAVReader(FileReader &inputFile) : file(inputFile) { file.Rewind(); RIFFHeader fileHeader; isDLS = false; subFormat = 0; mayBeCoolEdit16_8 = false; if(!file.ReadStruct(fileHeader) || (fileHeader.magic != RIFFHeader::idRIFF && fileHeader.magic != RIFFHeader::idLIST) || (fileHeader.type != RIFFHeader::idWAVE && fileHeader.type != RIFFHeader::idwave)) { return; } isDLS = (fileHeader.magic == RIFFHeader::idLIST); auto chunks = file.ReadChunks(2); if(chunks.size() >= 4 && chunks[1].GetHeader().GetID() == RIFFChunk::iddata && chunks[1].GetHeader().GetLength() % 2u != 0 && chunks[2].GetHeader().GetLength() == 0 && chunks[3].GetHeader().GetID() == RIFFChunk::id____) { // Houston, we have a problem: Old versions of (Open)MPT didn't write RIFF padding bytes. -_- // Luckily, the only RIFF chunk with an odd size those versions would ever write would be the "data" chunk // (which contains the sample data), and its size is only odd iff the sample has an odd length and is in // 8-Bit mono format. In all other cases, the sample size (and thus the chunk size) is even. // And we're even more lucky: The versions of (Open)MPT in question will always write a relatively small // (smaller than 256 bytes) "smpl" chunk after the "data" chunk. This means that after an unpadded sample, // we will always read "mpl?" (? being the length of the "smpl" chunk) as the next chunk magic. The first two // 32-Bit members of the "smpl" chunk are always zero in our case, so we are going to read a chunk length of 0 // next and the next chunk magic, which will always consist of four zero bytes. Hooray! We just checked for those // four zero bytes and can be pretty confident that we should not have applied padding. file.Seek(sizeof(RIFFHeader)); chunks = file.ReadChunks(1); } // Read format chunk FileReader formatChunk = chunks.GetChunk(RIFFChunk::idfmt_); if(!formatChunk.ReadStruct(formatInfo)) { return; } if(formatInfo.format == WAVFormatChunk::fmtPCM && formatChunk.BytesLeft() == 4) { uint16 size = formatChunk.ReadIntLE(); uint16 value = formatChunk.ReadIntLE(); if(size == 2 && value == 1) { // May be Cool Edit 16.8 format. // See SampleFormats.cpp for details. mayBeCoolEdit16_8 = true; } } else if(formatInfo.format == WAVFormatChunk::fmtExtensible) { WAVFormatChunkExtension extFormat; if(!formatChunk.ReadStruct(extFormat)) { return; } subFormat = static_cast(mpt::UUID(extFormat.subFormat).GetData1()); } // Read sample data sampleData = chunks.GetChunk(RIFFChunk::iddata); if(!sampleData.IsValid()) { // The old IMA ADPCM loader code looked for the "pcm " chunk instead of the "data" chunk... // Dunno why (Windows XP's audio recorder saves IMA ADPCM files with a "data" chunk), but we will just look for both. sampleData = chunks.GetChunk(RIFFChunk::idpcm_); } // "fact" chunk should contain sample length of compressed samples. sampleLength = chunks.GetChunk(RIFFChunk::idfact).ReadUint32LE(); if((formatInfo.format != WAVFormatChunk::fmtIMA_ADPCM || sampleLength == 0) && GetSampleSize() != 0) { if((GetBlockAlign() == 0) || (GetBlockAlign() / GetNumChannels() >= 2 * GetSampleSize())) { // Some samples have an incorrect blockAlign / sample size set (e.g. it's 8 in SQUARE.WAV while it should be 1), so let's better not always trust this value. // The idea here is, if block align is off by twice or more, it is unlikely to be describing sample padding inside the block. // Ignore it in this case and calculate the length based on the single sample size and number of channels instead. sampleLength = sampleData.GetLength() / GetSampleSize(); } else { // Correct case (so that 20bit WAVEFORMATEX files work). sampleLength = sampleData.GetLength() / GetBlockAlign(); } } // Check for loop points, texts, etc... FindMetadataChunks(chunks); // DLS bank chunk wsmpChunk = chunks.GetChunk(RIFFChunk::idwsmp); } void WAVReader::FindMetadataChunks(ChunkReader::ChunkList &chunks) { // Read sample loop points and other sampler information smplChunk = chunks.GetChunk(RIFFChunk::idsmpl); instChunk = chunks.GetChunk(RIFFChunk::idinst); // Read sample cues cueChunk = chunks.GetChunk(RIFFChunk::idcue_); // Read text chunks ChunkReader listChunk = chunks.GetChunk(RIFFChunk::idLIST); if(listChunk.ReadMagic("INFO")) { infoChunk = listChunk.ReadChunks(2); } // Read MPT sample information xtraChunk = chunks.GetChunk(RIFFChunk::idxtra); } void WAVReader::ApplySampleSettings(ModSample &sample, char (&sampleName)[MAX_SAMPLENAME]) { // Read sample name FileReader textChunk = infoChunk.GetChunk(RIFFChunk::idINAM); if(textChunk.IsValid()) { textChunk.ReadString(sampleName, textChunk.GetLength()); } if(isDLS) { // DLS sample -> sample filename mpt::String::Copy(sample.filename, sampleName); } // Read software name const bool isOldMPT = infoChunk.GetChunk(RIFFChunk::idISFT).ReadMagic("Modplug Tracker"); // Convert loops WAVSampleInfoChunk sampleInfo; smplChunk.Rewind(); if(smplChunk.ReadStruct(sampleInfo)) { WAVSampleLoop loopData; if(sampleInfo.numLoops > 1 && smplChunk.ReadStruct(loopData)) { // First loop: Sustain loop loopData.ApplyToSample(sample.nSustainStart, sample.nSustainEnd, sample.nLength, sample.uFlags, CHN_SUSTAINLOOP, CHN_PINGPONGSUSTAIN, isOldMPT); } // First loop (if only one loop is present) or second loop (if more than one loop is present): Normal sample loop if(smplChunk.ReadStruct(loopData)) { loopData.ApplyToSample(sample.nLoopStart, sample.nLoopEnd, sample.nLength, sample.uFlags, CHN_LOOP, CHN_PINGPONGLOOP, isOldMPT); } //sample.Transpose((60 - sampleInfo.baseNote) / 12.0); sample.rootNote = static_cast(sampleInfo.baseNote); if(sample.rootNote < 128) sample.rootNote += NOTE_MIN; else sample.rootNote = NOTE_NONE; sample.SanitizeLoops(); } if(sample.rootNote == NOTE_NONE && instChunk.LengthIsAtLeast(sizeof(WAVInstrumentChunk))) { WAVInstrumentChunk inst; instChunk.Rewind(); if(instChunk.ReadStruct(inst)) { sample.rootNote = inst.unshiftedNote; if(sample.rootNote < 128) sample.rootNote += NOTE_MIN; else sample.rootNote = NOTE_NONE; } } // Read cue points if(cueChunk.IsValid()) { uint32 numPoints = cueChunk.ReadUint32LE(); LimitMax(numPoints, mpt::saturate_cast(MPT_ARRAY_COUNT(sample.cues))); for(uint32 i = 0; i < numPoints; i++) { WAVCuePoint cuePoint; cueChunk.ReadStruct(cuePoint); sample.cues[i] = cuePoint.position; } } // Read MPT extra info WAVExtraChunk mptInfo; xtraChunk.Rewind(); if(xtraChunk.ReadStruct(mptInfo)) { if(mptInfo.flags & WAVExtraChunk::setPanning) sample.uFlags.set(CHN_PANNING); sample.nPan = std::min(mptInfo.defaultPan, 256); sample.nVolume = std::min(mptInfo.defaultVolume, 256); sample.nGlobalVol = std::min(mptInfo.globalVolume, 64); sample.nVibType = mptInfo.vibratoType; sample.nVibSweep = mptInfo.vibratoSweep; sample.nVibDepth = mptInfo.vibratoDepth; sample.nVibRate = mptInfo.vibratoRate; if(xtraChunk.CanRead(MAX_SAMPLENAME)) { // Name present (clipboard only) xtraChunk.ReadString(sampleName, MAX_SAMPLENAME); xtraChunk.ReadString(sample.filename, xtraChunk.BytesLeft()); } } } // Apply WAV loop information to a mod sample. void WAVSampleLoop::ApplyToSample(SmpLength &start, SmpLength &end, SmpLength sampleLength, SampleFlags &flags, ChannelFlags enableFlag, ChannelFlags bidiFlag, bool mptLoopFix) const { if(loopEnd == 0) { // Some WAV files seem to have loops going from 0 to 0... We should ignore those. return; } start = std::min(static_cast(loopStart), sampleLength); end = Clamp(static_cast(loopEnd), start, sampleLength); if(!mptLoopFix && end < sampleLength) { // RIFF loop end points are inclusive - old versions of MPT didn't consider this. end++; } flags.set(enableFlag); if(loopType == loopBidi) { flags.set(bidiFlag); } } // Convert internal loop information into a WAV loop. void WAVSampleLoop::ConvertToWAV(SmpLength start, SmpLength end, bool bidi) { identifier = 0; loopType = bidi ? loopBidi : loopForward; loopStart = mpt::saturate_cast(start); // Loop ends are *inclusive* in the RIFF standard, while they're *exclusive* in OpenMPT. if(end > start) { loopEnd = mpt::saturate_cast(end - 1); } else { loopEnd = loopStart; } fraction = 0; playCount = 0; } #ifndef MODPLUG_NO_FILESAVE /////////////////////////////////////////////////////////// // WAV Writing // Output to stream: Initialize with std::ostream*. WAVWriter::WAVWriter(std::ostream *stream) : s(nullptr), memory(nullptr), memSize(0) { s = stream; Init(); } // Output to clipboard: Initialize with pointer to memory and size of reserved memory. WAVWriter::WAVWriter(void *mem, size_t size) : s(nullptr), memory(static_cast(mem)), memSize(size) { Init(); } WAVWriter::~WAVWriter() { Finalize(); } // Reset all file variables. void WAVWriter::Init() { chunkStartPos = 0; position = 0; totalSize = 0; // Skip file header for now Seek(sizeof(RIFFHeader)); } // Finalize the file by closing the last open chunk and updating the file header. Returns total size of file. size_t WAVWriter::Finalize() { FinalizeChunk(); RIFFHeader fileHeader; fileHeader.magic = RIFFHeader::idRIFF; fileHeader.length = static_cast(totalSize - 8); fileHeader.type = RIFFHeader::idWAVE; Seek(0); Write(fileHeader); s = nullptr; memory = nullptr; return totalSize; } // Write a new chunk header to the file. void WAVWriter::StartChunk(RIFFChunk::ChunkIdentifiers id) { FinalizeChunk(); chunkStartPos = position; chunkHeader.id = id; Skip(sizeof(chunkHeader)); } // End current chunk by updating the chunk header and writing a padding byte if necessary. void WAVWriter::FinalizeChunk() { if(chunkStartPos != 0) { const size_t chunkSize = position - (chunkStartPos + sizeof(RIFFChunk)); chunkHeader.length = chunkSize; size_t curPos = position; Seek(chunkStartPos); Write(chunkHeader); Seek(curPos); if((chunkSize % 2u) != 0) { // Write padding uint8 padding = 0; Write(padding); } chunkStartPos = 0; } } // Seek to a position in file. void WAVWriter::Seek(size_t pos) { position = pos; totalSize = std::max(totalSize, position); if(s != nullptr) { s->seekp(position); } } // Write some data to the file. void WAVWriter::Write(const void *data, size_t numBytes) { if(s != nullptr) { s->write(static_cast(data), numBytes); } else if(memory != nullptr) { if(position <= memSize && numBytes <= memSize - position) { memcpy(memory + position, data, numBytes); } else { // Should never happen - did we calculate a wrong memory size? MPT_ASSERT_NOTREACHED(); } } position += numBytes; totalSize = std::max(totalSize, position); } // Write the WAV format to the file. void WAVWriter::WriteFormat(uint32 sampleRate, uint16 bitDepth, uint16 numChannels, WAVFormatChunk::SampleFormats encoding) { StartChunk(RIFFChunk::idfmt_); WAVFormatChunk wavFormat; bool extensible = (numChannels > 2); wavFormat.format = static_cast(extensible ? WAVFormatChunk::fmtExtensible : encoding); wavFormat.numChannels = numChannels; wavFormat.sampleRate = sampleRate; wavFormat.blockAlign = (bitDepth * numChannels + 7) / 8; wavFormat.byteRate = wavFormat.sampleRate * wavFormat.blockAlign; wavFormat.bitsPerSample = bitDepth; Write(wavFormat); if(extensible) { WAVFormatChunkExtension extFormat; extFormat.size = sizeof(WAVFormatChunkExtension) - sizeof(uint16); extFormat.validBitsPerSample = bitDepth; switch(numChannels) { case 1: extFormat.channelMask = 0x0004; // FRONT_CENTER break; case 2: extFormat.channelMask = 0x0003; // FRONT_LEFT | FRONT_RIGHT break; case 3: extFormat.channelMask = 0x0103; // FRONT_LEFT | FRONT_RIGHT | BACK_CENTER break; case 4: extFormat.channelMask = 0x0033; // FRONT_LEFT | FRONT_RIGHT | BACK_LEFT | BACK_RIGHT break; default: extFormat.channelMask = 0; break; } extFormat.subFormat = mpt::UUID(static_cast(encoding), 0x0000, 0x0010, 0x800000AA00389B71ull); Write(extFormat); } } // Write text tags to the file. void WAVWriter::WriteMetatags(const FileTags &tags) { StartChunk(RIFFChunk::idLIST); const char info[] = { 'I', 'N', 'F', 'O' }; WriteArray(info); WriteTag(RIFFChunk::idINAM, tags.title); WriteTag(RIFFChunk::idIART, tags.artist); WriteTag(RIFFChunk::idIPRD, tags.album); WriteTag(RIFFChunk::idICRD, tags.year); WriteTag(RIFFChunk::idICMT, tags.comments); WriteTag(RIFFChunk::idIGNR, tags.genre); WriteTag(RIFFChunk::idTURL, tags.url); WriteTag(RIFFChunk::idISFT, tags.encoder); //WriteTag(RIFFChunk:: , tags.bpm); WriteTag(RIFFChunk::idTRCK, tags.trackno); } // Write a single tag into a open idLIST chunk void WAVWriter::WriteTag(RIFFChunk::ChunkIdentifiers id, const mpt::ustring &utext) { std::string text = mpt::ToCharset(mpt::CharsetWindows1252, utext); if(!text.empty()) { const size_t length = text.length() + 1; RIFFChunk chunk; chunk.id = static_cast(id); chunk.length = length; Write(chunk); Write(text.c_str(), length); if((length % 2u) != 0) { uint8 padding = 0; Write(padding); } } } // Write a sample loop information chunk to the file. void WAVWriter::WriteLoopInformation(const ModSample &sample) { if(!sample.uFlags[CHN_LOOP | CHN_SUSTAINLOOP] && !ModCommand::IsNote(sample.rootNote)) { return; } StartChunk(RIFFChunk::idsmpl); WAVSampleInfoChunk info; uint32 sampleRate = sample.nC5Speed; if(sampleRate == 0) { sampleRate = ModSample::TransposeToFrequency(sample.RelativeTone, sample.nFineTune); } info.ConvertToWAV(sampleRate, sample.rootNote); // Set up loops WAVSampleLoop loops[2]; if(sample.uFlags[CHN_SUSTAINLOOP]) { loops[info.numLoops++].ConvertToWAV(sample.nSustainStart, sample.nSustainEnd, sample.uFlags[CHN_PINGPONGSUSTAIN]); } if(sample.uFlags[CHN_LOOP]) { loops[info.numLoops++].ConvertToWAV(sample.nLoopStart, sample.nLoopEnd, sample.uFlags[CHN_PINGPONGLOOP]); } else if(sample.uFlags[CHN_SUSTAINLOOP]) { // Since there are no "loop types" to distinguish between sustain and normal loops, OpenMPT assumes // that the first loop is a sustain loop if there are two loops. If we only want a sustain loop, // we will have to write a second bogus loop. loops[info.numLoops++].ConvertToWAV(0, 0, false); } Write(info); for(uint32 i = 0; i < info.numLoops; i++) { Write(loops[i]); } } // Write a sample's cue points to the file. void WAVWriter::WriteCueInformation(const ModSample &sample) { StartChunk(RIFFChunk::idcue_); { const uint32 numPoints = SwapBytesLE(static_cast(CountOf(sample.cues))); Write(numPoints); } for(uint32 i = 0; i < CountOf(sample.cues); i++) { WAVCuePoint cuePoint; cuePoint.ConvertToWAV(i, sample.cues[i]); Write(cuePoint); } } // Write MPT's sample information chunk to the file. void WAVWriter::WriteExtraInformation(const ModSample &sample, MODTYPE modType, const char *sampleName) { StartChunk(RIFFChunk::idxtra); WAVExtraChunk mptInfo; mptInfo.ConvertToWAV(sample, modType); Write(mptInfo); if(sampleName != nullptr) { // Write sample name (clipboard only) char name[MAX_SAMPLENAME]; mpt::String::Write(name, sampleName, MAX_SAMPLENAME); WriteArray(name); char filename[MAX_SAMPLEFILENAME]; mpt::String::Write(filename, sample.filename); WriteArray(filename); } } #endif // MODPLUG_NO_FILESAVE OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/OggStream.h0000644000372100037210000000321013070446042020132 00000000000000/* * OggStream.h * ----------- * Purpose: Basic Ogg stream parsing functionality * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "../common/Endianness.h" #include "../common/mptIO.h" #include "../common/FileReaderFwd.h" OPENMPT_NAMESPACE_BEGIN namespace Ogg { struct PageHeader { char capture_pattern[4]; // "OggS" uint8le version; uint8le header_type; uint64le granule_position; uint32le bitstream_serial_number; uint32le page_seqauence_number; uint32le CRC_checksum; uint8le page_segments; }; } // namespace Ogg MPT_BINARY_STRUCT(Ogg::PageHeader, 27) namespace Ogg { struct PageInfo { PageHeader header; uint8 segment_table[255]; PageInfo() { MemsetZero(header); MemsetZero(segment_table); } uint16 GetPagePhysicalSize() const; uint16 GetPageDataSize() const; }; // returns false on EOF bool AdvanceToPageMagic(FileReader &file); bool ReadPage(FileReader &file, PageInfo &pageInfo, std::vector &pageData); bool ReadPageAndSkipJunk(FileReader &file, PageInfo &pageInfo, std::vector &pageData); bool UpdatePageCRC(PageInfo &pageInfo, const std::vector &pageData); template bool WritePage(Tfile & f, const PageInfo &pageInfo, const std::vector &pageData) { if(!mpt::IO::Write(f, pageInfo.header)) { return false; } if(!mpt::IO::WriteRaw(f, pageInfo.segment_table, pageInfo.header.page_segments)) { return false; } if(!mpt::IO::WriteRaw(f, pageData.data(), pageData.size())) { return false; } return true; } } // namespace Ogg OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/RowVisitor.h0000644000372100037210000000531413161656666020420 00000000000000/* * RowVisitor.h * ------------ * Purpose: Class for managing which rows of a song has already been visited. Useful for detecting backwards jumps, loops, etc. * Notes : See implementation file. * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include #include "Snd_defs.h" OPENMPT_NAMESPACE_BEGIN class CSoundFile; class ModSequence; class RowVisitor { protected: // Memory for every row in the module if it has been visited or not. std::vector> m_visitedRows; // Memory of visited rows (including their order) to reset pattern loops. std::vector m_visitOrder; const CSoundFile &m_sndFile; ORDERINDEX m_currentOrder; SEQUENCEINDEX m_sequence; public: RowVisitor(const CSoundFile &sf, SEQUENCEINDEX sequence = SEQUENCEINDEX_INVALID); // Resize / Clear the row vector. // If reset is true, the vector is not only resized to the required dimensions, but also completely cleared (i.e. all visited rows are unset). void Initialize(bool reset); // Mark a row as visited. void Visit(ORDERINDEX ord, ROWINDEX row) { SetVisited(ord, row, true); }; // Mark a row as not visited. void Unvisit(ORDERINDEX ord, ROWINDEX row) { SetVisited(ord, row, false); }; // Returns whether a given row has been visited yet. // If autoSet is true, the queried row will automatically be marked as visited. // Use this parameter instead of consecutive IsRowVisited / SetRowVisited calls. bool IsVisited(ORDERINDEX ord, ROWINDEX row, bool autoSet); // Get the needed vector size for a given pattern. size_t GetVisitedRowsVectorSize(PATTERNINDEX pattern) const; // Find the first row that has not been played yet. // The order and row is stored in the order and row variables on success, on failure they contain invalid values. // If fastSearch is true (default), only the first row of each pattern is looked at, otherwise every row is examined. // Function returns true on success. bool GetFirstUnvisitedRow(ORDERINDEX &order, ROWINDEX &row, bool fastSearch) const; // Retrieve visited rows vector from another RowVisitor object. void Set(const RowVisitor &other) { m_visitedRows = other.m_visitedRows; } // Set all rows of a previous pattern loop as unvisited. void ResetPatternLoop(ORDERINDEX ord, ROWINDEX startRow); protected: // (Un)sets a given row as visited. // order, row - which row should be (un)set // If visited is true, the row will be set as visited. void SetVisited(ORDERINDEX ord, ROWINDEX row, bool visited); // Add a row to the visited row memory for this pattern. void AddVisitedRow(ORDERINDEX ord, ROWINDEX row); const ModSequence &Order() const; }; OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Loaders.h0000644000372100037210000000533313161656666017663 00000000000000/* * Loaders.h * --------- * Purpose: Common functions for module loaders * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "../common/misc_util.h" #include "../common/FileReader.h" #include "Sndfile.h" #include "SampleIO.h" OPENMPT_NAMESPACE_BEGIN // Macros to create magic bytes in little-endian format #define MAGIC4LE(a, b, c, d) static_cast((static_cast(d) << 24) | (static_cast(c) << 16) | (static_cast(b) << 8) | static_cast(a)) #define MAGIC2LE(a, b) static_cast((static_cast(b) << 8) | static_cast(a)) // Macros to create magic bytes in big-endian format #define MAGIC4BE(a, b, c, d) static_cast((static_cast(a) << 24) | (static_cast(b) << 16) | (static_cast(c) << 8) | static_cast(d)) #define MAGIC2BE(a, b) static_cast((static_cast(a) << 8) | static_cast(b)) // Read 'howMany' order items from an array. // 'stopIndex' is treated as '---', 'ignoreIndex' is treated as '+++'. If the format doesn't support such indices, just pass ORDERINDEX_INVALID. template bool ReadOrderFromArray(ModSequence &order, const T(&orders)[arraySize], size_t howMany = arraySize, uint16 stopIndex = ORDERINDEX_INVALID, uint16 ignoreIndex = ORDERINDEX_INVALID) { STATIC_ASSERT(mpt::is_binary_safe::value); LimitMax(howMany, arraySize); LimitMax(howMany, MAX_ORDERS); ORDERINDEX readEntries = static_cast(howMany); order.resize(readEntries); for(int i = 0; i < readEntries; i++) { PATTERNINDEX pat = static_cast(orders[i]); if(pat == stopIndex) pat = order.GetInvalidPatIndex(); else if(pat == ignoreIndex) pat = order.GetIgnoreIndex(); order.at(i) = pat; } return true; } // Read 'howMany' order items as integers with defined endianness from a file. // 'stopIndex' is treated as '---', 'ignoreIndex' is treated as '+++'. If the format doesn't support such indices, just pass ORDERINDEX_INVALID. template bool ReadOrderFromFile(ModSequence &order, FileReader &file, size_t howMany, uint16 stopIndex = ORDERINDEX_INVALID, uint16 ignoreIndex = ORDERINDEX_INVALID) { STATIC_ASSERT(mpt::is_binary_safe::value); if(!file.CanRead(howMany * sizeof(T))) return false; LimitMax(howMany, MAX_ORDERS); ORDERINDEX readEntries = static_cast(howMany); order.resize(readEntries); T patF; for(auto &pat : order) { file.ReadStruct(patF); pat = static_cast(patF); if(pat == stopIndex) pat = order.GetInvalidPatIndex(); else if(pat == ignoreIndex) pat = order.GetIgnoreIndex(); } return true; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/SampleFormats.cpp0000644000372100037210000021520113231227072021356 00000000000000/* * SampleFormats.cpp * ----------------- * Purpose: Code for loading various more or less common sample and instrument formats. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Sndfile.h" #include "mod_specifications.h" #ifdef MODPLUG_TRACKER #include "../mptrack/Moddoc.h" #include "../mptrack/TrackerSettings.h" #include "Dlsbank.h" #endif //MODPLUG_TRACKER #include "../soundlib/AudioCriticalSection.h" #ifndef MODPLUG_NO_FILESAVE #include "../common/mptFileIO.h" #endif #include "../common/misc_util.h" #include "Tagging.h" #include "ITTools.h" #include "XMTools.h" #include "S3MTools.h" #include "WAVTools.h" #include "../common/version.h" #include "Loaders.h" #include "ChunkReader.h" #include "modsmp_ctrl.h" #include "../soundbase/SampleFormatConverters.h" #include "../soundbase/SampleFormatCopy.h" #include "../soundlib/ModSampleCopy.h" OPENMPT_NAMESPACE_BEGIN bool CSoundFile::ReadSampleFromFile(SAMPLEINDEX nSample, FileReader &file, bool mayNormalize, bool includeInstrumentFormats) { if(!nSample || nSample >= MAX_SAMPLES) return false; if(!ReadWAVSample(nSample, file, mayNormalize) && !(includeInstrumentFormats && ReadXISample(nSample, file)) && !(includeInstrumentFormats && ReadITISample(nSample, file)) && !ReadAIFFSample(nSample, file, mayNormalize) && !ReadITSSample(nSample, file) && !(includeInstrumentFormats && ReadPATSample(nSample, file)) && !ReadIFFSample(nSample, file) && !ReadS3ISample(nSample, file) && !ReadAUSample(nSample, file, mayNormalize) && !ReadFLACSample(nSample, file) && !ReadOpusSample(nSample, file) && !ReadVorbisSample(nSample, file) && !ReadMP3Sample(nSample, file) && !ReadMediaFoundationSample(nSample, file) ) { return false; } if(nSample > GetNumSamples()) { m_nSamples = nSample; } return true; } bool CSoundFile::ReadInstrumentFromFile(INSTRUMENTINDEX nInstr, FileReader &file, bool mayNormalize) { if ((!nInstr) || (nInstr >= MAX_INSTRUMENTS)) return false; if(!ReadITIInstrument(nInstr, file) && !ReadXIInstrument(nInstr, file) && !ReadPATInstrument(nInstr, file) && !ReadSFZInstrument(nInstr, file) // Generic read && !ReadSampleAsInstrument(nInstr, file, mayNormalize)) { bool ok = false; #ifdef MODPLUG_TRACKER CDLSBank bank; if(bank.Open(file)) { ok = bank.ExtractInstrument(*this, nInstr, 0, 0); } #endif // MODPLUG_TRACKER if(!ok) return false; } if(nInstr > GetNumInstruments()) m_nInstruments = nInstr; return true; } bool CSoundFile::ReadSampleAsInstrument(INSTRUMENTINDEX nInstr, FileReader &file, bool mayNormalize) { // Scanning free sample SAMPLEINDEX nSample = GetNextFreeSample(nInstr); // may also return samples which are only referenced by the current instrument if(nSample == SAMPLEINDEX_INVALID) { return false; } // Loading Instrument ModInstrument *pIns = new (std::nothrow) ModInstrument(nSample); if(pIns == nullptr) { return false; } if(!ReadSampleFromFile(nSample, file, mayNormalize, false)) { delete pIns; return false; } // Remove all samples which are only referenced by the old instrument, except for the one we just loaded our new sample into. RemoveInstrumentSamples(nInstr, nSample); // Replace the instrument DestroyInstrument(nInstr, doNoDeleteAssociatedSamples); Instruments[nInstr] = pIns; #if defined(MPT_ENABLE_FILEIO) && defined(MPT_EXTERNAL_SAMPLES) SetSamplePath(nSample, file.GetFileName()); #endif return true; } bool CSoundFile::DestroyInstrument(INSTRUMENTINDEX nInstr, deleteInstrumentSamples removeSamples) { if(nInstr == 0 || nInstr >= MAX_INSTRUMENTS || !Instruments[nInstr]) return true; if(removeSamples == deleteAssociatedSamples) { RemoveInstrumentSamples(nInstr); } CriticalSection cs; ModInstrument *pIns = Instruments[nInstr]; Instruments[nInstr] = nullptr; for(auto &chn : m_PlayState.Chn) { if(chn.pModInstrument == pIns) chn.pModInstrument = nullptr; } delete pIns; return true; } // Remove all unused samples from the given nInstr and keep keepSample if provided bool CSoundFile::RemoveInstrumentSamples(INSTRUMENTINDEX nInstr, SAMPLEINDEX keepSample) { if(Instruments[nInstr] == nullptr) { return false; } std::vector keepSamples(GetNumSamples() + 1, true); // Check which samples are used by the instrument we are going to nuke. auto referencedSamples = Instruments[nInstr]->GetSamples(); for(auto sample : referencedSamples) { if(sample <= GetNumSamples()) { keepSamples[sample] = false; } } // If we want to keep a specific sample, do so. if(keepSample != SAMPLEINDEX_INVALID) { if(keepSample <= GetNumSamples()) { keepSamples[keepSample] = true; } } // Check if any of those samples are referenced by other instruments as well, in which case we want to keep them of course. for(INSTRUMENTINDEX nIns = 1; nIns <= GetNumInstruments(); nIns++) if (Instruments[nIns] != nullptr && nIns != nInstr) { Instruments[nIns]->GetSamples(keepSamples); } // Now nuke the selected samples. RemoveSelectedSamples(keepSamples); return true; } //////////////////////////////////////////////////////////////////////////////// // // I/O From another song // bool CSoundFile::ReadInstrumentFromSong(INSTRUMENTINDEX targetInstr, const CSoundFile &srcSong, INSTRUMENTINDEX sourceInstr) { if ((!sourceInstr) || (sourceInstr > srcSong.GetNumInstruments()) || (targetInstr >= MAX_INSTRUMENTS) || (!srcSong.Instruments[sourceInstr])) { return false; } if (m_nInstruments < targetInstr) m_nInstruments = targetInstr; ModInstrument *pIns = new (std::nothrow) ModInstrument(); if(pIns == nullptr) { return false; } DestroyInstrument(targetInstr, deleteAssociatedSamples); Instruments[targetInstr] = pIns; *pIns = *srcSong.Instruments[sourceInstr]; std::vector sourceSample; // Sample index in source song std::vector targetSample; // Sample index in target song SAMPLEINDEX targetIndex = 0; // Next index for inserting sample for(auto &sample : pIns->Keyboard) { const SAMPLEINDEX sourceIndex = sample; if(sourceIndex > 0 && sourceIndex <= srcSong.GetNumSamples()) { const auto entry = std::find(sourceSample.cbegin(), sourceSample.cend(), sourceIndex); if(entry == sourceSample.end()) { // Didn't consider this sample yet, so add it to our map. targetIndex = GetNextFreeSample(targetInstr, targetIndex + 1); if(targetIndex <= GetModSpecifications().samplesMax) { sourceSample.push_back(sourceIndex); targetSample.push_back(targetIndex); sample = targetIndex; } else { sample = 0; } } else { // Sample reference has already been created, so only need to update the sample map. sample = *(entry - sourceSample.begin() + targetSample.begin()); } } else { // Invalid or no source sample sample = 0; } } #ifdef MODPLUG_TRACKER if(!strcmp(pIns->filename, "") && srcSong.GetpModDoc() != nullptr) { mpt::String::Copy(pIns->filename, srcSong.GetpModDoc()->GetPathNameMpt().GetFullFileName().ToLocale()); } #endif pIns->Convert(srcSong.GetType(), GetType()); // Copy all referenced samples over for(size_t i = 0; i < targetSample.size(); i++) { ReadSampleFromSong(targetSample[i], srcSong, sourceSample[i]); } return true; } bool CSoundFile::ReadSampleFromSong(SAMPLEINDEX targetSample, const CSoundFile &srcSong, SAMPLEINDEX sourceSample) { if(!sourceSample || sourceSample > srcSong.GetNumSamples() || (targetSample >= GetModSpecifications().samplesMax && targetSample > GetNumSamples())) { return false; } DestroySampleThreadsafe(targetSample); const ModSample &sourceSmp = srcSong.GetSample(sourceSample); ModSample &targetSmp = GetSample(targetSample); if(GetNumSamples() < targetSample) m_nSamples = targetSample; targetSmp = sourceSmp; strcpy(m_szNames[targetSample], srcSong.m_szNames[sourceSample]); if(sourceSmp.pSample) { targetSmp.pSample = nullptr; // Don't want to delete the original sample! if(targetSmp.AllocateSample()) { SmpLength nSize = sourceSmp.GetSampleSizeInBytes(); memcpy(targetSmp.pSample, sourceSmp.pSample, nSize); targetSmp.PrecomputeLoops(*this, false); } // Remember on-disk path (for MPTM files), but don't implicitely enable on-disk storage // (we really don't want this for e.g. duplicating samples or splitting stereo samples) #ifdef MPT_EXTERNAL_SAMPLES SetSamplePath(targetSample, srcSong.GetSamplePath(sourceSample)); #endif targetSmp.uFlags.reset(SMP_KEEPONDISK); } #ifdef MODPLUG_TRACKER if(!strcmp(targetSmp.filename, "") && srcSong.GetpModDoc() != nullptr) { mpt::String::Copy(targetSmp.filename, mpt::ToCharset(GetCharsetInternal(), srcSong.GetpModDoc()->GetTitle())); } #endif targetSmp.Convert(srcSong.GetType(), GetType()); return true; } //////////////////////////////////////////////////////////////////////// // IMA ADPCM Support for WAV files static bool IMAADPCMUnpack16(int16 *target, SmpLength sampleLen, FileReader file, uint16 blockAlign, uint32 numChannels) { static const int32 IMAIndexTab[8] = { -1, -1, -1, -1, 2, 4, 6, 8 }; static const int32 IMAUnpackTable[90] = { 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767, 0 }; if(target == nullptr || blockAlign < 4u * numChannels) return false; SmpLength samplePos = 0; sampleLen *= numChannels; while(file.CanRead(4u * numChannels) && samplePos < sampleLen) { FileReader block = file.ReadChunk(blockAlign); FileReader::PinnedRawDataView blockView = block.GetPinnedRawDataView(); const mpt::byte *data = blockView.data(); const uint32 blockSize = static_cast(blockView.size()); for(uint32 chn = 0; chn < numChannels; chn++) { // Block header int32 value = block.ReadInt16LE(); int32 nIndex = block.ReadUint8(); Limit(nIndex, 0, 89); block.Skip(1); SmpLength smpPos = samplePos + chn; uint32 dataPos = (numChannels + chn) * 4; // Block data while(smpPos <= (sampleLen - 8) && dataPos <= (blockSize - 4)) { for(uint32 i = 0; i < 8; i++) { uint8 delta = data[dataPos]; if(i & 1) { delta >>= 4; dataPos++; } else { delta &= 0x0F; } int32 v = IMAUnpackTable[nIndex] >> 3; if (delta & 1) v += IMAUnpackTable[nIndex] >> 2; if (delta & 2) v += IMAUnpackTable[nIndex] >> 1; if (delta & 4) v += IMAUnpackTable[nIndex]; if (delta & 8) value -= v; else value += v; nIndex += IMAIndexTab[delta & 7]; Limit(nIndex, 0, 88); Limit(value, -32768, 32767); target[smpPos] = static_cast(value); smpPos += numChannels; } dataPos += (numChannels - 1) * 4u; } } samplePos += ((blockSize - (numChannels * 4u)) * 2u); } return true; } //////////////////////////////////////////////////////////////////////////////// // WAV Open bool CSoundFile::ReadWAVSample(SAMPLEINDEX nSample, FileReader &file, bool mayNormalize, FileReader *wsmpChunk) { WAVReader wavFile(file); if(!wavFile.IsValid() || wavFile.GetNumChannels() == 0 || wavFile.GetNumChannels() > 2 || (wavFile.GetBitsPerSample() == 0 && wavFile.GetSampleFormat() != WAVFormatChunk::fmtMP3) || (wavFile.GetBitsPerSample() > 64) || (wavFile.GetSampleFormat() != WAVFormatChunk::fmtPCM && wavFile.GetSampleFormat() != WAVFormatChunk::fmtFloat && wavFile.GetSampleFormat() != WAVFormatChunk::fmtIMA_ADPCM && wavFile.GetSampleFormat() != WAVFormatChunk::fmtMP3 && wavFile.GetSampleFormat() != WAVFormatChunk::fmtALaw && wavFile.GetSampleFormat() != WAVFormatChunk::fmtULaw)) { return false; } DestroySampleThreadsafe(nSample); strcpy(m_szNames[nSample], ""); ModSample &sample = Samples[nSample]; sample.Initialize(); sample.nLength = wavFile.GetSampleLength(); sample.nC5Speed = wavFile.GetSampleRate(); wavFile.ApplySampleSettings(sample, m_szNames[nSample]); FileReader sampleChunk = wavFile.GetSampleData(); SampleIO sampleIO( SampleIO::_8bit, (wavFile.GetNumChannels() > 1) ? SampleIO::stereoInterleaved : SampleIO::mono, SampleIO::littleEndian, SampleIO::signedPCM); if(wavFile.GetSampleFormat() == WAVFormatChunk::fmtIMA_ADPCM && wavFile.GetNumChannels() <= 2) { // IMA ADPCM 4:1 LimitMax(sample.nLength, MAX_SAMPLE_LENGTH); sample.uFlags.set(CHN_16BIT); sample.uFlags.set(CHN_STEREO, wavFile.GetNumChannels() == 2); if(!sample.AllocateSample()) { return false; } IMAADPCMUnpack16(sample.pSample16, sample.nLength, sampleChunk, wavFile.GetBlockAlign(), wavFile.GetNumChannels()); sample.PrecomputeLoops(*this, false); } else if(wavFile.GetSampleFormat() == WAVFormatChunk::fmtMP3) { // MP3 in WAV return ReadMP3Sample(nSample, sampleChunk, true) || ReadMediaFoundationSample(nSample, sampleChunk, true); } else if(!wavFile.IsExtensibleFormat() && wavFile.MayBeCoolEdit16_8() && wavFile.GetSampleFormat() == WAVFormatChunk::fmtPCM && wavFile.GetBitsPerSample() == 32 && wavFile.GetBlockAlign() == wavFile.GetNumChannels() * 4) { // Syntrillium Cool Edit hack to store IEEE 32bit floating point // Format is described as 32bit integer PCM contained in 32bit blocks and an WAVEFORMATEX extension size of 2 which contains a single 16 bit little endian value of 1. // (This is parsed in WAVTools.cpp and returned via MayBeCoolEdit16_8()). // The data actually stored in this case is little endian 32bit floating point PCM with 2**15 full scale. // Cool Edit calls this format "16.8 float". sampleIO |= SampleIO::_32bit; sampleIO |= SampleIO::floatPCM15; sampleIO.ReadSample(sample, sampleChunk); } else if(!wavFile.IsExtensibleFormat() && wavFile.GetSampleFormat() == WAVFormatChunk::fmtPCM && wavFile.GetBitsPerSample() == 24 && wavFile.GetBlockAlign() == wavFile.GetNumChannels() * 4) { // Syntrillium Cool Edit hack to store IEEE 32bit floating point // Format is described as 24bit integer PCM contained in 32bit blocks. // The data actually stored in this case is little endian 32bit floating point PCM with 2**23 full scale. // Cool Edit calls this format "24.0 float". sampleIO |= SampleIO::_32bit; sampleIO |= SampleIO::floatPCM23; sampleIO.ReadSample(sample, sampleChunk); } else if(wavFile.GetSampleFormat() == WAVFormatChunk::fmtALaw || wavFile.GetSampleFormat() == WAVFormatChunk::fmtULaw) { // a-law / u-law sampleIO |= SampleIO::_16bit; sampleIO |= wavFile.GetSampleFormat() == WAVFormatChunk::fmtALaw ? SampleIO::aLaw : SampleIO::uLaw; sampleIO.ReadSample(sample, sampleChunk); } else { // PCM / Float SampleIO::Bitdepth bitDepth; switch((wavFile.GetBitsPerSample() - 1) / 8u) { default: case 0: bitDepth = SampleIO::_8bit; break; case 1: bitDepth = SampleIO::_16bit; break; case 2: bitDepth = SampleIO::_24bit; break; case 3: bitDepth = SampleIO::_32bit; break; case 7: bitDepth = SampleIO::_64bit; break; } sampleIO |= bitDepth; if(wavFile.GetBitsPerSample() <= 8) sampleIO |= SampleIO::unsignedPCM; if(wavFile.GetSampleFormat() == WAVFormatChunk::fmtFloat) sampleIO |= SampleIO::floatPCM; if(mayNormalize) sampleIO.MayNormalize(); sampleIO.ReadSample(sample, sampleChunk); } if(wsmpChunk != nullptr) { // DLS WSMP chunk *wsmpChunk = wavFile.GetWsmpChunk(); } sample.Convert(MOD_TYPE_IT, GetType()); sample.PrecomputeLoops(*this, false); return true; } /////////////////////////////////////////////////////////////// // Save WAV #ifndef MODPLUG_NO_FILESAVE bool CSoundFile::SaveWAVSample(SAMPLEINDEX nSample, const mpt::PathString &filename) const { mpt::ofstream f(filename, std::ios::binary); if(!f) { return false; } WAVWriter file(&f); if(!file.IsValid()) { return false; } const ModSample &sample = Samples[nSample]; file.WriteFormat(sample.GetSampleRate(GetType()), sample.GetElementarySampleSize() * 8, sample.GetNumChannels(), WAVFormatChunk::fmtPCM); // Write sample data file.StartChunk(RIFFChunk::iddata); file.Skip(SampleIO( sample.uFlags[CHN_16BIT] ? SampleIO::_16bit : SampleIO::_8bit, sample.uFlags[CHN_STEREO] ? SampleIO::stereoInterleaved : SampleIO::mono, SampleIO::littleEndian, sample.uFlags[CHN_16BIT] ? SampleIO::signedPCM : SampleIO::unsignedPCM) .WriteSample(f, sample)); file.WriteLoopInformation(sample); file.WriteExtraInformation(sample, GetType()); if(sample.HasCustomCuePoints()) { file.WriteCueInformation(sample); } FileTags tags; tags.title = mpt::ToUnicode(GetCharsetInternal(), m_szNames[nSample]); tags.encoder = mpt::ToUnicode(mpt::CharsetUTF8, MptVersion::GetOpenMPTVersionStr()); file.WriteMetatags(tags); return true; } #endif // MODPLUG_NO_FILESAVE #ifndef MODPLUG_NO_FILESAVE /////////////////////////////////////////////////////////////// // Save RAW bool CSoundFile::SaveRAWSample(SAMPLEINDEX nSample, const mpt::PathString &filename) const { mpt::ofstream f(filename, std::ios::binary); if(!f) { return false; } const ModSample &sample = Samples[nSample]; SampleIO( sample.uFlags[CHN_16BIT] ? SampleIO::_16bit : SampleIO::_8bit, sample.uFlags[CHN_STEREO] ? SampleIO::stereoInterleaved : SampleIO::mono, SampleIO::littleEndian, SampleIO::signedPCM) .WriteSample(f, sample); return true; } #endif // MODPLUG_NO_FILESAVE ///////////////////////////////////////////////////////////// // GUS Patches struct GF1PatchFileHeader { char magic[8]; // "GF1PATCH" char version[4]; // "100", or "110" char id[10]; // "ID#000002" char copyright[60]; // Copyright uint8le numInstr; // Number of instruments in patch uint8le voices; // Number of voices, usually 14 uint8le channels; // Number of wav channels that can be played concurently to the patch uint16le numSamples; // Total number of waveforms for all the .PAT uint16le volume; // Master volume uint32le dataSize; char reserved2[36]; }; MPT_BINARY_STRUCT(GF1PatchFileHeader, 129) struct GF1Instrument { uint16le id; // Instrument id: 0-65535 char name[16]; // Name of instrument. Gravis doesn't seem to use it uint32le size; // Number of bytes for the instrument with header. (To skip to next instrument) uint8 layers; // Number of layers in instrument: 1-4 char reserved[40]; }; MPT_BINARY_STRUCT(GF1Instrument, 63) struct GF1SampleHeader { char name[7]; // null terminated string. name of the wave. uint8le fractions; // Start loop point fraction in 4 bits + End loop point fraction in the 4 other bits. uint32le length; // total size of wavesample. limited to 65535 now by the drivers, not the card. uint32le loopstart; // start loop position in the wavesample uint32le loopend; // end loop position in the wavesample uint16le freq; // Rate at which the wavesample has been sampled uint32le low_freq, high_freq, root_freq; // check note.h for the correspondance. int16le finetune; // fine tune. -512 to +512, EXCLUDING 0 cause it is a multiplier. 512 is one octave off, and 1 is a neutral value uint8le balance; // Balance: 0-15. 0=full left, 15 = full right uint8le env_rate[6]; // attack rates uint8le env_volume[6]; // attack volumes uint8le tremolo_sweep, tremolo_rate, tremolo_depth; uint8le vibrato_sweep, vibrato_rate, vibrato_depth; uint8le flags; int16le scale_frequency; // Note uint16le scale_factor; // 0...2048 (1024 is normal) or 0...2 char reserved[36]; }; MPT_BINARY_STRUCT(GF1SampleHeader, 96) // -- GF1 Envelopes -- // // It can be represented like this (the envelope is totally bogus, it is // just to show the concept): // // | // | /----` | | // | /------/ `\ | | | | | // | / \ | | | | | // | / \ | | | | | // |/ \ | | | | | // ---------------------------- | | | | | | // <---> attack rate 0 0 1 2 3 4 5 amplitudes // <----> attack rate 1 // <> attack rate 2 // <--> attack rate 3 // <> attack rate 4 // <-----> attack rate 5 // // -- GF1 Flags -- // // bit 0: 8/16 bit // bit 1: Signed/Unsigned // bit 2: off/on looping // bit 3: off/on bidirectionnal looping // bit 4: off/on backward looping // bit 5: off/on sustaining (3rd point in env.) // bit 6: off/on envelopes // bit 7: off/on clamped release (6th point, env) struct GF1Layer { uint8le previous; // If !=0 the wavesample to use is from the previous layer. The waveheader is still needed uint8le id; // Layer id: 0-3 uint32le size; // data size in bytes in the layer, without the header. to skip to next layer for example: uint8le samples; // number of wavesamples char reserved[40]; }; MPT_BINARY_STRUCT(GF1Layer, 47) static double PatchFreqToNote(uint32 nFreq) { return std::log(nFreq / 2044.0) * (12.0 * 1.44269504088896340736); // 1.0/std::log(2.0) } static int32 PatchFreqToNoteInt(uint32 nFreq) { return Util::Round(PatchFreqToNote(nFreq)); } static void PatchToSample(CSoundFile *that, SAMPLEINDEX nSample, GF1SampleHeader &sampleHeader, FileReader &file) { ModSample &sample = that->GetSample(nSample); file.ReadStruct(sampleHeader); sample.Initialize(); if(sampleHeader.flags & 4) sample.uFlags.set(CHN_LOOP); if(sampleHeader.flags & 8) sample.uFlags.set(CHN_PINGPONGLOOP); if(sampleHeader.flags & 16) sample.uFlags.set(CHN_REVERSE); sample.nLength = sampleHeader.length; sample.nLoopStart = sampleHeader.loopstart; sample.nLoopEnd = sampleHeader.loopend; sample.nC5Speed = sampleHeader.freq; sample.nPan = (sampleHeader.balance * 256 + 8) / 15; if(sample.nPan > 256) sample.nPan = 128; else sample.uFlags.set(CHN_PANNING); sample.nVibType = VIB_SINE; sample.nVibSweep = sampleHeader.vibrato_sweep; sample.nVibDepth = sampleHeader.vibrato_depth; sample.nVibRate = sampleHeader.vibrato_rate / 4; if(sampleHeader.scale_factor) { sample.Transpose((84.0 - PatchFreqToNote(sampleHeader.root_freq)) / 12.0); } SampleIO sampleIO( SampleIO::_8bit, SampleIO::mono, SampleIO::littleEndian, (sampleHeader.flags & 2) ? SampleIO::unsignedPCM : SampleIO::signedPCM); if(sampleHeader.flags & 1) { sampleIO |= SampleIO::_16bit; sample.nLength /= 2; sample.nLoopStart /= 2; sample.nLoopEnd /= 2; } sampleIO.ReadSample(sample, file); sample.Convert(MOD_TYPE_IT, that->GetType()); sample.PrecomputeLoops(*that, false); mpt::String::Read(that->m_szNames[nSample], sampleHeader.name); } bool CSoundFile::ReadPATSample(SAMPLEINDEX nSample, FileReader &file) { file.Rewind(); GF1PatchFileHeader fileHeader; GF1Instrument instrHeader; // We only support one instrument GF1Layer layerHeader; if(!file.ReadStruct(fileHeader) || memcmp(fileHeader.magic, "GF1PATCH", 8) || (memcmp(fileHeader.version, "110\0", 4) && memcmp(fileHeader.version, "100\0", 4)) || memcmp(fileHeader.id, "ID#000002\0", 10) || !fileHeader.numInstr || !fileHeader.numSamples || !file.ReadStruct(instrHeader) //|| !instrHeader.layers // DOO.PAT has 0 layers || !file.ReadStruct(layerHeader) || !layerHeader.samples) { return false; } DestroySampleThreadsafe(nSample); GF1SampleHeader sampleHeader; PatchToSample(this, nSample, sampleHeader, file); if(instrHeader.name[0] > ' ') { mpt::String::Read(m_szNames[nSample], instrHeader.name); } return true; } // PAT Instrument bool CSoundFile::ReadPATInstrument(INSTRUMENTINDEX nInstr, FileReader &file) { file.Rewind(); GF1PatchFileHeader fileHeader; GF1Instrument instrHeader; // We only support one instrument GF1Layer layerHeader; if(!file.ReadStruct(fileHeader) || memcmp(fileHeader.magic, "GF1PATCH", 8) || (memcmp(fileHeader.version, "110\0", 4) && memcmp(fileHeader.version, "100\0", 4)) || memcmp(fileHeader.id, "ID#000002\0", 10) || !fileHeader.numInstr || !fileHeader.numSamples || !file.ReadStruct(instrHeader) //|| !instrHeader.layers // DOO.PAT has 0 layers || !file.ReadStruct(layerHeader) || !layerHeader.samples) { return false; } ModInstrument *pIns = new (std::nothrow) ModInstrument(); if(pIns == nullptr) { return false; } DestroyInstrument(nInstr, deleteAssociatedSamples); if (nInstr > m_nInstruments) m_nInstruments = nInstr; Instruments[nInstr] = pIns; mpt::String::Read(pIns->name, instrHeader.name); pIns->nFadeOut = 2048; if(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) { pIns->nNNA = NNA_NOTEOFF; pIns->nDNA = DNA_NOTEFADE; } SAMPLEINDEX nextSample = 0; int32 nMinSmpNote = 0xFF; SAMPLEINDEX nMinSmp = 0; for(uint8 smp = 0; smp < layerHeader.samples; smp++) { // Find a free sample nextSample = GetNextFreeSample(nInstr, nextSample + 1); if(nextSample == SAMPLEINDEX_INVALID) break; if(m_nSamples < nextSample) m_nSamples = nextSample; if(!nMinSmp) nMinSmp = nextSample; // Load it GF1SampleHeader sampleHeader; PatchToSample(this, nextSample, sampleHeader, file); int32 nMinNote = (sampleHeader.low_freq > 100) ? PatchFreqToNoteInt(sampleHeader.low_freq) : 0; int32 nMaxNote = (sampleHeader.high_freq > 100) ? PatchFreqToNoteInt(sampleHeader.high_freq) : NOTE_MAX; int32 nBaseNote = (sampleHeader.root_freq > 100) ? PatchFreqToNoteInt(sampleHeader.root_freq) : -1; if(!sampleHeader.scale_factor && layerHeader.samples == 1) { nMinNote = 0; nMaxNote = NOTE_MAX; } // Fill Note Map for(int32 k = 0; k < NOTE_MAX; k++) { if(k == nBaseNote || (!pIns->Keyboard[k] && k >= nMinNote && k <= nMaxNote)) { if(!sampleHeader.scale_factor) pIns->NoteMap[k] = NOTE_MIDDLEC; pIns->Keyboard[k] = nextSample; if(k < nMinSmpNote) { nMinSmpNote = k; nMinSmp = nextSample; } } } } if(nMinSmp) { // Fill note map and missing samples for(uint8 k = 0; k < NOTE_MAX; k++) { if(!pIns->NoteMap[k]) pIns->NoteMap[k] = k + 1; if(!pIns->Keyboard[k]) { pIns->Keyboard[k] = nMinSmp; } else { nMinSmp = pIns->Keyboard[k]; } } } pIns->Sanitize(MOD_TYPE_IT); pIns->Convert(MOD_TYPE_IT, GetType()); return true; } ///////////////////////////////////////////////////////////// // S3I Samples bool CSoundFile::ReadS3ISample(SAMPLEINDEX nSample, FileReader &file) { file.Rewind(); S3MSampleHeader sampleHeader; if(!file.ReadStruct(sampleHeader) || sampleHeader.sampleType != S3MSampleHeader::typePCM || memcmp(sampleHeader.magic, "SCRS", 4) || !file.Seek((sampleHeader.dataPointer[1] << 4) | (sampleHeader.dataPointer[2] << 12) | (sampleHeader.dataPointer[0] << 20))) { return false; } DestroySampleThreadsafe(nSample); ModSample &sample = Samples[nSample]; sampleHeader.ConvertToMPT(sample); mpt::String::Read(m_szNames[nSample], sampleHeader.name); sampleHeader.GetSampleFormat(false).ReadSample(sample, file); sample.Convert(MOD_TYPE_S3M, GetType()); sample.PrecomputeLoops(*this, false); return true; } ///////////////////////////////////////////////////////////// // XI Instruments bool CSoundFile::ReadXIInstrument(INSTRUMENTINDEX nInstr, FileReader &file) { file.Rewind(); XIInstrumentHeader fileHeader; if(!file.ReadStruct(fileHeader) || memcmp(fileHeader.signature, "Extended Instrument: ", 21) || fileHeader.version != XIInstrumentHeader::fileVersion || fileHeader.eof != 0x1A) { return false; } ModInstrument *pIns = new (std::nothrow) ModInstrument(); if(pIns == nullptr) { return false; } DestroyInstrument(nInstr, deleteAssociatedSamples); if(nInstr > m_nInstruments) { m_nInstruments = nInstr; } Instruments[nInstr] = pIns; fileHeader.ConvertToMPT(*pIns); // Translate sample map and find available sample slots std::vector sampleMap(fileHeader.numSamples); SAMPLEINDEX maxSmp = 0; for(size_t i = 0 + 12; i < 96 + 12; i++) { if(pIns->Keyboard[i] >= fileHeader.numSamples) { continue; } if(sampleMap[pIns->Keyboard[i]] == 0) { // Find slot for this sample maxSmp = GetNextFreeSample(nInstr, maxSmp + 1); if(maxSmp != SAMPLEINDEX_INVALID) { sampleMap[pIns->Keyboard[i]] = maxSmp; } } pIns->Keyboard[i] = sampleMap[pIns->Keyboard[i]]; } if(m_nSamples < maxSmp) { m_nSamples = maxSmp; } std::vector sampleFlags(fileHeader.numSamples); // Read sample headers for(SAMPLEINDEX i = 0; i < fileHeader.numSamples; i++) { XMSample sampleHeader; if(!file.ReadStruct(sampleHeader) || !sampleMap[i]) { continue; } ModSample &mptSample = Samples[sampleMap[i]]; sampleHeader.ConvertToMPT(mptSample); fileHeader.instrument.ApplyAutoVibratoToMPT(mptSample); mptSample.Convert(MOD_TYPE_XM, GetType()); if(GetType() != MOD_TYPE_XM && fileHeader.numSamples == 1) { // No need to pan that single sample, thank you... mptSample.uFlags &= ~CHN_PANNING; } mpt::String::Read(mptSample.filename, sampleHeader.name); mpt::String::Read(m_szNames[sampleMap[i]], sampleHeader.name); sampleFlags[i] = sampleHeader.GetSampleFormat(); } // Read sample data for(SAMPLEINDEX i = 0; i < fileHeader.numSamples; i++) { if(sampleMap[i]) { sampleFlags[i].ReadSample(Samples[sampleMap[i]], file); Samples[sampleMap[i]].PrecomputeLoops(*this, false); } } pIns->Convert(MOD_TYPE_XM, GetType()); // Read MPT crap ReadExtendedInstrumentProperties(pIns, file); pIns->Sanitize(GetType()); return true; } #ifndef MODPLUG_NO_FILESAVE bool CSoundFile::SaveXIInstrument(INSTRUMENTINDEX nInstr, const mpt::PathString &filename) const { ModInstrument *pIns = Instruments[nInstr]; if(pIns == nullptr || filename.empty()) { return false; } FILE *f; if((f = mpt_fopen(filename, "wb")) == nullptr) { return false; } // Create file header XIInstrumentHeader header; header.ConvertToXM(*pIns, false); const std::vector samples = header.instrument.GetSampleList(*pIns, false); if(samples.size() > 0 && samples[0] <= GetNumSamples()) { // Copy over auto-vibrato settings of first sample header.instrument.ApplyAutoVibratoToXM(Samples[samples[0]], GetType()); } fwrite(&header, 1, sizeof(XIInstrumentHeader), f); std::vector sampleFlags(samples.size()); // XI Sample Headers for(SAMPLEINDEX i = 0; i < samples.size(); i++) { XMSample xmSample; if(samples[i] <= GetNumSamples()) { xmSample.ConvertToXM(Samples[samples[i]], GetType(), false); } else { MemsetZero(xmSample); } sampleFlags[i] = xmSample.GetSampleFormat(); mpt::String::Write(xmSample.name, m_szNames[samples[i]]); fwrite(&xmSample, 1, sizeof(xmSample), f); } // XI Sample Data for(SAMPLEINDEX i = 0; i < samples.size(); i++) { if(samples[i] <= GetNumSamples()) { sampleFlags[i].WriteSample(f, Samples[samples[i]]); } } // Write 'MPTX' extension tag char code[4]; memcpy(code, "XTPM", 4); fwrite(code, 1, 4, f); WriteInstrumentHeaderStructOrField(pIns, f); // Write full extended header. fclose(f); return true; } #endif // MODPLUG_NO_FILESAVE // Read first sample from XI file into a sample slot bool CSoundFile::ReadXISample(SAMPLEINDEX nSample, FileReader &file) { file.Rewind(); XIInstrumentHeader fileHeader; if(!file.ReadStruct(fileHeader) || !file.CanRead(sizeof(XMSample)) || memcmp(fileHeader.signature, "Extended Instrument: ", 21) || fileHeader.version != XIInstrumentHeader::fileVersion || fileHeader.eof != 0x1A || fileHeader.numSamples == 0) { return false; } if(m_nSamples < nSample) { m_nSamples = nSample; } uint16 numSamples = fileHeader.numSamples; FileReader::off_t samplePos = sizeof(XIInstrumentHeader) + numSamples * sizeof(XMSample); // Preferrably read the middle-C sample auto sample = fileHeader.instrument.sampleMap[48]; if(sample >= fileHeader.numSamples) sample = 0; XMSample sampleHeader; while(sample--) { file.ReadStruct(sampleHeader); samplePos += sampleHeader.length; } file.ReadStruct(sampleHeader); // Gotta skip 'em all! file.Seek(samplePos); DestroySampleThreadsafe(nSample); ModSample &mptSample = Samples[nSample]; sampleHeader.ConvertToMPT(mptSample); if(GetType() != MOD_TYPE_XM) { // No need to pan that single sample, thank you... mptSample.uFlags.reset(CHN_PANNING); } fileHeader.instrument.ApplyAutoVibratoToMPT(mptSample); mptSample.Convert(MOD_TYPE_XM, GetType()); mpt::String::Read(mptSample.filename, sampleHeader.name); mpt::String::Read(m_szNames[nSample], sampleHeader.name); // Read sample data sampleHeader.GetSampleFormat().ReadSample(Samples[nSample], file); Samples[nSample].PrecomputeLoops(*this, false); return true; } ///////////////////////////////////////////////////////////////////////////////////////// // SFZ Instrument #ifdef MPT_EXTERNAL_SAMPLES struct SFZControl { std::string defaultPath; int8 octaveOffset = 0, noteOffset = 0; void Parse(const std::string &key, const std::string &value) { if(key == "default_path") defaultPath = value; else if(key == "octave_offset") octaveOffset = ConvertStrTo(value); else if(key == "note_offset") noteOffset = ConvertStrTo(value); } }; struct SFZEnvelope { float startLevel = 0, delay = 0, attack = 0, hold = 0, decay = 0, sustainLevel = 100, release = 0, depth = 0; void Parse(std::string key, const std::string &value) { key.erase(0, key.find('_') + 1); float v = ConvertStrTo(value); if(key == "depth") Limit(v, -12000.0f, 12000.0f); else if(key == "start" || key == "sustain") Limit(v, -100.0f, 100.0f); else Limit(v, 0.0f, 100.0f); if(key == "start") startLevel = v; else if(key == "delay") delay = v; else if(key == "attack") attack = v; else if(key == "hold") hold = v; else if(key == "decay") decay = v; else if(key == "sustain") sustainLevel = v; else if(key == "release") release = v; else if(key == "depth") depth = v; } static EnvelopeNode::tick_t ToTicks(float duration, float tickDuration) { return std::max(EnvelopeNode::tick_t(1), Util::Round(duration / tickDuration)); } EnvelopeNode::value_t ToValue(float value, EnvelopeType envType) const { value *= (ENVELOPE_MAX / 100.0f); if(envType == ENV_PITCH) { value *= depth / 3200.0f; value += ENVELOPE_MID; } Limit(value, ENVELOPE_MIN, ENVELOPE_MAX); return Util::Round(value); } void ConvertToMPT(ModInstrument *ins, const CSoundFile &sndFile, EnvelopeType envType) const { auto &env = ins->GetEnvelope(envType); float tickDuration = sndFile.m_PlayState.m_nSamplesPerTick / static_cast(sndFile.GetSampleRate()); if(tickDuration <= 0) return; env.clear(); if(envType != ENV_VOLUME && attack == 0 && delay == 0 && hold == 0 && decay == 0 && sustainLevel == 100 && release == 0 && depth == 0) { env.dwFlags.reset(ENV_SUSTAIN | ENV_ENABLED); return; } if(attack > 0 || delay > 0) { env.push_back(0, ToValue(startLevel, envType)); if(delay > 0) env.push_back(ToTicks(delay, tickDuration), env.back().value); env.push_back(env.back().tick + ToTicks(attack, tickDuration), ToValue(100, envType)); } if(hold > 0) { if(env.empty()) env.push_back(0, ToValue(100, envType)); env.push_back(env.back().tick + ToTicks(hold, tickDuration), env.back().value); } if(env.empty()) env.push_back(0, ToValue(100, envType)); auto sustain = ToValue(sustainLevel, envType); if(env.back().value != sustain) env.push_back(env.back().tick + ToTicks(decay, tickDuration), sustain); env.nSustainStart = env.nSustainEnd = static_cast(env.size() - 1); if(sustainLevel != 0) { env.push_back(env.back().tick + ToTicks(release, tickDuration), ToValue(0, envType)); env.dwFlags.set(ENV_SUSTAIN); } env.dwFlags.set(ENV_ENABLED); } }; struct SFZRegion { enum class LoopMode { kUnspecified, kContinuous, kOneShot, kSustain, kNoLoop }; enum class LoopType { kUnspecified, kForward, kBackward, kAlternate, }; std::string filename; SFZEnvelope ampEnv, pitchEnv, filterEnv; SmpLength loopStart = 0, loopEnd = 0; SmpLength end = MAX_SAMPLE_LENGTH, offset = 0; double loopCrossfade = 0.0; LoopMode loopMode = LoopMode::kUnspecified; LoopType loopType = LoopType::kUnspecified; int32 cutoff = 0; // in Hz int32 filterRandom = 0; // 0...9600 cents int16 volume = 0; // -144dB...+6dB int16 pitchBend = 200; // -9600...9600 cents float pitchLfoFade = 0; // 0...100 seconds int16 pitchLfoDepth = 0; // -1200...12000 uint8 pitchLfoFreq = 0; // 0...20 Hz int8 panning = -128; // -100...+100 int8 transpose = 0; int8 finetune = 0; uint8 keyLo = 0, keyHi = 127, keyRoot = 60; uint8 resonance = 0; // 0...40dB uint8 filterType = FLTMODE_UNCHANGED; uint8 polyphony = 255; bool useSampleKeyRoot = false; bool invertPhase = false; template static void Read(const std::string &valueStr, T &value, Tc valueMin = std::numeric_limits::min(), Tc valueMax = std::numeric_limits::max()) { double valueF = ConvertStrTo(valueStr); MPT_CONSTANT_IF(std::numeric_limits::is_integer) { valueF = Util::Round(valueF); } Limit(valueF, static_cast(valueMin), static_cast(valueMax)); value = static_cast(valueF); } static uint8 ReadKey(const std::string &value, const SFZControl &control) { if(value.empty()) return 0; int key = 0; if(value[0] >= '0' && value[0] <= '9') { // MIDI key key = ConvertStrTo(value); } else if(value.length() < 2) { return 0; } else { // Scientific pitch static const int8 keys[] = { 9, 11, 0, 2, 4, 5, 7 }; STATIC_ASSERT(CountOf(keys) == 'g' - 'a' + 1); auto keyC = value[0]; if(keyC >= 'A' && keyC <= 'G') key = keys[keyC - 'A']; if(keyC >= 'a' && keyC <= 'g') key = keys[keyC - 'a']; else return 0; uint8 octaveOffset = 1; if(value[1] == '#') { key++; octaveOffset = 2; } else if(value[1] == 'b' || value[1] == 'B') { key--; octaveOffset = 2; } if(octaveOffset >= value.length()) return 0; int8 octave = ConvertStrTo(value.c_str() + octaveOffset); key += (octave + 1) * 12; } key += control.octaveOffset * 12 + control.noteOffset; return static_cast(Clamp(key, 0, 127)); } void Parse(const std::string &key, const std::string &value, const SFZControl &control) { if(key == "sample") filename = control.defaultPath + value; else if(key == "lokey") keyLo = ReadKey(value, control); else if(key == "hikey") keyHi = ReadKey(value, control); else if(key == "pitch_keycenter") { keyRoot = ReadKey(value, control); useSampleKeyRoot = (value == "sample"); } else if(key == "key") { keyLo = keyHi = keyRoot = ReadKey(value, control); useSampleKeyRoot = false; } else if(key == "bend_up" || key == "bendup") Read(value, pitchBend, -9600, 9600); else if(key == "pitchlfo_fade") Read(value, pitchLfoFade, 0.0f, 100.0f); else if(key == "pitchlfo_depth") Read(value, pitchLfoDepth, -12000, 12000); else if(key == "pitchlfo_freq") Read(value, pitchLfoFreq, 0, 20); else if(key == "volume") Read(value, volume, -144, 6); else if(key == "pan") Read(value, panning, -100, 100); else if(key == "transpose") Read(value, transpose, -127, 127); else if(key == "tune") Read(value, finetune, -100, 100); else if(key == "end") Read(value, end, SmpLength(0), MAX_SAMPLE_LENGTH); else if(key == "offset") Read(value, offset, SmpLength(0), MAX_SAMPLE_LENGTH); else if(key == "loop_start" || key == "loopstart") Read(value, loopStart, SmpLength(0), MAX_SAMPLE_LENGTH); else if(key == "loop_end" || key == "loopend") Read(value, loopEnd, SmpLength(0), MAX_SAMPLE_LENGTH); else if(key == "loop_crossfade") Read(value, loopCrossfade, 0.0, DBL_MAX); else if(key == "loop_mode" || key == "loopmode") { if(value == "loop_continuous") loopMode = LoopMode::kContinuous; else if(value == "one_shot") loopMode = LoopMode::kOneShot; else if(value == "loop_sustain") loopMode = LoopMode::kSustain; else if(value == "no_loop") loopMode = LoopMode::kNoLoop; } else if(key == "loop_type" || key == "looptype") { if(value == "forward") loopType = LoopType::kForward; else if(value == "backward") loopType = LoopType::kBackward; else if(value == "alternate") loopType = LoopType::kAlternate; } else if(key == "cutoff") Read(value, cutoff, 0, 96000); else if(key == "fil_random") Read(value, filterRandom, 0, 9600); else if(key == "resonance") Read(value, resonance, 0u, 40u); else if(key == "polyphony") Read(value, polyphony, 0u, 255u); else if(key == "phase") invertPhase = (value == "invert"); else if(key == "fil_type" || key == "filtype") { if(value == "lpf_1p" || value == "lpf_2p" || value == "lpf_4p" || value == "lpf_6p") filterType = FLTMODE_LOWPASS; else if(value == "hpf_1p" || value == "hpf_2p" || value == "hpf_4p" || value == "hpf_6p") filterType = FLTMODE_HIGHPASS; // Alternatives: bpf_2p, brf_2p } else if(key.substr(0, 6) == "ampeg_") ampEnv.Parse(key, value); else if(key.substr(0, 6) == "fileg_") filterEnv.Parse(key, value); else if(key.substr(0, 8) == "pitcheg_") pitchEnv.Parse(key, value); } }; bool CSoundFile::ReadSFZInstrument(INSTRUMENTINDEX nInstr, FileReader &file) { file.Rewind(); enum { kNone, kGlobal, kMaster, kGroup, kRegion, kControl, kUnknown } section = kNone; SFZControl control; SFZRegion group, master, globals; std::vector regions; std::map macros; std::string s; while(file.ReadLine(s, 1024)) { // First, terminate line at the start of a comment block auto commentPos = s.find("//"); if(commentPos != std::string::npos) { s.resize(commentPos); } // Now, read the tokens. // This format is so funky that no general tokenizer approach seems to work here... // Consider this jolly good example found at https://stackoverflow.com/questions/5923895/tokenizing-a-custom-text-file-format-file-using-c-sharp // sample=piano C3.wav key=48 ampeg_release=0.7 // a comment here // key = 49 sample = piano Db3.wav // // group=1 // key = 48 // sample = piano D3.ogg // The original sfz specification claims that spaces around = are not allowed, but a quick look into the real world tells us otherwise. while(!s.empty()) { s.erase(0, s.find_first_not_of(" \t")); // Replace macros for(const auto &m : macros) { auto &oldStr = m.first; auto &newStr = m.second; std::string::size_type pos = 0; while((pos = s.find(oldStr, pos)) != std::string::npos) { s.replace(pos, oldStr.length(), newStr); pos += newStr.length(); } } if(s.empty()) { break; } std::string::size_type charsRead = 0; if(s[0] == '<' && (charsRead = s.find('>')) != std::string::npos) { // Section header std::string sec = s.substr(1, charsRead - 1); section = kUnknown; if(sec == "global") { section = kGlobal; // Reset global parameters globals = SFZRegion(); } else if(sec == "master") { section = kMaster; // Reset master parameters master = globals; } else if(sec == "group") { section = kGroup; // Reset group parameters group = master; } else if(sec == "region") { section = kRegion; regions.push_back(group); } else if(sec == "control") { section = kControl; } charsRead++; } else if(s.substr(0, 8) == "#define " || s.substr(0, 8) == "#define\t") { // Macro definition auto keyStart = s.find_first_not_of(" \t", 8); auto keyEnd = s.find_first_of(" \t", keyStart); auto valueStart = s.find_first_not_of(" \t", keyEnd); std::string key = s.substr(keyStart, keyEnd - keyStart); if(valueStart != std::string::npos && key.length() > 1 && key[0] == '$') { charsRead = s.find_first_of(" \t", valueStart); macros[key] = s.substr(valueStart, charsRead - valueStart); } } else if(s.substr(0, 9) == "#include " || s.substr(0, 9) == "#include\t") { AddToLog(LogWarning, MPT_USTRING("#include directive is not supported.")); auto fileStart = s.find("\"", 9); // Yes, there can be arbitrary characters before the opening quote, at least that's how sforzando does it. auto fileEnd = s.find("\"", fileStart + 1); if(fileStart != std::string::npos && fileEnd != std::string::npos) { charsRead = fileEnd + 1; } else { return false; } } else if(section == kNone) { // Garbage before any section, probably not an sfz file return false; } else if(s.find('=') != std::string::npos) { // Read key=value pair auto keyEnd = s.find_first_of(" \t="); auto valueStart = s.find_first_not_of(" \t=", keyEnd); std::string key = mpt::ToLowerCaseAscii(s.substr(0, keyEnd)); if(key == "sample" || key == "default_path" || key.substr(0, 8) == "label_cc") { // Sample / CC name may contain spaces... charsRead = s.find_first_of("=\t<", valueStart); if(charsRead != std::string::npos && s[charsRead] == '=') { // Backtrack to end of key while(charsRead > valueStart && s[charsRead] == ' ') charsRead--; // Backtrack to start of key while(charsRead > valueStart && s[charsRead] != ' ') charsRead--; } } else { charsRead = s.find_first_of(" \t<", valueStart); } std::string value = s.substr(valueStart, charsRead - valueStart); switch(section) { case kGlobal: globals.Parse(key, value, control); MPT_FALLTHROUGH; case kMaster: master.Parse(key, value, control); MPT_FALLTHROUGH; case kGroup: group.Parse(key, value, control); break; case kRegion: regions.back().Parse(key, value, control); break; case kControl: control.Parse(key, value); break; } } else { // Garbage, probably not an sfz file MPT_ASSERT(false); return false; } // Remove the token(s) we just read s.erase(0, charsRead); } } if(regions.empty()) { return false; } ModInstrument *pIns = new (std::nothrow) ModInstrument(); if(pIns == nullptr) { return false; } RecalculateSamplesPerTick(); DestroyInstrument(nInstr, deleteAssociatedSamples); if(nInstr > m_nInstruments) m_nInstruments = nInstr; Instruments[nInstr] = pIns; SAMPLEINDEX prevSmp = 0; for(auto ®ion : regions) { uint8 keyLo = region.keyLo, keyHi = region.keyHi; if(keyLo > keyHi) continue; Clamp(keyLo, 0, NOTE_MAX - NOTE_MIN); Clamp(keyHi, 0, NOTE_MAX - NOTE_MIN); SAMPLEINDEX smp = GetNextFreeSample(nInstr, prevSmp + 1); if(smp == SAMPLEINDEX_INVALID) break; prevSmp = smp; ModSample &sample = Samples[smp]; mpt::PathString filename = mpt::PathString::FromUTF8(region.filename); if(!filename.empty()) { if(region.filename.find(':') == std::string::npos) { filename = file.GetFileName().GetPath() + filename; } SetSamplePath(smp, filename); InputFile f(filename); FileReader smpFile = GetFileReader(f); if(!ReadSampleFromFile(smp, smpFile, false)) { AddToLog(LogWarning, MPT_USTRING("Unable to load sample: ") + filename.ToUnicode()); prevSmp--; continue; } if(!m_szNames[smp][0]) { mpt::String::Copy(m_szNames[smp], filename.GetFileName().ToLocale()); } } sample.uFlags.set(SMP_KEEPONDISK, sample.pSample != nullptr); if(region.useSampleKeyRoot) { if(sample.rootNote != NOTE_NONE) region.keyRoot = sample.rootNote - NOTE_MIN; else region.keyRoot = 60; } const auto origSampleRate = sample.GetSampleRate(GetType()); int8 transp = region.transpose + (60 - region.keyRoot); for(uint8 i = keyLo; i <= keyHi; i++) { pIns->Keyboard[i] = smp; if(GetType() != MOD_TYPE_XM) pIns->NoteMap[i] = NOTE_MIN + i + transp; } if(GetType() == MOD_TYPE_XM) sample.Transpose(transp / 12.0); pIns->nFilterMode = region.filterType; if(region.cutoff != 0) pIns->SetCutoff(FrequencyToCutOff(region.cutoff), true); if(region.resonance != 0) pIns->SetResonance(mpt::saturate_cast(Util::muldivr(region.resonance, 128, 24)), true); pIns->nCutSwing = mpt::saturate_cast(Util::muldivr(region.filterRandom, m_SongFlags[SONG_EXFILTERRANGE] ? 20 : 24, 1200)); pIns->midiPWD = static_cast(region.pitchBend / 100); pIns->nNNA = NNA_NOTEOFF; if(region.polyphony == 1) { pIns->nDNA = NNA_NOTECUT; pIns->nDCT = DCT_SAMPLE; } region.ampEnv.ConvertToMPT(pIns, *this, ENV_VOLUME); region.pitchEnv.ConvertToMPT(pIns, *this, ENV_PITCH); //region.filterEnv.ConvertToMPT(pIns, *this, ENV_PITCH); sample.rootNote = region.keyRoot + NOTE_MIN; sample.nGlobalVol = Util::Round(64 * std::pow(10.0, region.volume / 20.0)); if(region.panning != -128) { sample.nPan = static_cast(Util::muldivr_unsigned(region.panning + 100, 256, 200)); sample.uFlags.set(CHN_PANNING); } sample.Transpose(region.finetune / 1200.0); if(region.pitchLfoDepth && region.pitchLfoFreq) { sample.nVibSweep = 255; if(region.pitchLfoFade > 0) sample.nVibSweep = Util::Round(255 / region.pitchLfoFade); sample.nVibDepth = static_cast(Util::muldivr(region.pitchLfoDepth, 32, 100)); sample.nVibRate = region.pitchLfoFreq * 4; } if(region.loopMode != SFZRegion::LoopMode::kUnspecified) { switch(region.loopMode) { case SFZRegion::LoopMode::kContinuous: case SFZRegion::LoopMode::kOneShot: sample.uFlags.set(CHN_LOOP); break; case SFZRegion::LoopMode::kSustain: sample.uFlags.set(CHN_SUSTAINLOOP); break; case SFZRegion::LoopMode::kNoLoop: sample.uFlags.reset(CHN_LOOP | CHN_SUSTAINLOOP); } } if(region.loopEnd > region.loopStart) { // Loop may also be defined in file, in which case loopStart and loopEnd are unset. if(region.loopMode == SFZRegion::LoopMode::kSustain) { sample.nSustainStart = region.loopStart; sample.nSustainEnd = region.loopEnd + 1; } else if(region.loopMode == SFZRegion::LoopMode::kContinuous || region.loopMode == SFZRegion::LoopMode::kOneShot) { sample.nLoopStart = region.loopStart; sample.nLoopEnd = region.loopEnd + 1; } } else if(sample.nLoopEnd <= sample.nLoopStart && region.loopMode != SFZRegion::LoopMode::kUnspecified && region.loopMode != SFZRegion::LoopMode::kNoLoop) { sample.nLoopEnd = sample.nLength; } switch(region.loopType) { case SFZRegion::LoopType::kUnspecified: break; case SFZRegion::LoopType::kForward: sample.uFlags.reset(CHN_PINGPONGLOOP | CHN_PINGPONGSUSTAIN | CHN_REVERSE); break; case SFZRegion::LoopType::kBackward: sample.uFlags.set(CHN_REVERSE); break; case SFZRegion::LoopType::kAlternate: sample.uFlags.set(CHN_PINGPONGLOOP | CHN_PINGPONGSUSTAIN); break; default: break; } if(sample.nSustainEnd <= sample.nSustainStart && sample.nLoopEnd > sample.nLoopStart && region.loopMode == SFZRegion::LoopMode::kSustain) { // Turn normal loop (imported from sample) into sustain loop std::swap(sample.nSustainStart, sample.nLoopStart); std::swap(sample.nSustainEnd, sample.nLoopEnd); sample.uFlags.set(CHN_SUSTAINLOOP); sample.uFlags.set(CHN_PINGPONGSUSTAIN, sample.uFlags[CHN_PINGPONGLOOP]); sample.uFlags.reset(CHN_LOOP | CHN_PINGPONGLOOP); } // Loop cross-fade SmpLength fadeSamples = Util::Round(region.loopCrossfade * origSampleRate); LimitMax(fadeSamples, sample.uFlags[CHN_SUSTAINLOOP] ? sample.nSustainStart : sample.nLoopStart); if(fadeSamples > 0) { ctrlSmp::XFadeSample(sample, fadeSamples, 50000, true, sample.uFlags[CHN_SUSTAINLOOP], *this); sample.uFlags.set(SMP_MODIFIED); } // Sample offset if(region.offset && region.offset < sample.nLength) { auto offset = region.offset * sample.GetBytesPerSample(); memmove(sample.pSample8, sample.pSample8 + offset, sample.nLength * sample.GetBytesPerSample() - offset); if(region.end > region.offset) region.end -= region.offset; sample.nLength -= region.offset; sample.nLoopStart -= region.offset; sample.nLoopEnd -= region.offset; sample.uFlags.set(SMP_MODIFIED); } LimitMax(sample.nLength, region.end); if(region.invertPhase) { ctrlSmp::InvertSample(sample, 0, sample.nLength, *this); sample.uFlags.set(SMP_MODIFIED); } sample.PrecomputeLoops(*this, false); sample.Convert(MOD_TYPE_MPT, GetType()); } pIns->Sanitize(MOD_TYPE_MPT); pIns->Convert(MOD_TYPE_MPT, GetType()); return true; } #else bool CSoundFile::ReadSFZInstrument(INSTRUMENTINDEX, FileReader &) { return false; } #endif // MPT_EXTERNAL_SAMPLES ///////////////////////////////////////////////////////////////////////////////////////// // AIFF File I/O // AIFF header struct AIFFHeader { char magic[4]; // FORM uint32be length; // Size of the file, not including magic and length char type[4]; // AIFF or AIFC }; MPT_BINARY_STRUCT(AIFFHeader, 12) // General IFF Chunk header struct AIFFChunk { // 32-Bit chunk identifiers enum ChunkIdentifiers { idCOMM = MAGIC4BE('C','O','M','M'), idSSND = MAGIC4BE('S','S','N','D'), idINST = MAGIC4BE('I','N','S','T'), idMARK = MAGIC4BE('M','A','R','K'), idNAME = MAGIC4BE('N','A','M','E'), }; uint32be id; // See ChunkIdentifiers uint32be length; // Chunk size without header size_t GetLength() const { return length; } ChunkIdentifiers GetID() const { return static_cast(id.get()); } }; MPT_BINARY_STRUCT(AIFFChunk, 8) // "Common" chunk (in AIFC, a compression ID and compression name follows this header, but apart from that it's identical) struct AIFFCommonChunk { uint16be numChannels; uint32be numSampleFrames; uint16be sampleSize; uint8be sampleRate[10]; // Sample rate in 80-Bit floating point // Convert sample rate to integer uint32 GetSampleRate() const { uint32 mantissa = (sampleRate[2] << 24) | (sampleRate[3] << 16) | (sampleRate[4] << 8) | (sampleRate[5] << 0); uint32 last = 0; uint8 exp = 30 - sampleRate[1]; while(exp--) { last = mantissa; mantissa >>= 1; } if(last & 1) mantissa++; return mantissa; } }; MPT_BINARY_STRUCT(AIFFCommonChunk, 18) // Sound chunk struct AIFFSoundChunk { uint32be offset; uint32be blockSize; }; MPT_BINARY_STRUCT(AIFFSoundChunk, 8) // Marker struct AIFFMarker { uint16be id; uint32be position; // Position in sample uint8be nameLength; // Not counting eventually existing padding byte in name string }; MPT_BINARY_STRUCT(AIFFMarker, 7) // Instrument loop struct AIFFInstrumentLoop { enum PlayModes { noLoop = 0, loopNormal = 1, loopBidi = 2, }; uint16be playMode; uint16be beginLoop; // Marker index uint16be endLoop; // Marker index }; MPT_BINARY_STRUCT(AIFFInstrumentLoop, 6) struct AIFFInstrumentChunk { uint8be baseNote; uint8be detune; uint8be lowNote; uint8be highNote; uint8be lowVelocity; uint8be highVelocity; uint16be gain; AIFFInstrumentLoop sustainLoop; AIFFInstrumentLoop releaseLoop; }; MPT_BINARY_STRUCT(AIFFInstrumentChunk, 20) bool CSoundFile::ReadAIFFSample(SAMPLEINDEX nSample, FileReader &file, bool mayNormalize) { file.Rewind(); ChunkReader chunkFile(file); // Verify header AIFFHeader fileHeader; if(!chunkFile.ReadStruct(fileHeader) || memcmp(fileHeader.magic, "FORM", 4) || (memcmp(fileHeader.type, "AIFF", 4) && memcmp(fileHeader.type, "AIFC", 4))) { return false; } auto chunks = chunkFile.ReadChunks(2); // Read COMM chunk FileReader commChunk(chunks.GetChunk(AIFFChunk::idCOMM)); AIFFCommonChunk sampleInfo; if(!commChunk.ReadStruct(sampleInfo)) { return false; } // Is this a proper sample? if(sampleInfo.numSampleFrames == 0 || sampleInfo.numChannels < 1 || sampleInfo.numChannels > 2 || sampleInfo.sampleSize < 1 || sampleInfo.sampleSize > 64) { return false; } // Read compression type in AIFF-C files. uint8 compression[4] = { 'N', 'O', 'N', 'E' }; SampleIO::Endianness endian = SampleIO::bigEndian; if(!memcmp(fileHeader.type, "AIFC", 4)) { if(!commChunk.ReadArray(compression)) { return false; } if(!memcmp(compression, "twos", 4)) { endian = SampleIO::littleEndian; } } // Read SSND chunk FileReader soundChunk(chunks.GetChunk(AIFFChunk::idSSND)); AIFFSoundChunk sampleHeader; if(!soundChunk.ReadStruct(sampleHeader) || !soundChunk.CanRead(sampleHeader.offset)) { return false; } SampleIO::Bitdepth bitDepth; switch((sampleInfo.sampleSize - 1) / 8) { default: case 0: bitDepth = SampleIO::_8bit; break; case 1: bitDepth = SampleIO::_16bit; break; case 2: bitDepth = SampleIO::_24bit; break; case 3: bitDepth = SampleIO::_32bit; break; case 7: bitDepth = SampleIO::_64bit; break; } SampleIO sampleIO(bitDepth, (sampleInfo.numChannels == 2) ? SampleIO::stereoInterleaved : SampleIO::mono, endian, SampleIO::signedPCM); if(!memcmp(compression, "fl32", 4) || !memcmp(compression, "FL32", 4) || !memcmp(compression, "fl64", 4)) { sampleIO |= SampleIO::floatPCM; } else if(!memcmp(compression, "alaw", 4) || !memcmp(compression, "ALAW", 4)) { sampleIO |= SampleIO::aLaw; sampleIO |= SampleIO::_16bit; } else if(!memcmp(compression, "ulaw", 4) || !memcmp(compression, "ULAW", 4)) { sampleIO |= SampleIO::uLaw; sampleIO |= SampleIO::_16bit; } if(mayNormalize) { sampleIO.MayNormalize(); } soundChunk.Skip(sampleHeader.offset); ModSample &mptSample = Samples[nSample]; DestroySampleThreadsafe(nSample); mptSample.Initialize(); mptSample.nLength = sampleInfo.numSampleFrames; mptSample.nC5Speed = sampleInfo.GetSampleRate(); sampleIO.ReadSample(mptSample, soundChunk); // Read MARK and INST chunk to extract sample loops FileReader markerChunk(chunks.GetChunk(AIFFChunk::idMARK)); AIFFInstrumentChunk instrHeader; if(markerChunk.IsValid() && chunks.GetChunk(AIFFChunk::idINST).ReadStruct(instrHeader)) { uint16 numMarkers = markerChunk.ReadUint16BE(); std::vector markers; markers.reserve(numMarkers); for(size_t i = 0; i < numMarkers; i++) { AIFFMarker marker; if(!markerChunk.ReadStruct(marker)) { break; } markers.push_back(marker); markerChunk.Skip(marker.nameLength + ((marker.nameLength % 2u) == 0 ? 1 : 0)); } if(instrHeader.sustainLoop.playMode != AIFFInstrumentLoop::noLoop) { mptSample.uFlags.set(CHN_SUSTAINLOOP); mptSample.uFlags.set(CHN_PINGPONGSUSTAIN, instrHeader.sustainLoop.playMode == AIFFInstrumentLoop::loopBidi); } if(instrHeader.releaseLoop.playMode != AIFFInstrumentLoop::noLoop) { mptSample.uFlags.set(CHN_LOOP); mptSample.uFlags.set(CHN_PINGPONGLOOP, instrHeader.releaseLoop.playMode == AIFFInstrumentLoop::loopBidi); } // Read markers for(const auto &m : markers) { if(m.id == instrHeader.sustainLoop.beginLoop) mptSample.nSustainStart = m.position; if(m.id == instrHeader.sustainLoop.endLoop) mptSample.nSustainEnd = m.position; if(m.id == instrHeader.releaseLoop.beginLoop) mptSample.nLoopStart = m.position; if(m.id == instrHeader.releaseLoop.endLoop) mptSample.nLoopEnd = m.position; } mptSample.SanitizeLoops(); } // Extract sample name FileReader nameChunk(chunks.GetChunk(AIFFChunk::idNAME)); if(nameChunk.IsValid()) { nameChunk.ReadString(m_szNames[nSample], nameChunk.GetLength()); } else { strcpy(m_szNames[nSample], ""); } mptSample.Convert(MOD_TYPE_IT, GetType()); mptSample.PrecomputeLoops(*this, false); return true; } bool CSoundFile::ReadAUSample(SAMPLEINDEX nSample, FileReader &file, bool mayNormalize) { file.Rewind(); // Verify header if(!file.ReadMagic(".snd")) return false; uint32 dataOffset = file.ReadUint32BE(); uint32 dataSize = file.ReadUint32BE(); uint32 encoding = file.ReadUint32BE(); uint32 sampleRate = file.ReadUint32BE(); uint32 channels = file.ReadUint32BE(); if(channels < 1 || channels > 2) return false; SampleIO sampleIO(SampleIO::_8bit, channels == 1 ? SampleIO::mono : SampleIO::stereoInterleaved, SampleIO::bigEndian, SampleIO::signedPCM); switch(encoding) { case 1: sampleIO |= SampleIO::_16bit; // u-law sampleIO |= SampleIO::uLaw; break; case 2: break; // 8-bit linear PCM case 3: sampleIO |= SampleIO::_16bit; break; // 16-bit linear PCM case 4: sampleIO |= SampleIO::_24bit; break; // 24-bit linear PCM case 5: sampleIO |= SampleIO::_32bit; break; // 32-bit linear PCM case 6: sampleIO |= SampleIO::_32bit; // 32-bit IEEE floating point sampleIO |= SampleIO::floatPCM; break; case 7: sampleIO |= SampleIO::_64bit; // 64-bit IEEE floating point sampleIO |= SampleIO::floatPCM; break; case 27: sampleIO |= SampleIO::_16bit; // a-law sampleIO |= SampleIO::aLaw; break; default: return false; } if(!file.Seek(dataOffset)) return false; ModSample &mptSample = Samples[nSample]; DestroySampleThreadsafe(nSample); mptSample.Initialize(); SmpLength length = mpt::saturate_cast(file.BytesLeft()); if(dataSize != 0xFFFFFFFF) LimitMax(length, dataSize); mptSample.nLength = (length * 8u) / (sampleIO.GetEncodedBitsPerSample() * channels); mptSample.nC5Speed = sampleRate; strcpy(m_szNames[nSample], ""); if(mayNormalize) { sampleIO.MayNormalize(); } sampleIO.ReadSample(mptSample, file); mptSample.Convert(MOD_TYPE_IT, GetType()); mptSample.PrecomputeLoops(*this, false); return true; } ///////////////////////////////////////////////////////////////////////////////////////// // ITS Samples bool CSoundFile::ReadITSSample(SAMPLEINDEX nSample, FileReader &file, bool rewind) { if(rewind) { file.Rewind(); } ITSample sampleHeader; if(!file.ReadStruct(sampleHeader) || memcmp(sampleHeader.id, "IMPS", 4)) { return false; } DestroySampleThreadsafe(nSample); ModSample &sample = Samples[nSample]; file.Seek(sampleHeader.ConvertToMPT(sample)); mpt::String::Read(m_szNames[nSample], sampleHeader.name); if(!sample.uFlags[SMP_KEEPONDISK]) { sampleHeader.GetSampleFormat().ReadSample(Samples[nSample], file); } else { // External sample size_t strLen; file.ReadVarInt(strLen); #ifdef MPT_EXTERNAL_SAMPLES std::string filenameU8; file.ReadString(filenameU8, strLen); mpt::PathString filename = mpt::PathString::FromUTF8(filenameU8); if(!filename.empty()) { if(!file.GetFileName().empty()) { filename = filename.RelativePathToAbsolute(file.GetFileName().GetPath()); } if(!LoadExternalSample(nSample, filename)) { AddToLog(LogWarning, MPT_USTRING("Unable to load sample: ") + filename.ToUnicode()); } } else { sample.uFlags.reset(SMP_KEEPONDISK); } #else file.Skip(strLen); #endif // MPT_EXTERNAL_SAMPLES } sample.Convert(MOD_TYPE_IT, GetType()); sample.PrecomputeLoops(*this, false); return true; } bool CSoundFile::ReadITISample(SAMPLEINDEX nSample, FileReader &file) { ITInstrument instrumentHeader; file.Rewind(); if(!file.ReadStruct(instrumentHeader) || memcmp(instrumentHeader.id, "IMPI", 4)) { return false; } file.Rewind(); ModInstrument dummy; ITInstrToMPT(file, dummy, instrumentHeader.trkvers); // Old SchismTracker versions set nos=0 const SAMPLEINDEX nsamples = std::max(static_cast(instrumentHeader.nos), *std::max_element(std::begin(dummy.Keyboard), std::end(dummy.Keyboard))); if(!nsamples) return false; // Preferrably read the middle-C sample auto sample = dummy.Keyboard[NOTE_MIDDLEC - NOTE_MIN]; if(sample > 0) sample--; else sample = 0; file.Seek(file.GetPosition() + sample * sizeof(ITSample)); return ReadITSSample(nSample, file, false); } bool CSoundFile::ReadITIInstrument(INSTRUMENTINDEX nInstr, FileReader &file) { ITInstrument instrumentHeader; SAMPLEINDEX smp = 0; file.Rewind(); if(!file.ReadStruct(instrumentHeader) || memcmp(instrumentHeader.id, "IMPI", 4)) { return false; } if(nInstr > GetNumInstruments()) m_nInstruments = nInstr; ModInstrument *pIns = new (std::nothrow) ModInstrument(); if(pIns == nullptr) { return false; } DestroyInstrument(nInstr, deleteAssociatedSamples); Instruments[nInstr] = pIns; file.Rewind(); ITInstrToMPT(file, *pIns, instrumentHeader.trkvers); // Old SchismTracker versions set nos=0 const SAMPLEINDEX nsamples = std::max(static_cast(instrumentHeader.nos), *std::max_element(std::begin(pIns->Keyboard), std::end(pIns->Keyboard))); // In order to properly compute the position, in file, of eventual extended settings // such as "attack" we need to keep the "real" size of the last sample as those extra // setting will follow this sample in the file FileReader::off_t extraOffset = file.GetPosition(); // Reading Samples std::vector samplemap(nsamples, 0); for(SAMPLEINDEX i = 0; i < nsamples; i++) { smp = GetNextFreeSample(nInstr, smp + 1); if(smp == SAMPLEINDEX_INVALID) break; samplemap[i] = smp; const FileReader::off_t offset = file.GetPosition(); if(!ReadITSSample(smp, file, false)) smp--; extraOffset = std::max(extraOffset, file.GetPosition()); file.Seek(offset + sizeof(ITSample)); } if(GetNumSamples() < smp) m_nSamples = smp; // Adjust sample assignment for(auto &sample : pIns->Keyboard) { if(sample > 0 && sample <= nsamples) { sample = samplemap[sample - 1]; } } pIns->Convert(MOD_TYPE_IT, GetType()); if(file.Seek(extraOffset)) { // Read MPT crap ReadExtendedInstrumentProperties(pIns, file); } pIns->Sanitize(GetType()); return true; } #ifndef MODPLUG_NO_FILESAVE bool CSoundFile::SaveITIInstrument(INSTRUMENTINDEX nInstr, const mpt::PathString &filename, bool compress, bool allowExternal) const { ITInstrument iti; ModInstrument *pIns = Instruments[nInstr]; FILE *f; if((!pIns) || filename.empty()) return false; if((f = mpt_fopen(filename, "wb")) == nullptr) return false; auto instSize = iti.ConvertToIT(*pIns, false, *this); // Create sample assignment table std::vector smptable; std::vector smpmap(GetNumSamples(), 0); for(size_t i = 0; i < NOTE_MAX; i++) { const SAMPLEINDEX smp = pIns->Keyboard[i]; if(smp && smp <= GetNumSamples()) { if(!smpmap[smp - 1]) { // We haven't considered this sample yet. smptable.push_back(smp); smpmap[smp - 1] = static_cast(smptable.size()); } iti.keyboard[i * 2 + 1] = smpmap[smp - 1]; } else { iti.keyboard[i * 2 + 1] = 0; } } iti.nos = static_cast(smptable.size()); smpmap.clear(); uint32 filePos = instSize; mpt::IO::WritePartial(f, iti, instSize); filePos += mpt::saturate_cast(smptable.size() * sizeof(ITSample)); // Writing sample headers + data std::vector sampleFlags; for(auto smp : smptable) { ITSample itss; itss.ConvertToIT(Samples[smp], GetType(), compress, compress, allowExternal); const bool isExternal = itss.cvt == ITSample::cvtExternalSample; mpt::String::Write(itss.name, m_szNames[smp]); itss.samplepointer = filePos; mpt::IO::Write(f, itss); // Write sample auto curPos = mpt::IO::TellWrite(f); mpt::IO::SeekAbsolute(f, filePos); if(!isExternal) { filePos += mpt::saturate_cast(itss.GetSampleFormat(0x0214).WriteSample(f, Samples[smp])); } else { #ifdef MPT_EXTERNAL_SAMPLES const std::string filenameU8 = GetSamplePath(smp).AbsolutePathToRelative(filename.GetPath()).ToUTF8(); const size_t strSize = mpt::saturate_cast(filenameU8.size()); size_t intBytes = 0; if(mpt::IO::WriteVarInt(f, strSize, &intBytes)) { filePos += intBytes + strSize; mpt::IO::WriteRaw(f, filenameU8.data(), strSize); } #endif // MPT_EXTERNAL_SAMPLES } mpt::IO::SeekAbsolute(f, curPos); } mpt::IO::SeekEnd(f); // Write 'MPTX' extension tag mpt::IO::WriteRaw(f, "XTPM", 4); WriteInstrumentHeaderStructOrField(pIns, f); // Write full extended header. fclose(f); return true; } #endif // MODPLUG_NO_FILESAVE /////////////////////////////////////////////////////////////////////////////////////////////////// // 8SVX / 16SVX Samples // IFF File Header struct IFFHeader { char form[4]; // "FORM" uint32be size; char magic[4]; // "8SVX" or "16SV" }; MPT_BINARY_STRUCT(IFFHeader, 12) // General IFF Chunk header struct IFFChunk { // 32-Bit chunk identifiers enum ChunkIdentifiers { idVHDR = MAGIC4BE('V','H','D','R'), idBODY = MAGIC4BE('B','O','D','Y'), idNAME = MAGIC4BE('N','A','M','E'), }; uint32be id; // See ChunkIdentifiers uint32be length; // Chunk size without header size_t GetLength() const { if(length == 0) // Broken files return std::numeric_limits::max(); return length; } ChunkIdentifiers GetID() const { return static_cast(id.get()); } }; MPT_BINARY_STRUCT(IFFChunk, 8) struct IFFSampleHeader { uint32be oneShotHiSamples; // Samples in the high octave 1-shot part uint32be repeatHiSamples; // Samples in the high octave repeat part uint32be samplesPerHiCycle; // Samples/cycle in high octave, else 0 uint16be samplesPerSec; // Data sampling rate uint8be octave; // Octaves of waveforms uint8be compression; // Data compression technique used uint32be volume; }; MPT_BINARY_STRUCT(IFFSampleHeader, 20) bool CSoundFile::ReadIFFSample(SAMPLEINDEX nSample, FileReader &file) { file.Rewind(); IFFHeader fileHeader; if(!file.ReadStruct(fileHeader) || memcmp(fileHeader.form, "FORM", 4 ) || (memcmp(fileHeader.magic, "8SVX", 4) && memcmp(fileHeader.magic, "16SV", 4))) { return false; } ChunkReader chunkFile(file); ChunkReader::ChunkList chunks = chunkFile.ReadChunks(2); FileReader vhdrChunk = chunks.GetChunk(IFFChunk::idVHDR); FileReader bodyChunk = chunks.GetChunk(IFFChunk::idBODY); IFFSampleHeader sampleHeader; if(!bodyChunk.IsValid() || !vhdrChunk.IsValid() || !vhdrChunk.ReadStruct(sampleHeader)) { return false; } DestroySampleThreadsafe(nSample); // Default values const uint8 bytesPerSample = memcmp(fileHeader.magic, "8SVX", 4) ? 2 : 1; ModSample &sample = Samples[nSample]; sample.Initialize(); sample.nLoopStart = sampleHeader.oneShotHiSamples / bytesPerSample; sample.nLoopEnd = sample.nLoopStart + sampleHeader.repeatHiSamples / bytesPerSample; sample.nC5Speed = sampleHeader.samplesPerSec; sample.nVolume = static_cast(sampleHeader.volume >> 8); if(!sample.nVolume || sample.nVolume > 256) sample.nVolume = 256; if(!sample.nC5Speed) sample.nC5Speed = 22050; sample.Convert(MOD_TYPE_IT, GetType()); FileReader nameChunk = chunks.GetChunk(IFFChunk::idNAME); if(nameChunk.IsValid()) { nameChunk.ReadString(m_szNames[nSample], nameChunk.GetLength()); } else { strcpy(m_szNames[nSample], ""); } sample.nLength = mpt::saturate_cast(bodyChunk.GetLength() / bytesPerSample); if((sample.nLoopStart + 4 < sample.nLoopEnd) && (sample.nLoopEnd <= sample.nLength)) sample.uFlags.set(CHN_LOOP); // While this is an Amiga format, the 16SV version appears to be only used on PC, and only with little-endian sample data. SampleIO( (bytesPerSample == 2) ? SampleIO::_16bit : SampleIO::_8bit, SampleIO::mono, SampleIO::littleEndian, SampleIO::signedPCM) .ReadSample(sample, bodyChunk); sample.PrecomputeLoops(*this, false); return true; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/MixFuncTable.cpp0000644000372100037210000000571613161656666021153 00000000000000/* * MixFuncTable.cpp * ---------------- * Purpose: Table containing all mixer functions. * Notes : The Visual Studio project settings for this file have been adjusted * to force function inlining, so that the mixer has a somewhat acceptable * performance in debug mode. If you need to debug anything here, be sure * to disable those optimizations if needed. * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Mixer.h" #include "Snd_defs.h" #include "ModChannel.h" #include "MixFuncTable.h" #ifdef MPT_INTMIXER #include "IntMixer.h" #else #include "FloatMixer.h" #endif // MPT_INTMIXER OPENMPT_NAMESPACE_BEGIN namespace MixFuncTable { #ifdef MPT_INTMIXER typedef Int8MToIntS I8M; typedef Int16MToIntS I16M; typedef Int8SToIntS I8S; typedef Int16SToIntS I16S; #else typedef Int8MToFloatS I8M; typedef Int16MToFloatS I16M; typedef Int8SToFloatS I8S; typedef Int16SToFloatS I16S; #endif // MPT_INTMIXER // Build mix function table for given resampling, filter and ramping settings: One function each for 8-Bit / 16-Bit Mono / Stereo #define BuildMixFuncTableRamp(resampling, filter, ramp) \ SampleLoop, filter, MixMono ## ramp >, \ SampleLoop, filter, MixMono ## ramp >, \ SampleLoop, filter, MixStereo ## ramp >, \ SampleLoop, filter, MixStereo ## ramp > // Build mix function table for given resampling, filter settings: With and without ramping #define BuildMixFuncTableFilter(resampling, filter) \ BuildMixFuncTableRamp(resampling, filter, NoRamp), \ BuildMixFuncTableRamp(resampling, filter, Ramp) // Build mix function table for given resampling settings: With and without filter #define BuildMixFuncTable(resampling) \ BuildMixFuncTableFilter(resampling, NoFilter), \ BuildMixFuncTableFilter(resampling, ResonantFilter) const MixFuncInterface Functions[6 * 16] = { BuildMixFuncTable(NoInterpolation), // No SRC BuildMixFuncTable(LinearInterpolation), // Linear SRC BuildMixFuncTable(FastSincInterpolation), // Fast Sinc (Cubic Spline) SRC BuildMixFuncTable(PolyphaseInterpolation), // Kaiser SRC BuildMixFuncTable(FIRFilterInterpolation), // FIR SRC BuildMixFuncTable(AmigaBlepInterpolation), // Amiga emulation }; #undef BuildMixFuncTableRamp #undef BuildMixFuncTableFilter #undef BuildMixFuncTable ResamplingIndex ResamplingModeToMixFlags(ResamplingMode resamplingMode) { switch(resamplingMode) { case SRCMODE_NEAREST: return ndxNoInterpolation; case SRCMODE_LINEAR: return ndxLinear; case SRCMODE_SPLINE: return ndxFastSinc; case SRCMODE_POLYPHASE: return ndxKaiser; case SRCMODE_FIRFILTER: return ndxFIRFilter; case SRCMODE_AMIGA: return ndxAmigaBlep; default: MPT_ASSERT_NOTREACHED(); } return ndxNoInterpolation; } } // namespace MixFuncTable OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/modcommand.cpp0000644000372100037210000006656013164747010020737 00000000000000/* * ModCommand.cpp * -------------- * Purpose: Various functions for writing effects to patterns, converting ModCommands, etc. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Sndfile.h" #include "mod_specifications.h" #include "Tables.h" OPENMPT_NAMESPACE_BEGIN const EffectType effectTypes[] = { EFFECT_TYPE_NORMAL, EFFECT_TYPE_NORMAL, EFFECT_TYPE_PITCH, EFFECT_TYPE_PITCH, EFFECT_TYPE_PITCH, EFFECT_TYPE_PITCH, EFFECT_TYPE_VOLUME, EFFECT_TYPE_VOLUME, EFFECT_TYPE_VOLUME, EFFECT_TYPE_PANNING, EFFECT_TYPE_NORMAL, EFFECT_TYPE_VOLUME, EFFECT_TYPE_GLOBAL, EFFECT_TYPE_VOLUME, EFFECT_TYPE_GLOBAL, EFFECT_TYPE_NORMAL, EFFECT_TYPE_GLOBAL, EFFECT_TYPE_GLOBAL, EFFECT_TYPE_NORMAL, EFFECT_TYPE_NORMAL, EFFECT_TYPE_NORMAL, EFFECT_TYPE_VOLUME, EFFECT_TYPE_VOLUME, EFFECT_TYPE_GLOBAL, EFFECT_TYPE_GLOBAL, EFFECT_TYPE_NORMAL, EFFECT_TYPE_PITCH, EFFECT_TYPE_PANNING, EFFECT_TYPE_PITCH, EFFECT_TYPE_PANNING, EFFECT_TYPE_NORMAL, EFFECT_TYPE_NORMAL, EFFECT_TYPE_NORMAL, EFFECT_TYPE_NORMAL, EFFECT_TYPE_NORMAL, EFFECT_TYPE_PITCH, EFFECT_TYPE_PITCH, EFFECT_TYPE_PITCH, EFFECT_TYPE_PITCH, EFFECT_TYPE_NORMAL, EFFECT_TYPE_NORMAL, EFFECT_TYPE_NORMAL, }; STATIC_ASSERT(CountOf(effectTypes) == MAX_EFFECTS); const EffectType volumeEffectTypes[] = { EFFECT_TYPE_NORMAL, EFFECT_TYPE_VOLUME, EFFECT_TYPE_PANNING, EFFECT_TYPE_VOLUME, EFFECT_TYPE_VOLUME, EFFECT_TYPE_VOLUME, EFFECT_TYPE_VOLUME, EFFECT_TYPE_PITCH, EFFECT_TYPE_PITCH, EFFECT_TYPE_PANNING, EFFECT_TYPE_PANNING, EFFECT_TYPE_PITCH, EFFECT_TYPE_PITCH, EFFECT_TYPE_PITCH, EFFECT_TYPE_NORMAL, EFFECT_TYPE_NORMAL, }; STATIC_ASSERT(CountOf(volumeEffectTypes) == MAX_VOLCMDS); EffectType ModCommand::GetEffectType(COMMAND cmd) { if(cmd < CountOf(effectTypes)) { return effectTypes[cmd]; } else { return EFFECT_TYPE_NORMAL; } } EffectType ModCommand::GetVolumeEffectType(VOLCMD volcmd) { if(volcmd < CountOf(volumeEffectTypes)) { return volumeEffectTypes[volcmd]; } else { return EFFECT_TYPE_NORMAL; } } // Convert an Exx command (MOD) to Sxx command (S3M) void ModCommand::ExtendedMODtoS3MEffect() { if(command != CMD_MODCMDEX) return; command = CMD_S3MCMDEX; switch(param & 0xF0) { case 0x10: command = CMD_PORTAMENTOUP; param |= 0xF0; break; case 0x20: command = CMD_PORTAMENTODOWN; param |= 0xF0; break; case 0x30: param = (param & 0x0F) | 0x10; break; case 0x40: param = (param & 0x03) | 0x30; break; case 0x50: param = (param & 0x0F) | 0x20; break; case 0x60: param = (param & 0x0F) | 0xB0; break; case 0x70: param = (param & 0x03) | 0x40; break; case 0x90: command = CMD_RETRIG; param = (param & 0x0F); break; case 0xA0: if(param & 0x0F) { command = CMD_VOLUMESLIDE; param = (param << 4) | 0x0F; } else command = CMD_NONE; break; case 0xB0: if(param & 0x0F) { command = CMD_VOLUMESLIDE; param |= 0xF0; } else command = CMD_NONE; break; case 0xC0: if(param == 0xC0) { command = CMD_NONE; note = NOTE_NOTECUT; } break; // this does different things in IT and ST3 case 0xD0: if(param == 0xD0) { command = CMD_NONE; } break; // ditto // rest are the same } } // Convert an Sxx command (S3M) to Exx command (MOD) void ModCommand::ExtendedS3MtoMODEffect() { if(command != CMD_S3MCMDEX) return; command = CMD_MODCMDEX; switch(param & 0xF0) { case 0x10: param = (param & 0x0F) | 0x30; break; case 0x20: param = (param & 0x0F) | 0x50; break; case 0x30: param = (param & 0x0F) | 0x40; break; case 0x40: param = (param & 0x0F) | 0x70; break; case 0x50: command = CMD_XFINEPORTAUPDOWN; break; // map to unused X5x case 0x60: command = CMD_XFINEPORTAUPDOWN; break; // map to unused X6x case 0x90: command = CMD_XFINEPORTAUPDOWN; break; // map to unused X9x case 0xA0: command = CMD_XFINEPORTAUPDOWN; break; // map to unused XAx case 0xB0: param = (param & 0x0F) | 0x60; break; case 0x70: command = CMD_NONE; break; // No NNA / envelope control in MOD/XM format // rest are the same } } // Convert a mod command from one format to another. void ModCommand::Convert(MODTYPE fromType, MODTYPE toType, const CSoundFile &sndFile) { if(fromType == toType) { return; } if(fromType == MOD_TYPE_MTM) { // Special MTM fixups. // Retrigger with param 0 if(command == CMD_MODCMDEX && param == 0x90) { command = CMD_NONE; } else if(command == CMD_VIBRATO) { // Vibrato is approximately half as deep compared to MOD/S3M. uint8 speed = (param & 0xF0); uint8 depth = (param & 0x0F) >> 1; param = speed | depth; } // Apart from these special fixups, do a regular conversion from MOD. fromType = MOD_TYPE_MOD; } // helper variables const bool oldTypeIsMOD = (fromType == MOD_TYPE_MOD), oldTypeIsXM = (fromType == MOD_TYPE_XM), oldTypeIsS3M = (fromType == MOD_TYPE_S3M), oldTypeIsIT = (fromType == MOD_TYPE_IT), oldTypeIsMPT = (fromType == MOD_TYPE_MPT), oldTypeIsMOD_XM = (oldTypeIsMOD || oldTypeIsXM), oldTypeIsS3M_IT_MPT = (oldTypeIsS3M || oldTypeIsIT || oldTypeIsMPT), oldTypeIsIT_MPT = (oldTypeIsIT || oldTypeIsMPT); const bool newTypeIsMOD = (toType == MOD_TYPE_MOD), newTypeIsXM = (toType == MOD_TYPE_XM), newTypeIsS3M = (toType == MOD_TYPE_S3M), newTypeIsIT = (toType == MOD_TYPE_IT), newTypeIsMPT = (toType == MOD_TYPE_MPT), newTypeIsMOD_XM = (newTypeIsMOD || newTypeIsXM), newTypeIsS3M_IT_MPT = (newTypeIsS3M || newTypeIsIT || newTypeIsMPT), newTypeIsIT_MPT = (newTypeIsIT || newTypeIsMPT); const CModSpecifications &newSpecs = CSoundFile::GetModSpecifications(toType); ////////////////////////// // Convert 8-bit Panning if(command == CMD_PANNING8) { if(newTypeIsS3M) { param = (param + 1) >> 1; } else if(oldTypeIsS3M) { if(param == 0xA4) { // surround remap command = static_cast((toType & (MOD_TYPE_IT | MOD_TYPE_MPT)) ? CMD_S3MCMDEX : CMD_XFINEPORTAUPDOWN); param = 0x91; } else { param = std::min(param << 1, 0xFF); } } } // End if(command == CMD_PANNING8) // Re-map \xx to Zxx if the new format only knows the latter command. if(command == CMD_SMOOTHMIDI && !newSpecs.HasCommand(CMD_SMOOTHMIDI) && newSpecs.HasCommand(CMD_MIDI)) { command = CMD_MIDI; } /////////////////////////////////////////////////////////////////////////////////////// // MPTM to anything: Convert param control, extended envelope control, note delay+cut if(oldTypeIsMPT) { if(IsPcNote()) { COMMAND newCmd = static_cast(note == NOTE_PC ? CMD_MIDI : CMD_SMOOTHMIDI); if(!newSpecs.HasCommand(newCmd)) { newCmd = CMD_MIDI; // assuming that this was CMD_SMOOTHMIDI if(!newSpecs.HasCommand(newCmd)) { newCmd = CMD_NONE; } } param = (PARAM)(std::min(maxColumnValue, GetValueEffectCol()) * 0x7F / maxColumnValue); command = newCmd; // might be removed later volcmd = VOLCMD_NONE; note = NOTE_NONE; instr = 0; } // adjust extended envelope control commands if((command == CMD_S3MCMDEX) && ((param & 0xF0) == 0x70) && ((param & 0x0F) > 0x0C)) { param = 0x7C; } if(command == CMD_DELAYCUT) { command = CMD_S3MCMDEX; // When converting to MOD/XM, this will be converted to CMD_MODCMDEX later param = 0xD0 | (param >> 4); // Preserve delay nibble. } } // End if(oldTypeIsMPT) ///////////////////////////////////////// // Convert MOD / XM to S3M / IT / MPTM if(oldTypeIsMOD_XM && newTypeIsS3M_IT_MPT) { switch(command) { case CMD_ARPEGGIO: if(!param) command = CMD_NONE; // 000 does nothing in MOD/XM break; case CMD_MODCMDEX: ExtendedMODtoS3MEffect(); break; case CMD_VOLUME: // Effect column volume command overrides the volume column in XM. if(volcmd == VOLCMD_NONE || volcmd == VOLCMD_VOLUME) { volcmd = VOLCMD_VOLUME; vol = param; if(vol > 64) vol = 64; command = CMD_NONE; param = 0; } else if(volcmd == VOLCMD_PANNING) { std::swap(vol, param); volcmd = VOLCMD_VOLUME; if(vol > 64) vol = 64; command = CMD_S3MCMDEX; param = 0x80 | (param / 4); // XM volcol panning is actually 4-Bit, so we can use 4-Bit panning here. } break; case CMD_PORTAMENTOUP: if(param > 0xDF) param = 0xDF; break; case CMD_PORTAMENTODOWN: if(param > 0xDF) param = 0xDF; break; case CMD_XFINEPORTAUPDOWN: switch(param & 0xF0) { case 0x10: command = CMD_PORTAMENTOUP; param = (param & 0x0F) | 0xE0; break; case 0x20: command = CMD_PORTAMENTODOWN; param = (param & 0x0F) | 0xE0; break; case 0x50: case 0x60: case 0x70: case 0x90: case 0xA0: command = CMD_S3MCMDEX; // Surround remap (this is the "official" command) if(toType & MOD_TYPE_S3M && param == 0x91) { command = CMD_PANNING8; param = 0xA4; } break; } break; case CMD_KEYOFF: if(note == NOTE_NONE) { note = newTypeIsS3M ? NOTE_NOTECUT : NOTE_KEYOFF; command = CMD_S3MCMDEX; if(param == 0) instr = 0; param = 0xD0 | (param & 0x0F); } break; case CMD_PANNINGSLIDE: // swap L/R, convert to fine slide if(param & 0xF0) { param = 0xF0 | std::min(0x0E, (param >> 4)); } else { param = 0x0F | (std::min(0x0E, param & 0x0F) << 4); } default: break; } } // End if(oldTypeIsMOD_XM && newTypeIsS3M_IT_MPT) ///////////////////////////////////////// // Convert S3M / IT / MPTM to MOD / XM else if(oldTypeIsS3M_IT_MPT && newTypeIsMOD_XM) { if(note == NOTE_NOTECUT) { // convert note cut to EC0 if possible or volume command otherwise (MOD/XM has no real way of cutting notes that cannot be "undone" by volume commands) note = NOTE_NONE; if(command == CMD_NONE || !newTypeIsXM) { command = CMD_MODCMDEX; param = 0xC0; } else { volcmd = VOLCMD_VOLUME; vol = 0; } } else if(note == NOTE_FADE) { // convert note fade to note off note = NOTE_KEYOFF; } switch(command) { case CMD_S3MCMDEX: ExtendedS3MtoMODEffect(); break; case CMD_TONEPORTAVOL: // Can't do fine slides and portamento/vibrato at the same time :( case CMD_VIBRATOVOL: // ditto if(volcmd == VOLCMD_NONE && (((param & 0xF0) && ((param & 0x0F) == 0x0F)) || ((param & 0x0F) && ((param & 0xF0) == 0xF0)))) { // Try to salvage portamento/vibrato if(command == CMD_TONEPORTAVOL) volcmd = VOLCMD_TONEPORTAMENTO; else if(command == CMD_VIBRATOVOL) volcmd = VOLCMD_VIBRATODEPTH; vol = 0; } MPT_FALLTHROUGH; case CMD_VOLUMESLIDE: if((param & 0xF0) && ((param & 0x0F) == 0x0F)) { command = CMD_MODCMDEX; param = (param >> 4) | 0xA0; } else if((param & 0x0F) && ((param & 0xF0) == 0xF0)) { command = CMD_MODCMDEX; param = (param & 0x0F) | 0xB0; } break; case CMD_PORTAMENTOUP: if(param >= 0xF0) { command = CMD_MODCMDEX; param = (param & 0x0F) | 0x10; } else if(param >= 0xE0) { if(newTypeIsXM) { command = CMD_XFINEPORTAUPDOWN; param = 0x10 | (param & 0x0F); } else { command = CMD_MODCMDEX; param = (((param & 0x0F) + 3) >> 2) | 0x10; } } else { command = CMD_PORTAMENTOUP; } break; case CMD_PORTAMENTODOWN: if(param >= 0xF0) { command = CMD_MODCMDEX; param = (param & 0x0F) | 0x20; } else if(param >= 0xE0) { if(newTypeIsXM) { command = CMD_XFINEPORTAUPDOWN; param = 0x20 | (param & 0x0F); } else { command = CMD_MODCMDEX; param = (((param & 0x0F) + 3) >> 2) | 0x20; } } else { command = CMD_PORTAMENTODOWN; } break; case CMD_TEMPO: if(param < 0x20) command = CMD_NONE; // no tempo slides break; case CMD_PANNINGSLIDE: // swap L/R, convert fine slides to normal slides if((param & 0x0F) == 0x0F && (param & 0xF0)) { param = (param >> 4); } else if((param & 0xF0) == 0xF0 && (param & 0x0F)) { param = (param & 0x0F) << 4; } else if(param & 0x0F) { param = 0xF0; } else if(param & 0xF0) { param = 0x0F; } else { param = 0; } break; case CMD_RETRIG: // Retrig: Q0y doesn't change volume in IT/S3M, but R0y in XM takes the last x parameter if(param != 0 && (param & 0xF0) == 0) { param |= 0x80; } break; default: break; } } // End if(oldTypeIsS3M_IT_MPT && newTypeIsMOD_XM) /////////////////////// // Convert IT to S3M else if(oldTypeIsIT_MPT && newTypeIsS3M) { if(note == NOTE_KEYOFF || note == NOTE_FADE) note = NOTE_NOTECUT; switch(command) { case CMD_S3MCMDEX: switch(param & 0xF0) { case 0x70: command = CMD_NONE; break; // No NNA / envelope control in S3M format case 0x90: if(param == 0x91) { // surround remap (this is the "official" command) command = CMD_PANNING8; param = 0xA4; } else if(param == 0x90) { command = CMD_PANNING8; param = 0x40; } break; } break; case CMD_GLOBALVOLUME: param = (std::min(0x80, param) + 1) / 2u; break; default: break; } } // End if(oldTypeIsIT_MPT && newTypeIsS3M) ////////////////////// // Convert IT to XM if(oldTypeIsIT_MPT && newTypeIsXM) { switch(command) { case CMD_VIBRATO: // With linear slides, strength is roughly doubled. param = (param & 0xF0) | (((param & 0x0F) + 1) / 2u); break; case CMD_GLOBALVOLUME: param = (std::min(0x80, param) + 1) / 2u; break; } } // End if(oldTypeIsIT_MPT && newTypeIsXM) ////////////////////// // Convert XM to IT if(oldTypeIsXM && newTypeIsIT_MPT) { switch(command) { case CMD_VIBRATO: // With linear slides, strength is roughly halved. param = (param & 0xF0) | std::min((param & 0x0F) * 2u, 15); break; case CMD_GLOBALVOLUME: param = std::min(0x80, param * 2u); break; } } // End if(oldTypeIsIT_MPT && newTypeIsXM) /////////////////////////////////// // MOD / XM Speed/Tempo limits if(newTypeIsMOD_XM) { switch(command) { case CMD_SPEED: param = std::min(param, 0x1F); break; break; case CMD_TEMPO: param = std::max(param, 0x20); break; } } /////////////////////////////////////////////////////////////////////// // Convert MOD to anything - adjust effect memory, remove Invert Loop if(oldTypeIsMOD) { switch(command) { case CMD_TONEPORTAVOL: // lacks memory -> 500 is the same as 300 if(param == 0x00) command = CMD_TONEPORTAMENTO; break; case CMD_VIBRATOVOL: // lacks memory -> 600 is the same as 400 if(param == 0x00) command = CMD_VIBRATO; break; case CMD_MODCMDEX: // This would turn into "Set Active Macro", so let's better remove it case CMD_S3MCMDEX: if((param & 0xF0) == 0xF0) command = CMD_NONE; break; } } // End if(oldTypeIsMOD && newTypeIsXM) ///////////////////////////////////////////////////////////////////// // Convert anything to MOD - remove volume column, remove Set Macro if(newTypeIsMOD) { // convert note off events if(IsSpecialNote()) { note = NOTE_NONE; // no effect present, so just convert note off to volume 0 if(command == CMD_NONE) { command = CMD_VOLUME; param = 0; // EDx effect present, so convert it to ECx } else if((command == CMD_MODCMDEX) && ((param & 0xF0) == 0xD0)) { param = 0xC0 | (param & 0x0F); } } if(command != CMD_NONE) switch(command) { case CMD_RETRIG: // MOD only has E9x command = CMD_MODCMDEX; param = 0x90 | (param & 0x0F); break; case CMD_MODCMDEX: // This would turn into "Invert Loop", so let's better remove it if((param & 0xF0) == 0xF0) command = CMD_NONE; break; } if(command == CMD_NONE) switch(volcmd) { case VOLCMD_VOLUME: command = CMD_VOLUME; param = vol; break; case VOLCMD_PANNING: command = CMD_PANNING8; param = vol < 64 ? vol << 2 : 255; break; case VOLCMD_VOLSLIDEDOWN: command = CMD_VOLUMESLIDE; param = vol; break; case VOLCMD_VOLSLIDEUP: command = CMD_VOLUMESLIDE; param = vol << 4; break; case VOLCMD_FINEVOLDOWN: command = CMD_MODCMDEX; param = 0xB0 | vol; break; case VOLCMD_FINEVOLUP: command = CMD_MODCMDEX; param = 0xA0 | vol; break; case VOLCMD_PORTADOWN: command = CMD_PORTAMENTODOWN; param = vol << 2; break; case VOLCMD_PORTAUP: command = CMD_PORTAMENTOUP; param = vol << 2; break; case VOLCMD_TONEPORTAMENTO: command = CMD_TONEPORTAMENTO; param = vol << 2; break; case VOLCMD_VIBRATODEPTH: command = CMD_VIBRATO; param = vol; break; case VOLCMD_VIBRATOSPEED: command = CMD_VIBRATO; param = vol << 4; break; } volcmd = VOLCMD_NONE; } // End if(newTypeIsMOD) /////////////////////////////////////////////////// // Convert anything to S3M - adjust volume column if(newTypeIsS3M) { if(command == CMD_NONE) switch(volcmd) { case VOLCMD_VOLSLIDEDOWN: command = CMD_VOLUMESLIDE; param = vol; volcmd = VOLCMD_NONE; break; case VOLCMD_VOLSLIDEUP: command = CMD_VOLUMESLIDE; param = vol << 4; volcmd = VOLCMD_NONE; break; case VOLCMD_FINEVOLDOWN: command = CMD_VOLUMESLIDE; param = 0xF0 | vol; volcmd = VOLCMD_NONE; break; case VOLCMD_FINEVOLUP: command = CMD_VOLUMESLIDE; param = (vol << 4) | 0x0F; volcmd = VOLCMD_NONE; break; case VOLCMD_PORTADOWN: command = CMD_PORTAMENTODOWN; param = vol << 2; volcmd = VOLCMD_NONE; break; case VOLCMD_PORTAUP: command = CMD_PORTAMENTOUP; param = vol << 2; volcmd = VOLCMD_NONE; break; case VOLCMD_TONEPORTAMENTO: command = CMD_TONEPORTAMENTO; param = vol << 2; volcmd = VOLCMD_NONE; break; case VOLCMD_VIBRATODEPTH: command = CMD_VIBRATO; param = vol; volcmd = VOLCMD_NONE; break; case VOLCMD_VIBRATOSPEED: command = CMD_VIBRATO; param = vol << 4; volcmd = VOLCMD_NONE; break; case VOLCMD_PANSLIDELEFT: command = CMD_PANNINGSLIDE; param = vol << 4; volcmd = VOLCMD_NONE; break; case VOLCMD_PANSLIDERIGHT: command = CMD_PANNINGSLIDE; param = vol; volcmd = VOLCMD_NONE; break; } } // End if(newTypeIsS3M) //////////////////////////////////////////////////////////////////////// // Convert anything to XM - adjust volume column, breaking EDx command if(newTypeIsXM) { // remove EDx if no note is next to it, or it will retrigger the note in FT2 mode if(command == CMD_MODCMDEX && (param & 0xF0) == 0xD0 && note == NOTE_NONE) { command = CMD_NONE; param = 0; } if(IsSpecialNote()) { // Instrument numbers next to Note Off reset instrument settings instr = 0; if(command == CMD_MODCMDEX && (param & 0xF0) == 0xD0) { // Note Off + Note Delay does nothing when using envelopes. note = NOTE_NONE; command = CMD_KEYOFF; param &= 0x0F; } } // Convert some commands which behave differently or don't exist if(command == CMD_NONE) switch(volcmd) { case VOLCMD_PORTADOWN: command = CMD_PORTAMENTODOWN; param = vol << 2; volcmd = VOLCMD_NONE; break; case VOLCMD_PORTAUP: command = CMD_PORTAMENTOUP; param = vol << 2; volcmd = VOLCMD_NONE; break; case VOLCMD_TONEPORTAMENTO: command = CMD_TONEPORTAMENTO; param = ImpulseTrackerPortaVolCmd[vol & 0x0F]; volcmd = VOLCMD_NONE; break; } } // End if(newTypeIsXM) /////////////////////////////////////////////////// // Convert anything to IT - adjust volume column if(newTypeIsIT_MPT) { // Convert some commands which behave differently or don't exist if(command == CMD_NONE) switch(volcmd) { case VOLCMD_PANSLIDELEFT: command = CMD_PANNINGSLIDE; param = vol << 4; volcmd = VOLCMD_NONE; break; case VOLCMD_PANSLIDERIGHT: command = CMD_PANNINGSLIDE; param = vol; volcmd = VOLCMD_NONE; break; case VOLCMD_VIBRATOSPEED: command = CMD_VIBRATO; param = vol << 4; volcmd = VOLCMD_NONE; break; case VOLCMD_TONEPORTAMENTO: command = CMD_TONEPORTAMENTO; param = vol << 4; volcmd = VOLCMD_NONE; break; } switch(volcmd) { case VOLCMD_VOLSLIDEDOWN: case VOLCMD_VOLSLIDEUP: case VOLCMD_FINEVOLDOWN: case VOLCMD_FINEVOLUP: case VOLCMD_PORTADOWN: case VOLCMD_PORTAUP: case VOLCMD_TONEPORTAMENTO: case VOLCMD_VIBRATODEPTH: // OpenMPT-specific commands case VOLCMD_OFFSET: vol = std::min(vol, 9); break; } } // End if(newTypeIsIT_MPT) // Fix volume column offset for formats that don't have it. if(volcmd == VOLCMD_OFFSET && !newSpecs.HasVolCommand(VOLCMD_OFFSET) && (command == CMD_NONE || !newSpecs.HasCommand(command))) { command = CMD_OFFSET; volcmd = VOLCMD_NONE; SAMPLEINDEX smp = instr; if(smp > 0 && smp <= sndFile.GetNumInstruments() && IsNote() && sndFile.Instruments[smp] != nullptr) smp = sndFile.Instruments[smp]->Keyboard[note - NOTE_MIN]; if(smp > 0 && smp <= sndFile.GetNumSamples() && vol > 0 && vol <= CountOf(sndFile.GetSample(smp).cues)) param = mpt::saturate_cast((sndFile.GetSample(smp).cues[vol - 1] + 128) >> 8); else param = vol << 3; } if((command == CMD_REVERSEOFFSET || command == CMD_OFFSETPERCENTAGE) && !newSpecs.HasCommand(command)) { command = CMD_OFFSET; } if(!newSpecs.HasNote(note)) note = NOTE_NONE; // ensure the commands really exist in this format if(!newSpecs.HasCommand(command)) command = CMD_NONE; if(!newSpecs.HasVolCommand(volcmd)) volcmd = VOLCMD_NONE; } bool ModCommand::IsGlobalCommand() const { switch(command) { case CMD_POSITIONJUMP: case CMD_PATTERNBREAK: case CMD_SPEED: case CMD_TEMPO: case CMD_GLOBALVOLUME: case CMD_GLOBALVOLSLIDE: case CMD_MIDI: case CMD_SMOOTHMIDI: case CMD_DBMECHO: return true; case CMD_MODCMDEX: switch(param & 0xF0) { case 0x00: // LED Filter case 0x60: // Pattern Loop case 0xE0: // Row Delay return true; default: return false; } case CMD_XFINEPORTAUPDOWN: case CMD_S3MCMDEX: switch(param & 0xF0) { case 0x60: // Tick Delay case 0x90: // Sound Control case 0xB0: // Pattern Loop case 0xE0: // Row Delay return true; default: return false; } default: return false; } } // "Importance" of every FX command. Table is used for importing from formats with multiple effect colums // and is approximately the same as in SchismTracker. size_t ModCommand::GetEffectWeight(COMMAND cmd) { // Effect weights, sorted from lowest to highest weight. static const COMMAND weights[] = { CMD_NONE, CMD_XPARAM, CMD_SETENVPOSITION, CMD_KEYOFF, CMD_TREMOLO, CMD_FINEVIBRATO, CMD_VIBRATO, CMD_XFINEPORTAUPDOWN, CMD_PANBRELLO, CMD_S3MCMDEX, CMD_MODCMDEX, CMD_DELAYCUT, CMD_MIDI, CMD_SMOOTHMIDI, CMD_PANNINGSLIDE, CMD_PANNING8, CMD_NOTESLIDEUPRETRIG, CMD_NOTESLIDEUP, CMD_NOTESLIDEDOWNRETRIG, CMD_NOTESLIDEDOWN, CMD_PORTAMENTOUP, CMD_PORTAMENTODOWN, CMD_VOLUMESLIDE, CMD_VIBRATOVOL, CMD_VOLUME, CMD_REVERSEOFFSET, CMD_OFFSETPERCENTAGE, CMD_OFFSET, CMD_TREMOR, CMD_RETRIG, CMD_ARPEGGIO, CMD_TONEPORTAMENTO, CMD_TONEPORTAVOL, CMD_DBMECHO, CMD_GLOBALVOLSLIDE, CMD_CHANNELVOLUME, CMD_GLOBALVOLSLIDE, CMD_GLOBALVOLUME, CMD_TEMPO, CMD_SPEED, CMD_POSITIONJUMP, CMD_PATTERNBREAK, }; STATIC_ASSERT(CountOf(weights) == MAX_EFFECTS); for(size_t i = 0; i < CountOf(weights); i++) { if(weights[i] == cmd) { return i; } } // Invalid / unknown command. return 0; } // Try to convert a fx column command (&effect) into a volume column command. // Returns true if successful. // Some commands can only be converted by losing some precision. // If moving the command into the volume column is more important than accuracy, use force = true. // (Code translated from SchismTracker and mainly supposed to be used with loaders ported from this tracker) bool ModCommand::ConvertVolEffect(uint8 &effect, uint8 ¶m, bool force) { switch(effect) { case CMD_NONE: return true; case CMD_VOLUME: effect = VOLCMD_VOLUME; param = std::min(param, 64); break; case CMD_PORTAMENTOUP: // if not force, reject when dividing causes loss of data in LSB, or if the final value is too // large to fit. (volume column Ex/Fx are four times stronger than effect column) if(!force && ((param & 3) || param >= 0xE0)) return false; param /= 4; effect = VOLCMD_PORTAUP; break; case CMD_PORTAMENTODOWN: if(!force && ((param & 3) || param >= 0xE0)) return false; param /= 4; effect = VOLCMD_PORTADOWN; break; case CMD_TONEPORTAMENTO: if(param >= 0xF0) { // hack for people who can't type F twice :) effect = VOLCMD_TONEPORTAMENTO; param = 9; return true; } for(uint8 n = 0; n < 10; n++) { if(force ? (param <= ImpulseTrackerPortaVolCmd[n]) : (param == ImpulseTrackerPortaVolCmd[n])) { effect = VOLCMD_TONEPORTAMENTO; param = n; return true; } } return false; case CMD_VIBRATO: if(force) param = std::min(param & 0x0F, 9); else if((param & 0x0F) > 9 || (param & 0xF0) != 0) return false; param &= 0x0F; effect = VOLCMD_VIBRATODEPTH; break; case CMD_FINEVIBRATO: if(force) param = 0; else if(param) return false; effect = VOLCMD_VIBRATODEPTH; break; case CMD_PANNING8: if(param == 255) param = 64; else param /= 4; effect = VOLCMD_PANNING; break; case CMD_VOLUMESLIDE: if(param == 0) return false; if((param & 0xF) == 0) // Dx0 / Cx { param >>= 4; effect = VOLCMD_VOLSLIDEUP; } else if((param & 0xF0) == 0) // D0x / Dx { effect = VOLCMD_VOLSLIDEDOWN; } else if((param & 0xF) == 0xF) // DxF / Ax { param >>= 4; effect = VOLCMD_FINEVOLUP; } else if((param & 0xF0) == 0xF0) // DFx / Bx { param &= 0xF; effect = VOLCMD_FINEVOLDOWN; } else // ??? { return false; } break; case CMD_S3MCMDEX: switch (param >> 4) { case 8: effect = VOLCMD_PANNING; param = ((param & 0xF) << 2) + 2; return true; case 0: case 1: case 2: case 0xF: if(force) { effect = param = 0; return true; } break; default: break; } return false; default: return false; } return true; } // Try to combine two commands into one. Returns true on success and the combined command is placed in eff1 / param1. bool ModCommand::CombineEffects(uint8 &eff1, uint8 ¶m1, uint8 &eff2, uint8 ¶m2) { if(eff1 == CMD_VOLUMESLIDE && (eff2 == CMD_VIBRATO || eff2 == CMD_TONEPORTAVOL) && param2 == 0) { // Merge commands if(eff2 == CMD_VIBRATO) { eff1 = CMD_VIBRATOVOL; } else { eff1 = CMD_TONEPORTAVOL; } eff2 = CMD_NONE; return true; } else if(eff2 == CMD_VOLUMESLIDE && (eff1 == CMD_VIBRATO || eff1 == CMD_TONEPORTAVOL) && param1 == 0) { // Merge commands if(eff1 == CMD_VIBRATO) { eff1 = CMD_VIBRATOVOL; } else { eff1 = CMD_TONEPORTAVOL; } param1 = param2; eff2 = CMD_NONE; return true; } else if(eff1 == CMD_OFFSET && eff2 == CMD_S3MCMDEX && param2 == 0x9F) { // Reverse offset eff1 = CMD_REVERSEOFFSET; eff2 = CMD_NONE; return true; } else if(eff1 == CMD_S3MCMDEX && param1 == 0x9F && eff2 == CMD_OFFSET) { // Reverse offset eff1 = CMD_REVERSEOFFSET; param1 = param2; eff2 = CMD_NONE; return true; } else { return false; } } bool ModCommand::TwoRegularCommandsToMPT(uint8 &effect1, uint8 ¶m1, uint8 &effect2, uint8 ¶m2) { for(uint8 n = 0; n < 4; n++) { if(ModCommand::ConvertVolEffect(effect1, param1, (n > 1))) { return true; } std::swap(effect1, effect2); std::swap(param1, param2); } // Can only keep one command :( if(GetEffectWeight(static_cast(effect1)) > GetEffectWeight(static_cast(effect2))) { std::swap(effect1, effect2); std::swap(param1, param2); } effect1 = VOLCMD_NONE; param1 = 0; return false; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Load_mdl.cpp0000644000372100037210000005164313161656666020345 00000000000000/* * Load_mdl.cpp * ------------ * Purpose: Digitrakker (MDL) module loader * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" #include "ChunkReader.h" #include OPENMPT_NAMESPACE_BEGIN // MDL file header struct MDLFileHeader { char id[4]; // "DMDL" uint8 version; }; MPT_BINARY_STRUCT(MDLFileHeader, 5) // RIFF-style Chunk struct MDLChunk { // 16-Bit chunk identifiers enum ChunkIdentifiers { idInfo = MAGIC2LE('I','N'), idMessage = MAGIC2LE('M','E'), idPats = MAGIC2LE('P','A'), idPatNames = MAGIC2LE('P','N'), idTracks = MAGIC2LE('T','R'), idInstrs = MAGIC2LE('I','I'), idVolEnvs = MAGIC2LE('V','E'), idPanEnvs = MAGIC2LE('P','E'), idFreqEnvs = MAGIC2LE('F','E'), idSampleInfo = MAGIC2LE('I','S'), ifSampleData = MAGIC2LE('S','A'), }; uint16le id; uint32le length; size_t GetLength() const { return length; } ChunkIdentifiers GetID() const { return static_cast(id.get()); } }; MPT_BINARY_STRUCT(MDLChunk, 6) struct MDLInfoBlock { char title[32]; char composer[20]; uint16le numOrders; uint16le restartPos; uint8le globalVol; // 1...255 uint8le speed; // 1...255 uint8le tempo; // 4...255 uint8le chnSetup[32]; }; MPT_BINARY_STRUCT(MDLInfoBlock, 91) // Sample header in II block struct MDLSampleHeader { uint8le smpNum; uint8le lastNote; uint8le volume; uint8le volEnvFlags; // 6 bits env #, 2 bits flags uint8le panning; uint8le panEnvFlags; uint16le fadeout; uint8le vibSpeed; uint8le vibDepth; uint8le vibSweep; uint8le vibType; uint8le reserved; // zero uint8le freqEnvFlags; }; MPT_BINARY_STRUCT(MDLSampleHeader, 14) // Part of the sample header that's common between v0 and v1. struct MDLSampleInfoCommon { uint8le sampleIndex; char name[32]; char filename[8]; }; MPT_BINARY_STRUCT(MDLSampleInfoCommon, 41) struct MDLEnvelope { uint8 envNum; struct { uint8 x; // Delta value from last point, 0 means no more points defined uint8 y; // 0...63 } nodes[15]; uint8 flags; uint8 loop; // Lower 4 bits = start, upper 4 bits = end void ConvertToMPT(InstrumentEnvelope &mptEnv) const { mptEnv.dwFlags.reset(); mptEnv.clear(); mptEnv.reserve(15); int16 tick = -nodes[0].x; for(uint8 n = 0; n < 15; n++) { if(!nodes[n].x) break; tick += nodes[n].x; mptEnv.push_back(EnvelopeNode(tick, std::min(nodes[n].y, uint8(64)))); // actually 0-63 } mptEnv.nLoopStart = (loop & 0x0F); mptEnv.nLoopEnd = (loop >> 4); mptEnv.nSustainStart = mptEnv.nSustainEnd = (flags & 0x0F); if(flags & 0x10) mptEnv.dwFlags.set(ENV_SUSTAIN); if(flags & 0x20) mptEnv.dwFlags.set(ENV_LOOP); } }; MPT_BINARY_STRUCT(MDLEnvelope, 33) struct MDLPatternHeader { uint8le channels; uint8le lastRow; char name[16]; }; MPT_BINARY_STRUCT(MDLPatternHeader, 18) enum { MDLNOTE_NOTE = 1 << 0, MDLNOTE_SAMPLE = 1 << 1, MDLNOTE_VOLUME = 1 << 2, MDLNOTE_EFFECTS = 1 << 3, MDLNOTE_PARAM1 = 1 << 4, MDLNOTE_PARAM2 = 1 << 5, }; static const uint8 MDLVibratoType[] = { VIB_SINE, VIB_RAMP_DOWN, VIB_SQUARE, VIB_SINE }; static const ModCommand::COMMAND MDLEffTrans[] = { /* 0 */ CMD_NONE, /* 1st column only */ /* 1 */ CMD_PORTAMENTOUP, /* 2 */ CMD_PORTAMENTODOWN, /* 3 */ CMD_TONEPORTAMENTO, /* 4 */ CMD_VIBRATO, /* 5 */ CMD_ARPEGGIO, /* 6 */ CMD_NONE, /* Either column */ /* 7 */ CMD_TEMPO, /* 8 */ CMD_PANNING8, /* 9 */ CMD_SETENVPOSITION, /* A */ CMD_NONE, /* B */ CMD_POSITIONJUMP, /* C */ CMD_GLOBALVOLUME, /* D */ CMD_PATTERNBREAK, /* E */ CMD_S3MCMDEX, /* F */ CMD_SPEED, /* 2nd column only */ /* G */ CMD_VOLUMESLIDE, // up /* H */ CMD_VOLUMESLIDE, // down /* I */ CMD_RETRIG, /* J */ CMD_TREMOLO, /* K */ CMD_TREMOR, /* L */ CMD_NONE, }; // receive an MDL effect, give back a 'normal' one. static void ConvertMDLCommand(uint8_t &cmd, uint8_t ¶m) { if(cmd >= CountOf(MDLEffTrans)) return; uint8 origCmd = cmd; cmd = MDLEffTrans[cmd]; switch(origCmd) { #ifdef MODPLUG_TRACKER case 0x07: // Tempo // MDL supports any nonzero tempo value, but OpenMPT doesn't param = std::max(param, uint8(0x20)); break; #endif // MODPLUG_TRACKER case 0x08: // Panning param = (param & 0x7F) * 2u; break; case 0x0C: // Global volume param = (param + 1) / 2u; break; case 0x0D: // Pattern Break // Convert from BCD param = 10 * (param >> 4) + (param & 0x0F); break; case 0x0E: // Special switch(param >> 4) { case 0x0: // unused case 0x3: // unused case 0x5: // Set Finetune case 0x8: // Set Samplestatus (loop type) cmd = CMD_NONE; break; case 0x1: // Pan Slide Left cmd = CMD_PANNINGSLIDE; param = (std::min(param & 0x0F, 0x0E) << 4) | 0x0F; break; case 0x2: // Pan Slide Right cmd = CMD_PANNINGSLIDE; param = 0xF0 | std::min(param & 0x0F, 0x0E); break; case 0x4: // Vibrato Waveform param = 0x30 | (param & 0x0F); break; case 0x6: // Pattern Loop param = 0xB0 | (param & 0x0F); break; case 0x7: // Tremolo Waveform param = 0x40 | (param & 0x0F); break; case 0x9: // Retrig cmd = CMD_RETRIG; param &= 0x0F; break; case 0xA: // Global vol slide up cmd = CMD_GLOBALVOLSLIDE; param = 0xF0 & (((param & 0x0F) + 1) << 3); break; case 0xB: // Global vol slide down cmd = CMD_GLOBALVOLSLIDE; param = ((param & 0x0F) + 1) >> 1; break; case 0xC: // Note cut case 0xD: // Note delay case 0xE: // Pattern delay // Nothing to change here break; case 0xF: // Offset -- further mangled later. cmd = CMD_OFFSET; break; } break; case 0x10: // Volslide up if(param < 0xE0) { // 00...DF regular slide - four times more precise than in XM param >>= 2; if(param > 0x0F) param = 0x0F; param <<= 4; } else if(param < 0xF0) { // E0...EF extra fine slide (on first tick, 4 times finer) param = (((param & 0x0F) << 2) | 0x0F); } else { // F0...FF regular fine slide (on first tick) - like in XM param = ((param << 4) | 0x0F); } break; case 0x11: // Volslide down if(param < 0xE0) { // 00...DF regular slide - four times more precise than in XM param >>= 2; if(param > 0x0F) param = 0x0F; } else if(param < 0xF0) { // E0...EF extra fine slide (on first tick, 4 times finer) param = (((param & 0x0F) >> 2) | 0xF0); } else { // F0...FF regular fine slide (on first tick) - like in XM } break; } } // Returns true if command was lost static bool ImportMDLCommands(ModCommand &m, uint8 vol, uint8 e1, uint8 e2, uint8 p1, uint8 p2) { // Map second effect values 1-6 to effects G-L if(e2 >= 1 && e2 <= 6) e2 += 15; ConvertMDLCommand(e1, p1); ConvertMDLCommand(e2, p2); /* From the Digitrakker documentation: * EFx -xx - Set Sample Offset This is a double-command. It starts the sample at adress xxx*256. Example: C-5 01 -- EF1 -23 ->starts sample 01 at address 12300 (in hex). Kind of screwy, but I guess it's better than the mess required to do it with IT (which effectively requires 3 rows in order to set the offset past 0xff00). If we had access to the entire track, we *might* be able to shove the high offset SAy into surrounding rows (or 2x MPTM #xx), but it wouldn't always be possible, it'd make the loader a lot uglier, and generally would be more trouble than it'd be worth to implement. What's more is, if there's another effect in the second column, it's ALSO processed in addition to the offset, and the second data byte is shared between the two effects. */ if(e1 == CMD_OFFSET) { // EFy -xx => offset yxx00 p1 = (p1 & 0x0F) ? 0xFF : p2; if(e2 == CMD_OFFSET) e2 = CMD_NONE; } else if (e2 == CMD_OFFSET) { // --- EFy => offset y0000 (best we can do without doing a ton of extra work is 0xff00) p2 = (p2 & 0x0F) ? 0xFF : 0; } if(vol) { m.volcmd = VOLCMD_VOLUME; m.vol = (vol + 2) / 4u; } // If we have Dxx + G00, or Dxx + H00, combine them into Lxx/Kxx. ModCommand::CombineEffects(e1, p1, e2, p2); bool lostCommand = false; // Try to fit the "best" effect into e2. if(e1 == CMD_NONE) { // Easy } else if(e2 == CMD_NONE) { // Almost as easy e2 = e1; p2 = p1; e1 = CMD_NONE; } else if(e1 == e2 && e1 != CMD_S3MCMDEX) { // Digitrakker processes the effects left-to-right, so if both effects are the same, the // second essentially overrides the first. e1 = CMD_NONE; } else if(!vol) { lostCommand |= !ModCommand::TwoRegularCommandsToMPT(e1, p1, e2, p2); m.volcmd = e1; m.vol = p1; } else { if(ModCommand::GetEffectWeight((ModCommand::COMMAND)e1) > ModCommand::GetEffectWeight((ModCommand::COMMAND)e2)) { std::swap(e1, e2); std::swap(p1, p2); } } m.command = e2; m.param = p2; return lostCommand; } static void MDLReadEnvelopes(FileReader file, std::vector &envelopes) { if(!file.CanRead(1)) return; envelopes.resize(64); uint8 numEnvs = file.ReadUint8(); while(numEnvs--) { MDLEnvelope mdlEnv; if(!file.ReadStruct(mdlEnv) || mdlEnv.envNum > 63) continue; envelopes[mdlEnv.envNum] = mdlEnv; } } static void CopyEnvelope(InstrumentEnvelope &mptEnv, uint8 flags, std::vector &envelopes) { uint8 envNum = flags & 0x3F; if(envNum < envelopes.size()) envelopes[envNum].ConvertToMPT(mptEnv); mptEnv.dwFlags.set(ENV_ENABLED, (flags & 0x80) && !mptEnv.empty()); } static bool ValidateHeader(const MDLFileHeader &fileHeader) { if(std::memcmp(fileHeader.id, "DMDL", 4) || fileHeader.version >= 0x20) { return false; } return true; } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderMDL(MemoryFileReader file, const uint64 *pfilesize) { MDLFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return ProbeWantMoreData; } if(!ValidateHeader(fileHeader)) { return ProbeFailure; } MPT_UNREFERENCED_PARAMETER(pfilesize); return ProbeSuccess; } bool CSoundFile::ReadMDL(FileReader &file, ModLoadingFlags loadFlags) { file.Rewind(); MDLFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return false; } if(!ValidateHeader(fileHeader)) { return false; } if(loadFlags == onlyVerifyHeader) { return true; } ChunkReader chunkFile(file); ChunkReader::ChunkList chunks = chunkFile.ReadChunks(0); // Read global info FileReader chunk = chunks.GetChunk(MDLChunk::idInfo); MDLInfoBlock info; if(!chunk.IsValid() || !chunk.ReadStruct(info)) { return false; } InitializeGlobals(MOD_TYPE_MDL); m_SongFlags = SONG_ITCOMPATGXX; m_playBehaviour.set(kPerChannelGlobalVolSlide); m_playBehaviour.reset(kITVibratoTremoloPanbrello); m_playBehaviour.reset(kITSCxStopsSample); // Gate effect in underbeat.mdl m_madeWithTracker = MPT_USTRING("Digitrakker ") + ( (fileHeader.version == 0x11) ? MPT_USTRING("3") // really could be 2.99b - close enough : (fileHeader.version == 0x10) ? MPT_USTRING("2.3") : (fileHeader.version == 0x00) ? MPT_USTRING("2.0 - 2.2b") // there was no 1.x release : MPT_USTRING("")); mpt::String::Read(m_songName, info.title); { std::string artist; mpt::String::Read(artist, info.composer); m_songArtist = mpt::ToUnicode(mpt::CharsetCP437, artist); } m_nDefaultGlobalVolume = info.globalVol + 1; m_nDefaultSpeed = Clamp(info.speed, 1, 255); m_nDefaultTempo.Set(Clamp(info.tempo, 4, 255)); ReadOrderFromFile(Order(), chunk, info.numOrders); Order().SetRestartPos(info.restartPos); m_nChannels = 0; for(CHANNELINDEX c = 0; c < 32; c++) { ChnSettings[c].Reset(); ChnSettings[c].nPan = (info.chnSetup[c] & 0x7F) * 2u; if(ChnSettings[c].nPan == 254) ChnSettings[c].nPan = 256; if(info.chnSetup[c] & 0x80) ChnSettings[c].dwFlags.set(CHN_MUTE); else m_nChannels = c + 1; chunk.ReadString(ChnSettings[c].szName, 8); } // Read song message chunk = chunks.GetChunk(MDLChunk::idMessage); m_songMessage.Read(chunk, chunk.GetLength(), SongMessage::leCR); // Read sample info and data chunk = chunks.GetChunk(MDLChunk::idSampleInfo); if(chunk.IsValid()) { FileReader dataChunk = chunks.GetChunk(MDLChunk::ifSampleData); uint8 numSamples = chunk.ReadUint8(); for(uint8 smp = 0; smp < numSamples; smp++) { MDLSampleInfoCommon header; if(!chunk.ReadStruct(header) || header.sampleIndex == 0) continue; #if 1 STATIC_ASSERT(MPT_MAX_UNSIGNED_VALUE(header.sampleIndex) < MAX_SAMPLES); #else MPT_MAYBE_CONSTANT_IF(header.sampleIndex >= MAX_SAMPLES) continue; #endif if(header.sampleIndex > GetNumSamples()) m_nSamples = header.sampleIndex; ModSample &sample = Samples[header.sampleIndex]; sample.Initialize(); mpt::String::Read(m_szNames[header.sampleIndex], header.name); mpt::String::Read(sample.filename, header.filename); uint32 c4speed; if(fileHeader.version < 0x10) c4speed = chunk.ReadUint16LE(); else c4speed = chunk.ReadUint32LE(); sample.nC5Speed = c4speed * 2u; sample.nLength = chunk.ReadUint32LE(); sample.nLoopStart = chunk.ReadUint32LE(); sample.nLoopEnd = chunk.ReadUint32LE(); if(sample.nLoopEnd != 0) { sample.uFlags.set(CHN_LOOP); sample.nLoopEnd += sample.nLoopStart; } if(fileHeader.version < 0x10) sample.nVolume = chunk.ReadUint8(); else chunk.Skip(1); uint8 flags = chunk.ReadUint8(); if(flags & 0x01) { sample.uFlags.set(CHN_16BIT); sample.nLength /= 2u; sample.nLoopStart /= 2u; sample.nLoopEnd /= 2u; } sample.uFlags.set(CHN_PINGPONGLOOP, (flags & 0x02) != 0); SampleIO sampleIO( (flags & 0x01) ? SampleIO::_16bit : SampleIO::_8bit, SampleIO::mono, SampleIO::littleEndian, (flags & 0x0C) ? SampleIO::MDL : SampleIO::signedPCM); if(loadFlags & loadSampleData) { sampleIO.ReadSample(sample, dataChunk); } } } chunk = chunks.GetChunk(MDLChunk::idInstrs); if(chunk.IsValid()) { std::vector volEnvs, panEnvs, pitchEnvs; MDLReadEnvelopes(chunks.GetChunk(MDLChunk::idVolEnvs), volEnvs); MDLReadEnvelopes(chunks.GetChunk(MDLChunk::idPanEnvs), panEnvs); MDLReadEnvelopes(chunks.GetChunk(MDLChunk::idFreqEnvs), pitchEnvs); uint8 numInstruments = chunk.ReadUint8(); for(uint8 i = 0; i < numInstruments; i++) { uint8 ins = chunk.ReadUint8(); uint8 numSamples = chunk.ReadUint8(); uint8 firstNote = 0; ModInstrument *mptIns = nullptr; if(ins == 0 || !chunk.CanRead(32 + sizeof(MDLSampleHeader) * numSamples) || (mptIns = AllocateInstrument(ins)) == nullptr) { chunk.Skip(32 + sizeof(MDLSampleHeader) * numSamples); continue; } chunk.ReadString(mptIns->name, 32); while(numSamples--) { MDLSampleHeader sampleHeader; chunk.ReadStruct(sampleHeader); if(sampleHeader.smpNum == 0) continue; #if 1 STATIC_ASSERT(MPT_MAX_UNSIGNED_VALUE(sampleHeader.smpNum) < MAX_SAMPLES); #else MPT_MAYBE_CONSTANT_IF(sampleHeader.smpNum >= MAX_SAMPLES) continue; #endif LimitMax(sampleHeader.lastNote, static_cast(CountOf(mptIns->Keyboard))); for(uint8 n = firstNote; n <= sampleHeader.lastNote; n++) { mptIns->Keyboard[n] = sampleHeader.smpNum; } firstNote = sampleHeader.lastNote + 1; CopyEnvelope(mptIns->VolEnv, sampleHeader.volEnvFlags, volEnvs); CopyEnvelope(mptIns->PanEnv, sampleHeader.panEnvFlags, panEnvs); CopyEnvelope(mptIns->PitchEnv, sampleHeader.freqEnvFlags, pitchEnvs); mptIns->nFadeOut = (sampleHeader.fadeout + 1u) / 2u; #ifdef MODPLUG_TRACKER if((mptIns->VolEnv.dwFlags & (ENV_ENABLED | ENV_LOOP)) == ENV_ENABLED) { // Fade-out is only supposed to happen on key-off, not at the end of a volume envelope. // Fake it by putting a loop at the end. mptIns->VolEnv.nLoopStart = mptIns->VolEnv.nLoopEnd = static_cast(mptIns->VolEnv.size() - 1); mptIns->VolEnv.dwFlags.set(ENV_LOOP); } for(auto &p : mptIns->PitchEnv) { // Scale pitch envelope p.value = (p.value * 6u) / 16u; } #endif // MODPLUG_TRACKER // Samples were already initialized above. Let's hope they are not going to be re-used with different volume / panning / vibrato... ModSample &mptSmp = Samples[sampleHeader.smpNum]; // This flag literally enables and disables the default volume of a sample. If you disable this flag, // the sample volume of a previously sample is re-used, even if you put an instrument number next to the note. if(sampleHeader.volEnvFlags & 0x40) mptSmp.nVolume = sampleHeader.volume; else mptSmp.uFlags.set(SMP_NODEFAULTVOLUME); mptSmp.nPan = std::min(sampleHeader.panning * 2, 254); mptSmp.nVibType = MDLVibratoType[sampleHeader.vibType & 3]; mptSmp.nVibSweep = sampleHeader.vibSweep; mptSmp.nVibDepth = sampleHeader.vibDepth; mptSmp.nVibRate = sampleHeader.vibSpeed; if(sampleHeader.panEnvFlags & 0x40) mptSmp.uFlags.set(CHN_PANNING); } } } // Read pattern tracks std::vector tracks; if((loadFlags & loadPatternData) && (chunk = chunks.GetChunk(MDLChunk::idTracks)).IsValid()) { uint32 numTracks = chunk.ReadUint16LE(); tracks.resize(numTracks + 1); for(uint32 i = 1; i <= numTracks; i++) { tracks[i] = chunk.ReadChunk(chunk.ReadUint16LE()); } } // Read actual patterns if((loadFlags & loadPatternData) && (chunk = chunks.GetChunk(MDLChunk::idPats)).IsValid()) { PATTERNINDEX numPats = chunk.ReadUint8(); // In case any muted channels contain data, be sure that we import them as well. for(PATTERNINDEX pat = 0; pat < numPats; pat++) { CHANNELINDEX numChans = 32; if(fileHeader.version >= 0x10) { MDLPatternHeader patHead; chunk.ReadStruct(patHead); if(patHead.channels > m_nChannels && patHead.channels <= 32) m_nChannels = patHead.channels; numChans = patHead.channels; } for(CHANNELINDEX chn = 0; chn < numChans; chn++) { if(chunk.ReadUint16LE() > 0 && chn >= m_nChannels) m_nChannels = chn + 1; } } chunk.Seek(1); Patterns.ResizeArray(numPats); for(PATTERNINDEX pat = 0; pat < numPats; pat++) { CHANNELINDEX numChans = 32; ROWINDEX numRows = 64; char name[17] = ""; if(fileHeader.version >= 0x10) { MDLPatternHeader patHead; chunk.ReadStruct(patHead); numChans = patHead.channels; numRows = patHead.lastRow + 1; mpt::String::Read(name, patHead.name); } if(!Patterns.Insert(pat, numRows)) { chunk.Skip(2 * numChans); continue; } Patterns[pat].SetName(name); for(CHANNELINDEX chn = 0; chn < numChans; chn++) { uint16 trkNum = chunk.ReadUint16LE(); if(!trkNum || trkNum >= tracks.size() || chn >= m_nChannels) continue; FileReader &track = tracks[trkNum]; track.Rewind(); ROWINDEX row = 0; while(row < numRows && track.CanRead(1)) { ModCommand *m = Patterns[pat].GetpModCommand(row, chn); uint8 b = track.ReadUint8(); uint8 x = (b >> 2), y = (b & 3); switch(y) { case 0: // (x + 1) empty notes follow row += x + 1; break; case 1: // Repeat previous note (x + 1) times if(row > 0) { ModCommand &orig = *Patterns[pat].GetpModCommand(row - 1, chn); do { *m = orig; m += m_nChannels; row++; } while (row < numRows && x--); } break; case 2: // Copy note from row x if(row > x) { *m = *Patterns[pat].GetpModCommand(x, chn); } row++; break; case 3: // New note data if(x & MDLNOTE_NOTE) { b = track.ReadUint8(); m->note = (b > 120) ? NOTE_KEYOFF : b; } if(x & MDLNOTE_SAMPLE) { m->instr = track.ReadUint8(); } { uint8 vol = 0, e1 = 0, e2 = 0, p1 = 0, p2 = 0; if(x & MDLNOTE_VOLUME) { vol = track.ReadUint8(); } if(x & MDLNOTE_EFFECTS) { b = track.ReadUint8(); e1 = (b & 0x0F); e2 = (b >> 4); } if(x & MDLNOTE_PARAM1) p1 = track.ReadUint8(); if(x & MDLNOTE_PARAM2) p2 = track.ReadUint8(); ImportMDLCommands(*m, vol, e1, e2, p1, p2); } row++; break; } } } } } if((loadFlags & loadPatternData) && (chunk = chunks.GetChunk(MDLChunk::idPatNames)).IsValid()) { PATTERNINDEX i = 0; while(i < Patterns.Size() && chunk.CanRead(16)) { char name[17]; chunk.ReadString(name, 16); Patterns[i].SetName(name); } } return true; } ///////////////////////////////////////////////////////////////////////// // MDL Sample Unpacking // MDL Huffman ReadBits compression uint8 MDLReadBits(uint32 &bitbuf, int32 &bitnum, const uint8 *(&ibuf), size_t &bytesLeft, int8 n) { if(bitnum < n) { if(bytesLeft) { bitbuf |= (((uint32)(*ibuf++)) << bitnum); bitnum += 8; bytesLeft--; } else { throw std::range_error("Truncated MDL sample block"); } } uint8 v = static_cast(bitbuf & ((1 << n) - 1)); bitbuf >>= n; bitnum -= n; return v; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Load_ptm.cpp0000644000372100037210000001726313161656666020371 00000000000000/* * Load_ptm.cpp * ------------ * Purpose: PTM (PolyTracker) module loader * Notes : (currently none) * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" OPENMPT_NAMESPACE_BEGIN struct PTMFileHeader { char songname[28]; // Name of song, asciiz string uint8le dosEOF; // 26 uint8le versionLo; // 03 version of file, currently 0203h uint8le versionHi; // 02 uint8le reserved1; // Reserved, set to 0 uint16le numOrders; // Number of orders (0..256) uint16le numSamples; // Number of instruments (1..255) uint16le numPatterns; // Number of patterns (1..128) uint16le numChannels; // Number of channels (voices) used (1..32) uint16le flags; // Set to 0 uint8le reserved2[2]; // Reserved, set to 0 char magic[4]; // Song identification, 'PTMF' uint8le reserved3[16]; // Reserved, set to 0 uint8le chnPan[32]; // Channel panning settings, 0..15, 0 = left, 7 = middle, 15 = right uint8le orders[256]; // Order list, valid entries 0..nOrders-1 uint16le patOffsets[128]; // Pattern offsets (*16) }; MPT_BINARY_STRUCT(PTMFileHeader, 608) struct PTMSampleHeader { enum SampleFlags { smpTypeMask = 0x03, smpPCM = 0x01, smpLoop = 0x04, smpPingPong = 0x08, smp16Bit = 0x10, }; uint8le flags; // Sample type (see SampleFlags) char filename[12]; // Name of external sample file uint8le volume; // Default volume uint16le c4speed; // C-4 speed (yep, not C-5) uint8le smpSegment[2]; // Sample segment (used internally) uint32le dataOffset; // Offset of sample data uint32le length; // Sample size (in bytes) uint32le loopStart; // Start of loop uint32le loopEnd; // End of loop uint8le gusdata[14]; char samplename[28]; // Name of sample, ASCIIZ char magic[4]; // Sample identification, 'PTMS' // Convert an PTM sample header to OpenMPT's internal sample header. SampleIO ConvertToMPT(ModSample &mptSmp) const { mptSmp.Initialize(MOD_TYPE_S3M); mptSmp.nVolume = std::min(volume, 64) * 4; mptSmp.nC5Speed = c4speed * 2; mpt::String::Read(mptSmp.filename, filename); SampleIO sampleIO( SampleIO::_8bit, SampleIO::mono, SampleIO::littleEndian, SampleIO::deltaPCM); if((flags & smpTypeMask) == smpPCM) { mptSmp.nLength = length; mptSmp.nLoopStart = loopStart; mptSmp.nLoopEnd = loopEnd; if(mptSmp.nLoopEnd > mptSmp.nLoopStart) mptSmp.nLoopEnd--; if(flags & smpLoop) mptSmp.uFlags.set(CHN_LOOP); if(flags & smpPingPong) mptSmp.uFlags.set(CHN_PINGPONGLOOP); if(flags & smp16Bit) { sampleIO |= SampleIO::_16bit; sampleIO |= SampleIO::PTM8Dto16; mptSmp.nLength /= 2; mptSmp.nLoopStart /= 2; mptSmp.nLoopEnd /= 2; } } return sampleIO; } }; MPT_BINARY_STRUCT(PTMSampleHeader, 80) static bool ValidateHeader(const PTMFileHeader &fileHeader) { if(std::memcmp(fileHeader.magic, "PTMF", 4) || fileHeader.dosEOF != 26 || fileHeader.versionHi > 2 || fileHeader.flags != 0 || !fileHeader.numChannels || fileHeader.numChannels > 32 || !fileHeader.numOrders || fileHeader.numOrders > 256 || !fileHeader.numSamples || fileHeader.numSamples > 255 || !fileHeader.numPatterns || fileHeader.numPatterns > 128 ) { return false; } return true; } static uint64 GetHeaderMinimumAdditionalSize(const PTMFileHeader &fileHeader) { return fileHeader.numSamples * sizeof(PTMSampleHeader); } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderPTM(MemoryFileReader file, const uint64 *pfilesize) { PTMFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return ProbeWantMoreData; } if(!ValidateHeader(fileHeader)) { return ProbeFailure; } return ProbeAdditionalSize(file, pfilesize, GetHeaderMinimumAdditionalSize(fileHeader)); } bool CSoundFile::ReadPTM(FileReader &file, ModLoadingFlags loadFlags) { file.Rewind(); PTMFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return false; } if(!ValidateHeader(fileHeader)) { return false; } if(!file.CanRead(mpt::saturate_cast(GetHeaderMinimumAdditionalSize(fileHeader)))) { return false; } if(loadFlags == onlyVerifyHeader) { return true; } InitializeGlobals(MOD_TYPE_PTM); mpt::String::Read(m_songName, fileHeader.songname); m_madeWithTracker = mpt::format(MPT_USTRING("PolyTracker %1.%2"))(fileHeader.versionHi.get(), mpt::ufmt::hex0<2>(fileHeader.versionLo.get())); m_SongFlags = SONG_ITCOMPATGXX | SONG_ITOLDEFFECTS; m_nChannels = fileHeader.numChannels; m_nSamples = std::min(fileHeader.numSamples, MAX_SAMPLES - 1); ReadOrderFromArray(Order(), fileHeader.orders, fileHeader.numOrders, 0xFF, 0xFE); // Reading channel panning for(CHANNELINDEX chn = 0; chn < m_nChannels; chn++) { ChnSettings[chn].Reset(); ChnSettings[chn].nPan = ((fileHeader.chnPan[chn] & 0x0F) << 4) + 4; } // Reading samples FileReader sampleHeaderChunk = file.ReadChunk(fileHeader.numSamples * sizeof(PTMSampleHeader)); for(SAMPLEINDEX smp = 0; smp < m_nSamples; smp++) { PTMSampleHeader sampleHeader; sampleHeaderChunk.ReadStruct(sampleHeader); ModSample &sample = Samples[smp + 1]; mpt::String::Read(m_szNames[smp + 1], sampleHeader.samplename); SampleIO sampleIO = sampleHeader.ConvertToMPT(sample); if((loadFlags & loadSampleData) && sample.nLength && file.Seek(sampleHeader.dataOffset)) { sampleIO.ReadSample(sample, file); } } // Reading Patterns if(!(loadFlags & loadPatternData)) { return true; } Patterns.ResizeArray(fileHeader.numPatterns); for(PATTERNINDEX pat = 0; pat < fileHeader.numPatterns; pat++) { if(!Patterns.Insert(pat, 64) || fileHeader.patOffsets[pat] == 0 || !file.Seek(fileHeader.patOffsets[pat] << 4)) { continue; } ModCommand *rowBase = Patterns[pat].GetpModCommand(0, 0); ROWINDEX row = 0; while(row < 64 && file.CanRead(1)) { uint8 b = file.ReadUint8(); if(b == 0) { row++; rowBase += m_nChannels; continue; } CHANNELINDEX chn = (b & 0x1F); ModCommand dummy = ModCommand(); ModCommand &m = chn < GetNumChannels() ? rowBase[chn] : dummy; if(b & 0x20) { m.note = file.ReadUint8(); m.instr = file.ReadUint8(); if(m.note == 254) m.note = NOTE_NOTECUT; else if(!m.note || m.note > 120) m.note = NOTE_NONE; } if(b & 0x40) { m.command = file.ReadUint8(); m.param = file.ReadUint8(); static const EffectCommand effTrans[] = { CMD_GLOBALVOLUME, CMD_RETRIG, CMD_FINEVIBRATO, CMD_NOTESLIDEUP, CMD_NOTESLIDEDOWN, CMD_NOTESLIDEUPRETRIG, CMD_NOTESLIDEDOWNRETRIG, CMD_REVERSEOFFSET }; if(m.command < 0x10) { // Beware: Effect letters are as in MOD, but portamento and volume slides behave like in S3M (i.e. fine slides share the same effect letters) ConvertModCommand(m); } else if(m.command < 0x10 + CountOf(effTrans)) { m.command = effTrans[m.command - 0x10]; } else { m.command = CMD_NONE; } switch(m.command) { case CMD_PANNING8: // My observations of this weird command... // 800...887 pan from hard left to hard right (whereas the low nibble seems to be ignored) // 888...8FF do the same (so 888...88F is hard left, and 890 is identical to 810) if(m.param >= 0x88) m.param &= 0x7F; else if(m.param > 0x80) m.param = 0x80; m.param &= 0x7F; m.param = (m.param * 0xFF) / 0x7F; break; case CMD_GLOBALVOLUME: m.param = std::min(m.param, uint8(0x40)) * 2u; break; } } if(b & 0x80) { m.volcmd = VOLCMD_VOLUME; m.vol = file.ReadUint8(); } } } return true; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Load_plm.cpp0000644000372100037210000002470113161656666020354 00000000000000/* * Load_plm.cpp * ------------ * Purpose: PLM (Disorder Tracker 2) module loader * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" OPENMPT_NAMESPACE_BEGIN struct PLMFileHeader { char magic[4]; // "PLM\x1A" uint8le headerSize; // Number of bytes in header, including magic bytes uint8le version; // version code of file format (0x10) char songName[48]; uint8le numChannels; uint8le flags; // unused? uint8le maxVol; // Maximum volume for vol slides, normally 0x40 uint8le amplify; // SoundBlaster amplify, 0x40 = no amplify uint8le tempo; uint8le speed; uint8le panPos[32]; // 0...15 uint8le numSamples; uint8le numPatterns; uint16le numOrders; }; MPT_BINARY_STRUCT(PLMFileHeader, 96) struct PLMSampleHeader { enum SampleFlags { smp16Bit = 1, smpPingPong = 2, }; char magic[4]; // "PLS\x1A" uint8le headerSize; // Number of bytes in header, including magic bytes uint8le version; char name[32]; char filename[12]; uint8le panning; // 0...15, 255 = no pan uint8le volume; // 0...64 uint8le flags; // See SampleFlags uint16le sampleRate; char unused[4]; uint32le loopStart; uint32le loopEnd; uint32le length; }; MPT_BINARY_STRUCT(PLMSampleHeader, 71) struct PLMPatternHeader { uint32le size; uint8le numRows; uint8le numChannels; uint8le color; char name[25]; }; MPT_BINARY_STRUCT(PLMPatternHeader, 32) struct PLMOrderItem { uint16le x; // Starting position of pattern uint8le y; // Number of first channel uint8le pattern; }; MPT_BINARY_STRUCT(PLMOrderItem, 4) static bool ValidateHeader(const PLMFileHeader &fileHeader) { if(std::memcmp(fileHeader.magic, "PLM\x1A", 4) || fileHeader.version != 0x10 || fileHeader.numChannels == 0 || fileHeader.numChannels > 32 || fileHeader.headerSize < sizeof(PLMFileHeader) ) { return false; } return true; } static uint64 GetHeaderMinimumAdditionalSize(const PLMFileHeader &fileHeader) { return fileHeader.headerSize - sizeof(PLMFileHeader) + 4 * (fileHeader.numOrders + fileHeader.numPatterns + fileHeader.numSamples); } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderPLM(MemoryFileReader file, const uint64 *pfilesize) { PLMFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return ProbeWantMoreData; } if(!ValidateHeader(fileHeader)) { return ProbeFailure; } return ProbeAdditionalSize(file, pfilesize, GetHeaderMinimumAdditionalSize(fileHeader)); } bool CSoundFile::ReadPLM(FileReader &file, ModLoadingFlags loadFlags) { file.Rewind(); PLMFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return false; } if(!ValidateHeader(fileHeader)) { return false; } if(!file.CanRead(mpt::saturate_cast(GetHeaderMinimumAdditionalSize(fileHeader)))) { return false; } if(loadFlags == onlyVerifyHeader) { return true; } if(!file.Seek(fileHeader.headerSize)) { return false; } InitializeGlobals(MOD_TYPE_PLM); InitializeChannels(); m_SongFlags = SONG_ITOLDEFFECTS; m_madeWithTracker = MPT_USTRING("Disorder Tracker 2"); // Some PLMs use ASCIIZ, some space-padding strings...weird. Oh, and the file browser stops at 0 bytes in the name, the main GUI doesn't. mpt::String::Read(m_songName, fileHeader.songName); m_nChannels = fileHeader.numChannels + 1; // Additional channel for writing pattern breaks m_nSamplePreAmp = fileHeader.amplify; m_nDefaultTempo.Set(fileHeader.tempo); m_nDefaultSpeed = fileHeader.speed; for(CHANNELINDEX chn = 0; chn < fileHeader.numChannels; chn++) { ChnSettings[chn].nPan = fileHeader.panPos[chn] * 0x11; } m_nSamples = fileHeader.numSamples; std::vector order(fileHeader.numOrders); file.ReadVector(order, fileHeader.numOrders); std::vector patternPos, samplePos; file.ReadVector(patternPos, fileHeader.numPatterns); file.ReadVector(samplePos, fileHeader.numSamples); for(SAMPLEINDEX smp = 0; smp < fileHeader.numSamples; smp++) { ModSample &sample = Samples[smp + 1]; sample.Initialize(); PLMSampleHeader sampleHeader; if(samplePos[smp] == 0 || !file.Seek(samplePos[smp]) || !file.ReadStruct(sampleHeader)) continue; mpt::String::Read(m_szNames[smp + 1], sampleHeader.name); mpt::String::Read(sample.filename, sampleHeader.filename); if(sampleHeader.panning <= 15) { sample.uFlags.set(CHN_PANNING); sample.nPan = sampleHeader.panning * 0x11; } sample.nGlobalVol = std::min(sampleHeader.volume, 64); sample.nC5Speed = sampleHeader.sampleRate; sample.nLoopStart = sampleHeader.loopStart; sample.nLoopEnd = sampleHeader.loopEnd; sample.nLength = sampleHeader.length; if(sampleHeader.flags & PLMSampleHeader::smp16Bit) { sample.nLoopStart /= 2; sample.nLoopEnd /= 2; sample.nLength /= 2; } if(sample.nLoopEnd > sample.nLoopStart) { sample.uFlags.set(CHN_LOOP); if(sampleHeader.flags & PLMSampleHeader::smpPingPong) sample.uFlags.set(CHN_PINGPONGLOOP); } sample.SanitizeLoops(); if(loadFlags & loadSampleData) { file.Seek(samplePos[smp] + sampleHeader.headerSize); SampleIO( (sampleHeader.flags & PLMSampleHeader::smp16Bit) ? SampleIO::_16bit : SampleIO::_8bit, SampleIO::mono, SampleIO::littleEndian, SampleIO::unsignedPCM) .ReadSample(sample, file); } } if(!(loadFlags & loadPatternData)) { return true; } // PLM is basically one huge continuous pattern, so we split it up into smaller patterns. const ROWINDEX rowsPerPat = 64; uint32 maxPos = 0; static const ModCommand::COMMAND effTrans[] = { CMD_NONE, CMD_PORTAMENTOUP, CMD_PORTAMENTODOWN, CMD_TONEPORTAMENTO, CMD_VOLUMESLIDE, CMD_TREMOLO, CMD_VIBRATO, CMD_S3MCMDEX, // Tremolo Waveform CMD_S3MCMDEX, // Vibrato Waveform CMD_TEMPO, CMD_SPEED, CMD_POSITIONJUMP, // Jump to order CMD_POSITIONJUMP, // Break to end of this order CMD_OFFSET, CMD_S3MCMDEX, // GUS Panning CMD_RETRIG, CMD_S3MCMDEX, // Note Delay CMD_S3MCMDEX, // Note Cut CMD_S3MCMDEX, // Pattern Delay CMD_FINEVIBRATO, CMD_VIBRATOVOL, CMD_TONEPORTAVOL, CMD_OFFSETPERCENTAGE, }; Order().clear(); for(const auto &ord : order) { if(ord.pattern >= fileHeader.numPatterns || ord.y > fileHeader.numChannels || !file.Seek(patternPos[ord.pattern])) continue; PLMPatternHeader patHeader; file.ReadStruct(patHeader); if(!patHeader.numRows) continue; STATIC_ASSERT(ORDERINDEX_MAX >= (MPT_MAX_UNSIGNED_VALUE(ord.x) + 255) / rowsPerPat); ORDERINDEX curOrd = static_cast(ord.x / rowsPerPat); ROWINDEX curRow = static_cast(ord.x % rowsPerPat); const CHANNELINDEX numChannels = std::min(patHeader.numChannels, fileHeader.numChannels - ord.y); const uint32 patternEnd = ord.x + patHeader.numRows; maxPos = std::max(maxPos, patternEnd); ModCommand::NOTE lastNote[32] = { 0 }; for(ROWINDEX r = 0; r < patHeader.numRows; r++, curRow++) { if(curRow >= rowsPerPat) { curRow = 0; curOrd++; } if(curOrd >= Order().size()) { Order().resize(curOrd + 1); Order()[curOrd] = Patterns.InsertAny(rowsPerPat); } PATTERNINDEX pat = Order()[curOrd]; if(!Patterns.IsValidPat(pat)) break; ModCommand *m = Patterns[pat].GetpModCommand(curRow, ord.y); for(CHANNELINDEX c = 0; c < numChannels; c++, m++) { uint8 data[5]; file.ReadArray(data); if(data[0]) lastNote[c] = m->note = (data[0] >> 4) * 12 + (data[0] & 0x0F) + 12 + NOTE_MIN; else m->note = NOTE_NONE; m->instr = data[1]; m->volcmd = VOLCMD_VOLUME; if(data[2] != 0xFF) m->vol = data[2]; else m->volcmd = VOLCMD_NONE; if(data[3] < CountOf(effTrans)) { m->command = effTrans[data[3]]; m->param = data[4]; // Fix some commands switch(data[3]) { case 0x07: // Tremolo waveform m->param = 0x40 | (m->param & 0x03); break; case 0x08: // Vibrato waveform m->param = 0x30 | (m->param & 0x03); break; case 0x0B: // Jump to order if(m->param < order.size()) { uint16 target = order[m->param].x; m->param = static_cast(target / rowsPerPat); ModCommand *mBreak = Patterns[pat].GetpModCommand(curRow, m_nChannels - 1); mBreak->command = CMD_PATTERNBREAK; mBreak->param = static_cast(target % rowsPerPat); } break; case 0x0C: // Jump to end of order { m->param = static_cast(patternEnd / rowsPerPat); ModCommand *mBreak = Patterns[pat].GetpModCommand(curRow, m_nChannels - 1); mBreak->command = CMD_PATTERNBREAK; mBreak->param = static_cast(patternEnd % rowsPerPat); } break; case 0x0E: // GUS Panning m->param = 0x80 | (m->param & 0x0F); break; case 0x10: // Delay Note m->param = 0xD0 | std::min(m->param, 0x0F); break; case 0x11: // Cut Note m->param = 0xC0 | std::min(m->param, 0x0F); break; case 0x12: // Pattern Delay m->param = 0xE0 | std::min(m->param, 0x0F); break; case 0x04: // Volume Slide case 0x14: // Vibrato + Volume Slide case 0x15: // Tone Portamento + Volume Slide // If both nibbles of a volume slide are set, act as fine volume slide up if((m->param & 0xF0) && (m->param & 0x0F) && (m->param & 0xF0) != 0xF0) { m->param |= 0x0F; } break; case 0x0D: case 0x16: // Offset without note if(m->note == NOTE_NONE) { m->note = lastNote[c]; } break; } } } if(patHeader.numChannels > numChannels) { file.Skip(5 * (patHeader.numChannels - numChannels)); } } } // Module ends with the last row of the last order item ROWINDEX endPatSize = maxPos % rowsPerPat; ORDERINDEX endOrder = static_cast(maxPos / rowsPerPat); if(endPatSize > 0 && Order().IsValidPat(endOrder)) { Patterns[Order()[endOrder]].Resize(endPatSize, false); } // If there are still any non-existent patterns in our order list, insert some blank patterns. PATTERNINDEX blankPat = PATTERNINDEX_INVALID; for(auto &pat : Order()) { if(pat == Order.GetInvalidPatIndex()) { if(blankPat == PATTERNINDEX_INVALID) { blankPat = Patterns.InsertAny(rowsPerPat); } pat = blankPat; } } return true; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/WindowedFIR.h0000644000372100037210000000460212345336772020405 00000000000000/* * WindowedFIR.h * ------------- * Purpose: FIR resampling code * Notes : (currently none) * Authors: OpenMPT Devs * ModPlug-XMMS Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "Mixer.h" OPENMPT_NAMESPACE_BEGIN /* ------------------------------------------------------------------------------------------------ fir interpolation doc, (derived from "an engineer's guide to fir digital filters", n.j. loy) calculate coefficients for ideal lowpass filter (with cutoff = fc in 0..1 (mapped to 0..nyquist)) c[-N..N] = (i==0) ? fc : sin(fc*pi*i)/(pi*i) then apply selected window to coefficients c[-N..N] *= w(0..N) with n in 2*N and w(n) being a window function (see loy) then calculate gain and scale filter coefs to have unity gain. ------------------------------------------------------------------------------------------------ */ #ifdef MPT_INTMIXER // quantizer scale of window coefs - only required for integer mixing #define WFIR_QUANTBITS 15 #define WFIR_QUANTSCALE float(1L< 2) { mptSmp.nLength = length; mptSmp.nLoopStart = loopStart; mptSmp.nLoopEnd = loopEnd; LimitMax(mptSmp.nLoopEnd, mptSmp.nLength); if(mptSmp.nLoopStart + 4 >= mptSmp.nLoopEnd) mptSmp.nLoopStart = mptSmp.nLoopEnd = 0; if(mptSmp.nLoopEnd) mptSmp.uFlags.set(CHN_LOOP); mptSmp.nFineTune = MOD2XMFineTune(finetune); mptSmp.nC5Speed = ModSample::TransposeToFrequency(0, mptSmp.nFineTune); if(attribute & 0x01) { mptSmp.uFlags.set(CHN_16BIT); mptSmp.nLength /= 2; mptSmp.nLoopStart /= 2; mptSmp.nLoopEnd /= 2; } } } }; MPT_BINARY_STRUCT(MTMSampleHeader, 37) static bool ValidateHeader(const MTMFileHeader &fileHeader) { if(std::memcmp(fileHeader.id, "MTM", 3) || fileHeader.version >= 0x20 || fileHeader.lastOrder > 127 || fileHeader.beatsPerTrack > 64 || fileHeader.numChannels > 32 || fileHeader.numChannels == 0 ) { return false; } return true; } static uint64 GetHeaderMinimumAdditionalSize(const MTMFileHeader &fileHeader) { return sizeof(MTMSampleHeader) * fileHeader.numSamples + 128 + 192 * fileHeader.numTracks + 64 * (fileHeader.lastPattern + 1) + fileHeader.commentSize; } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderMTM(MemoryFileReader file, const uint64 *pfilesize) { MTMFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return ProbeWantMoreData; } if(!ValidateHeader(fileHeader)) { return ProbeFailure; } return ProbeAdditionalSize(file, pfilesize, GetHeaderMinimumAdditionalSize(fileHeader)); } bool CSoundFile::ReadMTM(FileReader &file, ModLoadingFlags loadFlags) { file.Rewind(); MTMFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return false; } if(!ValidateHeader(fileHeader)) { return false; } if(!file.CanRead(mpt::saturate_cast(GetHeaderMinimumAdditionalSize(fileHeader)))) { return false; } if(loadFlags == onlyVerifyHeader) { return true; } InitializeGlobals(MOD_TYPE_MTM); mpt::String::Read(m_songName, fileHeader.songName); m_nSamples = fileHeader.numSamples; m_nChannels = fileHeader.numChannels; m_madeWithTracker = mpt::format(MPT_USTRING("MultiTracker %1.%2"))(fileHeader.version >> 4, fileHeader.version & 0x0F); // Reading instruments for(SAMPLEINDEX smp = 1; smp <= GetNumSamples(); smp++) { MTMSampleHeader sampleHeader; file.ReadStruct(sampleHeader); sampleHeader.ConvertToMPT(Samples[smp]); mpt::String::Read(m_szNames[smp], sampleHeader.samplename); } // Setting Channel Pan Position for(CHANNELINDEX chn = 0; chn < GetNumChannels(); chn++) { ChnSettings[chn].Reset(); ChnSettings[chn].nPan = ((fileHeader.panPos[chn] & 0x0F) << 4) + 8; } // Reading pattern order uint8 orders[128]; file.ReadArray(orders); ReadOrderFromArray(Order(), orders, fileHeader.lastOrder + 1, 0xFF, 0xFE); // Reading Patterns const ROWINDEX rowsPerPat = fileHeader.beatsPerTrack ? fileHeader.beatsPerTrack : 64; FileReader tracks = file.ReadChunk(192 * fileHeader.numTracks); if(loadFlags & loadPatternData) Patterns.ResizeArray(fileHeader.lastPattern + 1); for(PATTERNINDEX pat = 0; pat <= fileHeader.lastPattern; pat++) { if(!(loadFlags & loadPatternData) || !Patterns.Insert(pat, rowsPerPat)) { break; } for(CHANNELINDEX chn = 0; chn < 32; chn++) { uint16 track = file.ReadUint16LE(); if(track == 0 || track > fileHeader.numTracks || chn >= GetNumChannels()) { continue; } tracks.Seek(192 * (track - 1)); ModCommand *m = Patterns[pat].GetpModCommand(0, chn); for(ROWINDEX row = 0; row < rowsPerPat; row++, m += GetNumChannels()) { uint8 data[3]; tracks.ReadArray(data); if(data[0] & 0xFC) m->note = (data[0] >> 2) + 36 + NOTE_MIN; m->instr = ((data[0] & 0x03) << 4) | (data[1] >> 4); uint8 cmd = data[1] & 0x0F; uint8 param = data[2]; if(cmd == 0x0A) { if(param & 0xF0) param &= 0xF0; else param &= 0x0F; } else if(cmd == 0x08) { // No 8xx panning in MultiTracker, only E8x cmd = param = 0; } m->command = cmd; m->param = param; if(cmd != 0 || param != 0) { ConvertModCommand(*m); #ifdef MODPLUG_TRACKER m->Convert(MOD_TYPE_MTM, MOD_TYPE_S3M, *this); #endif } } } } if(fileHeader.commentSize != 0) { // Read message with a fixed line length of 40 characters // (actually the last character is always null, so make that 39 + 1 padding byte) m_songMessage.ReadFixedLineLength(file, fileHeader.commentSize, 39, 1); } // Reading Samples if(loadFlags & loadSampleData) { for(SAMPLEINDEX smp = 1; smp <= GetNumSamples(); smp++) { SampleIO( Samples[smp].uFlags[CHN_16BIT] ? SampleIO::_16bit : SampleIO::_8bit, SampleIO::mono, SampleIO::littleEndian, SampleIO::unsignedPCM) .ReadSample(Samples[smp], file); } } m_nMinPeriod = 64; m_nMaxPeriod = 32767; return true; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/pattern.h0000644000372100037210000001647613161656666017761 00000000000000/* * Pattern.h * --------- * Purpose: Module Pattern header class * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include #include "modcommand.h" #include "Snd_defs.h" OPENMPT_NAMESPACE_BEGIN class CPatternContainer; class CSoundFile; class EffectWriter; typedef ModCommand* PatternRow; class CPattern { friend class CPatternContainer; public: //BEGIN: OPERATORS CPattern& operator= (const CPattern &pat) { m_ModCommands = pat.m_ModCommands; m_Rows = pat.m_Rows; m_RowsPerBeat = pat.m_RowsPerBeat; m_RowsPerMeasure = pat.m_RowsPerMeasure; m_tempoSwing = pat.m_tempoSwing; m_PatternName = pat.m_PatternName; return *this; } bool operator== (const CPattern &other) const; bool operator!= (const CPattern &other) const { return !(*this == other); } //END: OPERATORS //BEGIN: INTERFACE METHODS public: ModCommand* GetpModCommand(const ROWINDEX r, const CHANNELINDEX c) { return &m_ModCommands[r * GetNumChannels() + c]; } const ModCommand* GetpModCommand(const ROWINDEX r, const CHANNELINDEX c) const { return &m_ModCommands[r * GetNumChannels() + c]; } ROWINDEX GetNumRows() const { return m_Rows; } ROWINDEX GetRowsPerBeat() const { return m_RowsPerBeat; } // pattern-specific rows per beat ROWINDEX GetRowsPerMeasure() const { return m_RowsPerMeasure; } // pattern-specific rows per measure bool GetOverrideSignature() const { return (m_RowsPerBeat + m_RowsPerMeasure > 0); } // override song time signature? // Returns true if pattern data can be accessed at given row, false otherwise. bool IsValidRow(const ROWINDEX row) const { return (row < GetNumRows()); } // Returns true if any pattern data is present. bool IsValid() const { return !m_ModCommands.empty(); } // Return PatternRow object which has operator[] defined so that ModCommand // at (iRow, iChn) can be accessed with GetRow(iRow)[iChn]. PatternRow GetRow(const ROWINDEX row) { return GetpModCommand(row, 0); } PatternRow GetRow(const ROWINDEX row) const { return const_cast(GetpModCommand(row, 0)); } CHANNELINDEX GetNumChannels() const; // Add or remove rows from the pattern. bool Resize(const ROWINDEX newRowCount, bool enforceFormatLimits = true, bool resizeAtEnd = true); // Check if there is any note data on a given row. bool IsEmptyRow(ROWINDEX row) const; // Allocate new pattern memory and replace old pattern data. bool AllocatePattern(ROWINDEX rows); // Deallocate pattern data. void Deallocate(); // Removes all modcommands from the pattern. void ClearCommands(); // Returns associated soundfile. CSoundFile& GetSoundFile(); const CSoundFile& GetSoundFile() const; const std::vector &GetData() const { return m_ModCommands; } void SetData(std::vector &&data) { MPT_ASSERT(data.size() == GetNumRows() * GetNumChannels()); m_ModCommands = std::move(data); } // Set pattern signature (rows per beat, rows per measure). Returns true on success. bool SetSignature(const ROWINDEX rowsPerBeat, const ROWINDEX rowsPerMeasure); void RemoveSignature() { m_RowsPerBeat = m_RowsPerMeasure = 0; } bool HasTempoSwing() const { return !m_tempoSwing.empty(); } const TempoSwing& GetTempoSwing() const { return m_tempoSwing; } void SetTempoSwing(const TempoSwing &swing) { m_tempoSwing = swing; m_tempoSwing.Normalize(); } void RemoveTempoSwing() { m_tempoSwing.clear(); } // Pattern name functions - bool functions return true on success. bool SetName(const std::string &newName); bool SetName(const char *newName, size_t maxChars); template bool SetName(const char (&buffer)[bufferSize]) { return SetName(buffer, bufferSize); } std::string GetName() const { return m_PatternName; }; #ifdef MODPLUG_TRACKER // Double number of rows bool Expand(); // Halve number of rows bool Shrink(); #endif // MODPLUG_TRACKER // Write some kind of effect data to the pattern bool WriteEffect(EffectWriter &settings); //END: INTERFACE METHODS typedef std::vector::iterator iterator; typedef std::vector::const_iterator const_iterator; iterator begin() { return m_ModCommands.begin(); } const_iterator begin() const { return m_ModCommands.begin(); } const_iterator cbegin() const { return m_ModCommands.cbegin(); } iterator end() { return m_ModCommands.end(); } const_iterator end() const { return m_ModCommands.end(); } const_iterator cend() const { return m_ModCommands.cend(); } CPattern(CPatternContainer& patCont) : m_ModCommands(0), m_Rows(64), m_RowsPerBeat(0), m_RowsPerMeasure(0), m_rPatternContainer(patCont) {}; CPattern(const CPattern &) = default; CPattern(CPattern &&) noexcept = default; protected: ModCommand& GetModCommand(size_t i) { return m_ModCommands[i]; } //Returns modcommand from (floor[i/channelCount], i%channelCount) ModCommand& GetModCommand(ROWINDEX r, CHANNELINDEX c) { return m_ModCommands[r * GetNumChannels() + c]; } const ModCommand& GetModCommand(ROWINDEX r, CHANNELINDEX c) const { return m_ModCommands[r * GetNumChannels() + c]; } //BEGIN: DATA protected: std::vector m_ModCommands; ROWINDEX m_Rows; ROWINDEX m_RowsPerBeat; // patterns-specific time signature. if != 0, this is implicitely set. ROWINDEX m_RowsPerMeasure; // ditto TempoSwing m_tempoSwing; std::string m_PatternName; CPatternContainer& m_rPatternContainer; //END: DATA }; const char FileIdPattern[] = "mptP"; void ReadModPattern(std::istream& iStrm, CPattern& patc, const size_t nSize = 0); void WriteModPattern(std::ostream& oStrm, const CPattern& patc); // Class for conveniently writing an effect to the pattern. class EffectWriter { friend class CPattern; // Row advance mode enum RetryMode { rmIgnore, // If effect can't be written, abort. rmTryNextRow, // If effect can't be written, try next row. rmTryPreviousRow, // If effect can't be written, try previous row. }; public: // Constructors with effect commands EffectWriter(EffectCommand cmd, ModCommand::PARAM param) : m_command(cmd), m_param(param), m_isVolEffect(false) { Init(); } EffectWriter(VolumeCommand cmd, ModCommand::VOL param) : m_volcmd(cmd), m_vol(param), m_isVolEffect(true) { Init(); } // Additional constructors: // Set row in which writing should start EffectWriter &Row(ROWINDEX row) { m_row = row; return *this; } // Set channel to which writing should be restricted to EffectWriter &Channel(CHANNELINDEX chn) { m_channel = chn; return *this; } // Allow multiple effects of the same kind to be written in the same row. EffectWriter &AllowMultiple() { m_allowMultiple = true; return *this; } // Set retry mode. EffectWriter &RetryNextRow() { m_retryMode = rmTryNextRow; return *this; } EffectWriter &RetryPreviousRow() { m_retryMode = rmTryPreviousRow; return *this; } protected: RetryMode m_retryMode; ROWINDEX m_row; CHANNELINDEX m_channel; union { EffectCommand m_command; VolumeCommand m_volcmd; }; union { ModCommand::PARAM m_param; ModCommand::VOL m_vol; }; bool m_retry : 1; bool m_allowMultiple : 1; bool m_isVolEffect : 1; // Common data initialisation void Init() { m_row = 0; m_channel = CHANNELINDEX_INVALID; // Any channel m_retryMode = rmIgnore; // If effect couldn't be written, abort. m_retry = true; m_allowMultiple = false; // Stop if same type of effect is encountered } }; OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Load_psm.cpp0000644000372100037210000011646013161656666020367 00000000000000/* * Load_psm.cpp * ------------ * Purpose: PSM16 and new PSM (ProTracker Studio / Epic MegaGames MASI) module loader * Notes : This is partly based on http://www.shikadi.net/moddingwiki/ProTracker_Studio_Module * and partly reverse-engineered. Also thanks to the author of foo_dumb, the source code gave me a few clues. :) * Authors: Johannes Schultz * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" #include "ChunkReader.h" #ifdef LIBOPENMPT_BUILD #define MPT_PSM_USE_REAL_SUBSONGS #endif OPENMPT_NAMESPACE_BEGIN //////////////////////////////////////////////////////////// // // New PSM support starts here. PSM16 structs are below. // // PSM File Header struct PSMFileHeader { char formatID[4]; // "PSM " (new format) uint32le fileSize; // Filesize - 12 char fileInfoID[4]; // "FILE" }; MPT_BINARY_STRUCT(PSMFileHeader, 12) // RIFF-style Chunk struct PSMChunk { // 32-Bit chunk identifiers enum ChunkIdentifiers { idTITL = MAGIC4LE('T','I','T','L'), idSDFT = MAGIC4LE('S','D','F','T'), idPBOD = MAGIC4LE('P','B','O','D'), idSONG = MAGIC4LE('S','O','N','G'), idDATE = MAGIC4LE('D','A','T','E'), idOPLH = MAGIC4LE('O','P','L','H'), idPPAN = MAGIC4LE('P','P','A','N'), idPATT = MAGIC4LE('P','A','T','T'), idDSAM = MAGIC4LE('D','S','A','M'), idDSMP = MAGIC4LE('D','S','M','P'), }; uint32le id; uint32le length; size_t GetLength() const { return length; } ChunkIdentifiers GetID() const { return static_cast(id.get()); } }; MPT_BINARY_STRUCT(PSMChunk, 8) // Song Information struct PSMSongHeader { char songType[9]; // Mostly "MAINSONG " (But not in Extreme Pinball!) uint8 compression; // 1 - uncompressed uint8 numChannels; // Number of channels }; MPT_BINARY_STRUCT(PSMSongHeader, 11) // Regular sample header struct PSMSampleHeader { uint8le flags; char fileName[8]; // Filename of the original module (without extension) char sampleID[4]; // INS0...INS9 (only last digit of sample ID, i.e. sample 1 and sample 11 are equal) char sampleName[33]; uint8le unknown1[6]; // 00 00 00 00 00 FF uint16le sampleNumber; uint32le sampleLength; uint32le loopStart; uint32le loopEnd; // FF FF FF FF = end of sample uint8le unknown3; uint8le finetune; // unused? always 0 uint8le defaultVolume; uint32le unknown4; uint32le c5Freq; // MASI ignores the high 16 bits char padding[19]; // 00 ... 00 // Convert header data to OpenMPT's internal format void ConvertToMPT(ModSample &mptSmp) const { mptSmp.Initialize(); mpt::String::Read(mptSmp.filename, fileName); mptSmp.nC5Speed = c5Freq; mptSmp.nLength = sampleLength; mptSmp.nLoopStart = loopStart; // It is not entirely clear if/when we should add +1 to the loopEnd value. // Sample 8 in the medieval table music of Extreme Pinball and CONVERT.EXE v1.36 suggest that we should do so. // But for other tunes it's not correct, e.g. the OMF 2097 music! mptSmp.nLoopEnd = loopEnd; mptSmp.nVolume = (defaultVolume + 1) * 2; mptSmp.uFlags.set(CHN_LOOP, (flags & 0x80) != 0); LimitMax(mptSmp.nLoopEnd, mptSmp.nLength); LimitMax(mptSmp.nLoopStart, mptSmp.nLoopEnd); } }; MPT_BINARY_STRUCT(PSMSampleHeader, 96) // Sinaria sample header (and possibly other games) struct PSMSinariaSampleHeader { uint8le flags; char fileName[8]; // Filename of the original module (without extension) char sampleID[8]; // INS0...INS99999 char sampleName[33]; uint8le unknown1[6]; // 00 00 00 00 00 FF uint16le sampleNumber; uint32le sampleLength; uint32le loopStart; uint32le loopEnd; uint16le unknown3; uint8le finetune; // Possibly finetune like in PSM16, but sounds even worse than just ignoring it uint8le defaultVolume; uint32le unknown4; uint16le c5Freq; char padding[16]; // 00 ... 00 // Convert header data to OpenMPT's internal format void ConvertToMPT(ModSample &mptSmp) const { mptSmp.Initialize(); mpt::String::Read(mptSmp.filename, fileName); mptSmp.nC5Speed = c5Freq; mptSmp.nLength = sampleLength; mptSmp.nLoopStart = loopStart; mptSmp.nLoopEnd = loopEnd; mptSmp.nVolume = (defaultVolume + 1) * 2; mptSmp.uFlags.set(CHN_LOOP, (flags & 0x80) != 0); LimitMax(mptSmp.nLoopEnd, mptSmp.nLength); LimitMax(mptSmp.nLoopStart, mptSmp.nLoopEnd); } }; MPT_BINARY_STRUCT(PSMSinariaSampleHeader, 96) struct PSMSubSong // For internal use (pattern conversion) { std::vector channelPanning, channelVolume; std::vector channelSurround; uint8 defaultTempo, defaultSpeed; char songName[10]; ORDERINDEX startOrder, endOrder, restartPos; PSMSubSong() { channelPanning.assign(MAX_BASECHANNELS, 128); channelVolume.assign(MAX_BASECHANNELS, 64); channelSurround.assign(MAX_BASECHANNELS, false); MemsetZero(songName); defaultTempo = 125; defaultSpeed = 6; startOrder = endOrder = ORDERINDEX_INVALID; restartPos = 0; } }; // Portamento effect conversion (depending on format version) static uint8 ConvertPSMPorta(uint8 param, bool sinariaFormat) { if(sinariaFormat) return param; if(param < 4) return (param | 0xF0); else return (param >> 2); } // Read a Pattern ID (something like "P0 " or "P13 " in the old format, or "PATT0 " in Sinaria) static PATTERNINDEX ReadPSMPatternIndex(FileReader &file, bool &sinariaFormat) { char patternID[5]; uint8 offset = 1; file.ReadString(patternID, 4); if(!memcmp(patternID, "PATT", 4)) { file.ReadString(patternID, 4); sinariaFormat = true; offset = 0; } return ConvertStrTo(&patternID[offset]); } static bool ValidateHeader(const PSMFileHeader &fileHeader) { if(std::memcmp(fileHeader.formatID, "PSM ", 4) || std::memcmp(fileHeader.fileInfoID, "FILE", 4)) { return false; } return true; } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderPSM(MemoryFileReader file, const uint64 *pfilesize) { PSMFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return ProbeWantMoreData; } if(!ValidateHeader(fileHeader)) { return ProbeFailure; } PSMChunk chunkHeader; if(!file.ReadStruct(chunkHeader)) { return ProbeWantMoreData; } if(chunkHeader.length == 0) { return ProbeFailure; } if((chunkHeader.id & 0x7f7f7f7fu) != chunkHeader.id) // ASCII? { return ProbeFailure; } MPT_UNREFERENCED_PARAMETER(pfilesize); return ProbeSuccess; } bool CSoundFile::ReadPSM(FileReader &file, ModLoadingFlags loadFlags) { file.Rewind(); PSMFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return false; } #ifdef MPT_PSM_DECRYPT // CONVERT.EXE /K - I don't think any game ever used this. std::vector decrypted; if(!memcmp(fileHeader.formatID, "QUP$", 4) && !memcmp(fileHeader.fileInfoID, "OSWQ", 4)) { if(loadFlags == onlyVerifyHeader) return true; file.Rewind(); decrypted.resize(file.GetLength()); file.ReadRaw(decrypted.data(), decrypted.size()); uint8 i = 0; for(auto &c : decrypted) { c -= ++i; } file = FileReader(mpt::as_span(decrypted)); file.ReadStruct(fileHeader); } #endif // MPT_PSM_DECRYPT // Check header if(!ValidateHeader(fileHeader)) { return false; } ChunkReader chunkFile(file); ChunkReader::ChunkList chunks; if(loadFlags == onlyVerifyHeader) chunks = chunkFile.ReadChunksUntil(1, PSMChunk::idSDFT); else chunks = chunkFile.ReadChunks(1); // "SDFT" - Format info (song data starts here) if(!chunks.GetChunk(PSMChunk::idSDFT).ReadMagic("MAINSONG")) return false; else if(loadFlags == onlyVerifyHeader) return true; // Yep, this seems to be a valid file. InitializeGlobals(MOD_TYPE_PSM); m_SongFlags = SONG_ITOLDEFFECTS | SONG_ITCOMPATGXX; // "TITL" - Song Title FileReader titleChunk = chunks.GetChunk(PSMChunk::idTITL); titleChunk.ReadString(m_songName, titleChunk.GetLength()); Order().clear(); // Subsong setup std::vector subsongs; bool subsongPanningDiffers = false; // Do we have subsongs with different panning positions? bool sinariaFormat = false; // The game "Sinaria" uses a slightly modified PSM structure - in some ways it's more like PSM16 (e.g. effects). // "SONG" - Subsong information (channel count etc) auto songChunks = chunks.GetAllChunks(PSMChunk::idSONG); for(ChunkReader chunk : songChunks) { PSMSongHeader songHeader; if(!chunk.ReadStruct(songHeader) || songHeader.compression != 0x01) // No compression for PSM files { return false; } // Subsongs *might* have different channel count m_nChannels = Clamp(static_cast(songHeader.numChannels), m_nChannels, MAX_BASECHANNELS); PSMSubSong subsong; mpt::String::Read(subsong.songName, songHeader.songType); #ifdef MPT_PSM_USE_REAL_SUBSONGS if(!Order().empty()) { // Add a new sequence for this subsong if(Order.AddSequence(false) == SEQUENCEINDEX_INVALID) break; } Order().SetName(subsong.songName); #endif // MPT_PSM_USE_REAL_SUBSONGS // Read "Sub chunks" auto subChunks = chunk.ReadChunks(1); for(const auto &subChunkIter : subChunks) { FileReader subChunk(subChunkIter.GetData()); PSMChunk subChunkHead = subChunkIter.GetHeader(); switch(subChunkHead.GetID()) { #if 0 case PSMChunk::idDATE: // "DATE" - Conversion date (YYMMDD) if(subChunkHead.GetLength() == 6) { char cversion[7]; subChunk.ReadString(cversion, 6); uint32 version = ConvertStrTo(cversion); // Sinaria song dates (just to go sure...) if(version == 800211 || version == 940902 || version == 940903 || version == 940906 || version == 940914 || version == 941213) sinariaFormat = true; } break; #endif case PSMChunk::idOPLH: // "OPLH" - Order list, channel + module settings if(subChunkHead.GetLength() >= 9) { // First two bytes = Number of chunks that follow //uint16 totalChunks = subChunk.ReadUint16LE(); subChunk.Skip(2); // Now, the interesting part begins! uint16 chunkCount = 0, firstOrderChunk = uint16_max; // "Sub sub chunks" (grrrr, silly format) while(subChunk.CanRead(1)) { uint8 opcode = subChunk.ReadUint8(); if(!opcode) { // Last chunk was reached. break; } // Note: This is more like a playlist than a collection of global values. // In theory, a tempo item inbetween two order items should modify the // tempo when switching patterns. No module uses this feature in practice // though, so we can keep our loader simple. // Unimplemented opcodes do nothing or freeze MASI. switch(opcode) { case 0x01: // Play order list item { if(subsong.startOrder == ORDERINDEX_INVALID) subsong.startOrder = Order().GetLength(); subsong.endOrder = Order().GetLength(); PATTERNINDEX pat = ReadPSMPatternIndex(subChunk, sinariaFormat); if(pat == 0xFF) pat = Order.GetInvalidPatIndex(); else if(pat == 0xFE) pat = Order.GetIgnoreIndex(); Order().push_back(pat); // Decide whether this is the first order chunk or not (for finding out the correct restart position) if(firstOrderChunk == uint16_max) firstOrderChunk = chunkCount; } break; // 0x02: Play Range // 0x03: Jump Loop case 0x04: // Jump Line (Restart position) { uint16 restartChunk = subChunk.ReadUint16LE(); if(restartChunk >= firstOrderChunk) subsong.restartPos = static_cast(restartChunk - firstOrderChunk); // Close enough - we assume that order list is continuous (like in any real-world PSM) Order().SetRestartPos(subsong.restartPos); } break; // 0x05: Channel Flip // 0x06: Transpose case 0x07: // Default Speed subsong.defaultSpeed = subChunk.ReadUint8(); break; case 0x08: // Default Tempo subsong.defaultTempo = subChunk.ReadUint8(); break; case 0x0C: // Sample map table // Never seems to be different, so... // This is probably a part of the never-implemented "mini programming language" mentioned in the PSM docs. // Output of PLAY.EXE: "SMapTabl from pos 0 to pos -1 starting at 0 and adding 1 to it each time" // It appears that this maps e.g. what is "I0" in the file to sample 1. // If we were being fancy, we could implement this, but in practice it won't matter. if (subChunk.ReadUint8() != 0x00 || subChunk.ReadUint8() != 0xFF || // "0 to -1" (does not seem to do anything) subChunk.ReadUint8() != 0x00 || subChunk.ReadUint8() != 0x00 || // "at 0" (actually this appears to be the adding part - changing this to 0x01 0x00 offsets all samples by 1) subChunk.ReadUint8() != 0x01 || subChunk.ReadUint8() != 0x00) // "adding 1" (does not seem to do anything) { return false; } break; case 0x0D: // Channel panning table - can be set using CONVERT.EXE /E { uint8 chn = subChunk.ReadUint8(); uint8 pan = subChunk.ReadUint8(); uint8 type = subChunk.ReadUint8(); if(chn < subsong.channelPanning.size()) { switch(type) { case 0: // use panning subsong.channelPanning[chn] = pan ^ 128; subsong.channelSurround[chn] = false; break; case 2: // surround subsong.channelPanning[chn] = 128; subsong.channelSurround[chn] = true; break; case 4: // center subsong.channelPanning[chn] = 128; subsong.channelSurround[chn] = false; break; } if(subsongPanningDiffers == false && subsongs.size() > 0) { if(subsongs.back().channelPanning[chn] != subsong.channelPanning[chn] || subsongs.back().channelSurround[chn] != subsong.channelSurround[chn]) subsongPanningDiffers = true; } } } break; case 0x0E: // Channel volume table (0...255) - can be set using CONVERT.EXE /E, is 255 in all "official" PSMs except for some OMF 2097 tracks { uint8 chn = subChunk.ReadUint8(); uint8 vol = subChunk.ReadUint8(); if(chn < subsong.channelVolume.size()) { subsong.channelVolume[chn] = (vol / 4u) + 1; } } break; default: // Should never happen in "real" PSM files. But in this case, we have to quit as we don't know how big the chunk really is. return false; } chunkCount++; } } break; case PSMChunk::idPPAN: // PPAN - Channel panning table (used in Sinaria) // In some Sinaria tunes, this is actually longer than 2 * channels... MPT_ASSERT(subChunkHead.GetLength() >= m_nChannels * 2u); for(CHANNELINDEX chn = 0; chn < m_nChannels; chn++) { if(!subChunk.CanRead(2)) break; uint8 type = subChunk.ReadUint8(); uint8 pan = subChunk.ReadUint8(); switch(type) { case 0: // use panning subsong.channelPanning[chn] = pan ^ 128; subsong.channelSurround[chn] = false; break; case 2: // surround subsong.channelPanning[chn] = 128; subsong.channelSurround[chn] = true; break; case 4: // center subsong.channelPanning[chn] = 128; subsong.channelSurround[chn] = false; break; default: break; } } break; case PSMChunk::idPATT: // PATT - Pattern list // We don't really need this. break; case PSMChunk::idDSAM: // DSAM - Sample list // We don't need this either. break; default: break; } } // Attach this subsong to the subsong list - finally, all "sub sub sub ..." chunks are parsed. if(subsong.startOrder != ORDERINDEX_INVALID && subsong.endOrder != ORDERINDEX_INVALID) { // Separate subsongs by "---" patterns Order().push_back(); subsongs.push_back(subsong); } } #ifdef MPT_PSM_USE_REAL_SUBSONGS Order.SetSequence(0); #endif // MPT_PSM_USE_REAL_SUBSONGS if(subsongs.empty()) return false; // DSMP - Samples if(loadFlags & loadSampleData) { auto sampleChunks = chunks.GetAllChunks(PSMChunk::idDSMP); for(auto &chunk : sampleChunks) { SAMPLEINDEX smp; if(!sinariaFormat) { // Original header PSMSampleHeader sampleHeader; if(!chunk.ReadStruct(sampleHeader)) { continue; } smp = static_cast(sampleHeader.sampleNumber + 1); if(smp > 0 && smp < MAX_SAMPLES) { m_nSamples = std::max(m_nSamples, smp); mpt::String::Read(m_szNames[smp], sampleHeader.sampleName); sampleHeader.ConvertToMPT(Samples[smp]); } } else { // Sinaria uses a slightly different sample header PSMSinariaSampleHeader sampleHeader; if(!chunk.ReadStruct(sampleHeader)) { continue; } smp = static_cast(sampleHeader.sampleNumber + 1); if(smp > 0 && smp < MAX_SAMPLES) { m_nSamples = std::max(m_nSamples, smp); mpt::String::Read(m_szNames[smp], sampleHeader.sampleName); sampleHeader.ConvertToMPT(Samples[smp]); } } if(smp > 0 && smp < MAX_SAMPLES) { SampleIO( SampleIO::_8bit, SampleIO::mono, SampleIO::littleEndian, SampleIO::deltaPCM).ReadSample(Samples[smp], chunk); } } } // Make the default variables of the first subsong global m_nDefaultSpeed = subsongs[0].defaultSpeed; m_nDefaultTempo.Set(subsongs[0].defaultTempo); Order().SetRestartPos(subsongs[0].restartPos); for(CHANNELINDEX chn = 0; chn < m_nChannels; chn++) { ChnSettings[chn].Reset(); ChnSettings[chn].nVolume = subsongs[0].channelVolume[chn]; ChnSettings[chn].nPan = subsongs[0].channelPanning[chn]; ChnSettings[chn].dwFlags.set(CHN_SURROUND, subsongs[0].channelSurround[chn]); } m_madeWithTracker = sinariaFormat ? MPT_USTRING("Epic MegaGames MASI (New Version / Sinaria)") : MPT_USTRING("Epic MegaGames MASI (New Version)"); if(!(loadFlags & loadPatternData) || m_nChannels == 0) { return true; } // "PBOD" - Pattern data of a single pattern // Now that we know the number of channels, we can go through all the patterns. auto pattChunks = chunks.GetAllChunks(PSMChunk::idPBOD); Patterns.ResizeArray(static_cast(pattChunks.size())); for(auto &chunk : pattChunks) { if(chunk.GetLength() != chunk.ReadUint32LE() // Same value twice || !chunk.LengthIsAtLeast(8)) { continue; } PATTERNINDEX pat = ReadPSMPatternIndex(chunk, sinariaFormat); uint16 numRows = chunk.ReadUint16LE(); if(!Patterns.Insert(pat, numRows)) { continue; } enum { noteFlag = 0x80, instrFlag = 0x40, volFlag = 0x20, effectFlag = 0x10, }; // Read pattern. for(ROWINDEX row = 0; row < numRows; row++) { PatternRow rowBase = Patterns[pat].GetRow(row); uint16 rowSize = chunk.ReadUint16LE(); if(rowSize <= 2) { continue; } FileReader rowChunk = chunk.ReadChunk(rowSize - 2); while(rowChunk.CanRead(3)) { uint8 flags = rowChunk.ReadUint8(); uint8 channel = rowChunk.ReadUint8(); // Point to the correct channel ModCommand &m = rowBase[std::min(m_nChannels - 1, channel)]; if(flags & noteFlag) { // Note present uint8 note = rowChunk.ReadUint8(); if(!sinariaFormat) { if(note == 0xFF) // Can be found in a few files but is apparently not supported by MASI note = NOTE_NOTECUT; else if(note < 129) note = (note & 0x0F) + 12 * (note >> 4) + 13; } else { if(note < 85) note += 36; } m.note = note; } if(flags & instrFlag) { // Instrument present m.instr = rowChunk.ReadUint8() + 1; } if(flags & volFlag) { // Volume present uint8 vol = rowChunk.ReadUint8(); m.volcmd = VOLCMD_VOLUME; m.vol = (MIN(vol, 127) + 1) / 2; } if(flags & effectFlag) { // Effect present - convert m.command = rowChunk.ReadUint8(); m.param = rowChunk.ReadUint8(); // This list is annoyingly similar to PSM16, but not quite identical. switch(m.command) { // Volslides case 0x01: // fine volslide up m.command = CMD_VOLUMESLIDE; if (sinariaFormat) m.param = (m.param << 4) | 0x0F; else m.param = ((m.param & 0x1E) << 3) | 0x0F; break; case 0x02: // volslide up m.command = CMD_VOLUMESLIDE; if (sinariaFormat) m.param = 0xF0 & (m.param << 4); else m.param = 0xF0 & (m.param << 3); break; case 0x03: // fine volslide down m.command = CMD_VOLUMESLIDE; if (sinariaFormat) m.param |= 0xF0; else m.param = 0xF0 | (m.param >> 1); break; case 0x04: // volslide down m.command = CMD_VOLUMESLIDE; if (sinariaFormat) m.param &= 0x0F; else if(m.param < 2) m.param |= 0xF0; else m.param = (m.param >> 1) & 0x0F; break; // Portamento case 0x0B: // fine portamento up m.command = CMD_PORTAMENTOUP; m.param = 0xF0 | ConvertPSMPorta(m.param, sinariaFormat); break; case 0x0C: // portamento up m.command = CMD_PORTAMENTOUP; m.param = ConvertPSMPorta(m.param, sinariaFormat); break; case 0x0D: // fine portamento down m.command = CMD_PORTAMENTODOWN; m.param = 0xF0 | ConvertPSMPorta(m.param, sinariaFormat); break; case 0x0E: // portamento down m.command = CMD_PORTAMENTODOWN; m.param = ConvertPSMPorta(m.param, sinariaFormat); break; case 0x0F: // tone portamento m.command = CMD_TONEPORTAMENTO; if(!sinariaFormat) m.param >>= 2; break; case 0x11: // glissando control m.command = CMD_S3MCMDEX; m.param = 0x10 | (m.param & 0x01); break; case 0x10: // tone portamento + volslide up m.command = CMD_TONEPORTAVOL; m.param = m.param & 0xF0; break; case 0x12: // tone portamento + volslide down m.command = CMD_TONEPORTAVOL; m.param = (m.param >> 4) & 0x0F; break; case 0x13: // ScreamTracker command S - actually hangs / crashes MASI m.command = CMD_S3MCMDEX; break; // Vibrato case 0x15: // vibrato m.command = CMD_VIBRATO; break; case 0x16: // vibrato waveform m.command = CMD_S3MCMDEX; m.param = 0x30 | (m.param & 0x0F); break; case 0x17: // vibrato + volslide up m.command = CMD_VIBRATOVOL; m.param = 0xF0 | m.param; break; case 0x18: // vibrato + volslide down m.command = CMD_VIBRATOVOL; break; // Tremolo case 0x1F: // tremolo m.command = CMD_TREMOLO; break; case 0x20: // tremolo waveform m.command = CMD_S3MCMDEX; m.param = 0x40 | (m.param & 0x0F); break; // Sample commands case 0x29: // 3-byte offset - we only support the middle byte. m.command = CMD_OFFSET; m.param = rowChunk.ReadUint8(); rowChunk.Skip(1); break; case 0x2A: // retrigger m.command = CMD_RETRIG; break; case 0x2B: // note cut m.command = CMD_S3MCMDEX; m.param = 0xC0 | (m.param & 0x0F); break; case 0x2C: // note delay m.command = CMD_S3MCMDEX; m.param = 0xD0 | (m.param & 0x0F); break; // Position change case 0x33: // position jump - MASI seems to ignore this command, and CONVERT.EXE never writes it m.command = CMD_POSITIONJUMP; m.param /= 2u; // actually it is probably just an index into the order table rowChunk.Skip(1); break; case 0x34: // pattern break m.command = CMD_PATTERNBREAK; // When converting from S3M, the parameter is double-BDC-encoded (wtf!) // When converting from MOD, it's in binary. // MASI ignores the parameter entirely, and so do we. m.param = 0; break; case 0x35: // loop pattern m.command = CMD_S3MCMDEX; m.param = 0xB0 | (m.param & 0x0F); break; case 0x36: // pattern delay m.command = CMD_S3MCMDEX; m.param = 0xE0 | (m.param & 0x0F); break; // speed change case 0x3D: // set speed m.command = CMD_SPEED; break; case 0x3E: // set tempo m.command = CMD_TEMPO; break; // misc commands case 0x47: // arpeggio m.command = CMD_ARPEGGIO; break; case 0x48: // set finetune m.command = CMD_S3MCMDEX; m.param = 0x20 | (m.param & 0x0F); break; case 0x49: // set balance m.command = CMD_S3MCMDEX; m.param = 0x80 | (m.param & 0x0F); break; default: m.command = CMD_NONE; break; } } } } } if(subsongs.size() > 1) { // Write subsong "configuration" to patterns (only if there are multiple subsongs) for(size_t i = 0; i < subsongs.size(); i++) { #ifdef MPT_PSM_USE_REAL_SUBSONGS ModSequence &order = Order(static_cast(i)); #else ModSequence &order = Order(); #endif // MPT_PSM_USE_REAL_SUBSONGS const PSMSubSong &subsong = subsongs[i]; PATTERNINDEX startPattern = order[subsong.startOrder]; if(Patterns.IsValidPat(startPattern)) { startPattern = order.EnsureUnique(subsong.startOrder); // Subsongs with different panning setup -> write to pattern (MUSIC_C.PSM) // Don't write channel volume for now, as there is no real-world module which needs it. if(subsongPanningDiffers) { for(CHANNELINDEX chn = 0; chn < m_nChannels; chn++) { if(subsong.channelSurround[chn]) Patterns[startPattern].WriteEffect(EffectWriter(CMD_S3MCMDEX, 0x91).Row(0).Channel(chn).RetryNextRow()); else Patterns[startPattern].WriteEffect(EffectWriter(CMD_PANNING8, subsong.channelPanning[chn]).Row(0).Channel(chn).RetryNextRow()); } } // Write default tempo/speed to pattern Patterns[startPattern].WriteEffect(EffectWriter(CMD_SPEED, subsong.defaultSpeed).Row(0).RetryNextRow()); Patterns[startPattern].WriteEffect(EffectWriter(CMD_TEMPO, subsong.defaultTempo).Row(0).RetryNextRow()); } #ifndef MPT_PSM_USE_REAL_SUBSONGS // Add restart position to the last pattern PATTERNINDEX endPattern = order[subsong.endOrder]; if(Patterns.IsValidPat(endPattern)) { endPattern = order.EnsureUnique(subsong.endOrder); ROWINDEX lastRow = Patterns[endPattern].GetNumRows() - 1; auto m = Patterns[endPattern].cbegin(); for(uint32 cell = 0; cell < m_nChannels * Patterns[endPattern].GetNumRows(); cell++, m++) { if(m->command == CMD_PATTERNBREAK || m->command == CMD_POSITIONJUMP) { lastRow = cell / m_nChannels; break; } } Patterns[endPattern].WriteEffect(EffectWriter(CMD_POSITIONJUMP, mpt::saturate_cast(subsong.startOrder + subsong.restartPos)).Row(lastRow).RetryPreviousRow()); } // Set the subsong name to all pattern names for(ORDERINDEX ord = subsong.startOrder; ord <= subsong.endOrder; ord++) { if(Patterns.IsValidIndex(order[ord])) Patterns[order[ord]].SetName(subsong.songName); } #endif // MPT_PSM_USE_REAL_SUBSONGS } } return true; } //////////////////////////////// // // PSM16 support starts here. // struct PSM16FileHeader { char formatID[4]; // "PSM\xFE" (PSM16) char songName[59]; // Song title, padded with nulls uint8le lineEnd; // $1A uint8le songType; // Song Type bitfield uint8le formatVersion; // $10 uint8le patternVersion; // 0 or 1 uint8le songSpeed; // 1 ... 255 uint8le songTempo; // 32 ... 255 uint8le masterVolume; // 0 ... 255 uint16le songLength; // 0 ... 255 (number of patterns to play in the song) uint16le songOrders; // 0 ... 255 (same as previous value as no subsongs are present) uint16le numPatterns; // 1 ... 255 uint16le numSamples; // 1 ... 255 uint16le numChannelsPlay; // 0 ... 32 (max. number of channels to play) uint16le numChannelsReal; // 0 ... 32 (max. number of channels to process) uint32le orderOffset; // Pointer to order list uint32le panOffset; // Pointer to pan table uint32le patOffset; // Pointer to pattern data uint32le smpOffset; // Pointer to sample headers uint32le commentsOffset; // Pointer to song comment uint32le patSize; // Size of all patterns char filler[40]; }; MPT_BINARY_STRUCT(PSM16FileHeader, 146) struct PSM16SampleHeader { enum SampleFlags { smpMask = 0x7F, smp16Bit = 0x04, smpUnsigned = 0x08, smpDelta = 0x10, smpPingPong = 0x20, smpLoop = 0x80, }; char filename[13]; // null-terminated char name[24]; // ditto uint32le offset; // in file uint32le memoffset; // not used uint16le sampleNumber; // 1 ... 255 uint8le flags; // sample flag bitfield uint32le length; // in bytes uint32le loopStart; // in samples? uint32le loopEnd; // in samples? uint8le finetune; // Low nibble = MOD finetune, high nibble = transpose (7 = center) uint8le volume; // default volume uint16le c2freq; // Middle-C frequency, which has to be combined with the finetune and transpose. // Convert sample header to OpenMPT's internal format void ConvertToMPT(ModSample &mptSmp) const { mptSmp.Initialize(); mpt::String::Read(mptSmp.filename, filename); mptSmp.nLength = length; mptSmp.nLoopStart = loopStart; mptSmp.nLoopEnd = loopEnd; // It seems like that finetune and transpose are added to the already given c2freq... That's a double WTF! // Why on earth would you want to use both systems at the same time? mptSmp.nC5Speed = c2freq; mptSmp.Transpose(((finetune ^ 0x08) - 0x78) / (12.0 * 16.0)); mptSmp.nVolume = std::min(volume, 64u) * 4u; mptSmp.uFlags.reset(); if(flags & PSM16SampleHeader::smp16Bit) { mptSmp.uFlags.set(CHN_16BIT); mptSmp.nLength /= 2u; } if(flags & PSM16SampleHeader::smpPingPong) { mptSmp.uFlags.set(CHN_PINGPONGLOOP); } if(flags & PSM16SampleHeader::smpLoop) { mptSmp.uFlags.set(CHN_LOOP); } } // Retrieve the internal sample format flags for this sample. SampleIO GetSampleFormat() const { SampleIO sampleIO( (flags & PSM16SampleHeader::smp16Bit) ? SampleIO::_16bit : SampleIO::_8bit, SampleIO::mono, SampleIO::littleEndian, SampleIO::signedPCM); if(flags & PSM16SampleHeader::smpUnsigned) { sampleIO |= SampleIO::unsignedPCM; } else if((flags & PSM16SampleHeader::smpDelta) || (flags & PSM16SampleHeader::smpMask) == 0) { sampleIO |= SampleIO::deltaPCM; } return sampleIO; } }; MPT_BINARY_STRUCT(PSM16SampleHeader, 64) struct PSM16PatternHeader { uint16le size; // includes header bytes uint8le numRows; // 1 ... 64 uint8le numChans; // 1 ... 32 }; MPT_BINARY_STRUCT(PSM16PatternHeader, 4) static bool ValidateHeader(const PSM16FileHeader &fileHeader) { if(std::memcmp(fileHeader.formatID, "PSM\xFE", 4) || fileHeader.lineEnd != 0x1A || (fileHeader.formatVersion != 0x10 && fileHeader.formatVersion != 0x01) // why is this sometimes 0x01? || fileHeader.patternVersion != 0 // 255ch pattern version not supported (did anyone use this?) || (fileHeader.songType & 3) != 0 || fileHeader.numChannelsPlay > MAX_BASECHANNELS || fileHeader.numChannelsReal > MAX_BASECHANNELS || std::max(fileHeader.numChannelsPlay, fileHeader.numChannelsReal) == 0) { return false; } return true; } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderPSM16(MemoryFileReader file, const uint64 *pfilesize) { PSM16FileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return ProbeWantMoreData; } if(!ValidateHeader(fileHeader)) { return ProbeFailure; } MPT_UNREFERENCED_PARAMETER(pfilesize); return ProbeSuccess; } bool CSoundFile::ReadPSM16(FileReader &file, ModLoadingFlags loadFlags) { file.Rewind(); // Is it a valid PSM16 file? PSM16FileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return false; } if(!ValidateHeader(fileHeader)) { return false; } if(loadFlags == onlyVerifyHeader) { return true; } // Seems to be valid! InitializeGlobals(MOD_TYPE_PSM); m_madeWithTracker = MPT_USTRING("Epic MegaGames MASI (Old Version)"); m_nChannels = Clamp(CHANNELINDEX(fileHeader.numChannelsPlay), CHANNELINDEX(fileHeader.numChannelsReal), MAX_BASECHANNELS); m_nSamplePreAmp = fileHeader.masterVolume; if(m_nSamplePreAmp == 255) { // Most of the time, the master volume value makes sense... Just not when it's 255. m_nSamplePreAmp = 48; } m_nDefaultSpeed = fileHeader.songSpeed; m_nDefaultTempo.Set(fileHeader.songTempo); mpt::String::Read(m_songName, fileHeader.songName); // Read orders if(fileHeader.orderOffset > 4 && file.Seek(fileHeader.orderOffset - 4) && file.ReadMagic("PORD")) { ReadOrderFromFile(Order(), file, fileHeader.songOrders); } // Read pan positions if(fileHeader.panOffset > 4 && file.Seek(fileHeader.panOffset - 4) && file.ReadMagic("PPAN")) { for(CHANNELINDEX i = 0; i < 32; i++) { ChnSettings[i].Reset(); ChnSettings[i].nPan = ((15 - (file.ReadUint8() & 0x0F)) * 256 + 8) / 15; // 15 seems to be left and 0 seems to be right... // ChnSettings[i].dwFlags = (i >= fileHeader.numChannelsPlay) ? CHN_MUTE : 0; // don't mute channels, as muted channels are completely ignored in S3M } } // Read samples if(fileHeader.smpOffset > 4 && file.Seek(fileHeader.smpOffset - 4) && file.ReadMagic("PSAH")) { FileReader sampleChunk = file.ReadChunk(fileHeader.numSamples * sizeof(PSM16SampleHeader)); for(SAMPLEINDEX fileSample = 0; fileSample < fileHeader.numSamples; fileSample++) { PSM16SampleHeader sampleHeader; if(!sampleChunk.ReadStruct(sampleHeader)) { break; } SAMPLEINDEX smp = sampleHeader.sampleNumber; if(smp > 0 && smp < MAX_SAMPLES) { m_nSamples = std::max(m_nSamples, smp); sampleHeader.ConvertToMPT(Samples[smp]); mpt::String::Read(m_szNames[smp], sampleHeader.name); if(loadFlags & loadSampleData) { file.Seek(sampleHeader.offset); sampleHeader.GetSampleFormat().ReadSample(Samples[smp], file); } } } } // Read patterns if(!(loadFlags & loadPatternData)) { return true; } if(fileHeader.patOffset > 4 && file.Seek(fileHeader.patOffset - 4) && file.ReadMagic("PPAT")) { Patterns.ResizeArray(fileHeader.numPatterns); for(PATTERNINDEX pat = 0; pat < fileHeader.numPatterns; pat++) { PSM16PatternHeader patternHeader; if(!file.ReadStruct(patternHeader)) { break; } if(patternHeader.size < sizeof(PSM16PatternHeader)) { continue; } // Patterns are padded to 16 Bytes FileReader patternChunk = file.ReadChunk(((patternHeader.size + 15) & ~15) - sizeof(PSM16PatternHeader)); if(!Patterns.Insert(pat, patternHeader.numRows)) { continue; } enum { channelMask = 0x1F, noteFlag = 0x80, volFlag = 0x40, effectFlag = 0x20, }; ROWINDEX curRow = 0; while(patternChunk.CanRead(1) && curRow < patternHeader.numRows) { uint8 chnFlag = patternChunk.ReadUint8(); if(chnFlag == 0) { curRow++; continue; } ModCommand &m = *Patterns[pat].GetpModCommand(curRow, std::min(chnFlag & channelMask, m_nChannels - 1)); if(chnFlag & noteFlag) { // note + instr present m.note = patternChunk.ReadUint8() + 36; m.instr = patternChunk.ReadUint8(); } if(chnFlag & volFlag) { // volume present m.volcmd = VOLCMD_VOLUME; m.vol = std::min(patternChunk.ReadUint8(), uint8(64)); } if(chnFlag & effectFlag) { // effect present - convert m.command = patternChunk.ReadUint8(); m.param = patternChunk.ReadUint8(); switch(m.command) { // Volslides case 0x01: // fine volslide up m.command = CMD_VOLUMESLIDE; m.param = (m.param << 4) | 0x0F; break; case 0x02: // volslide up m.command = CMD_VOLUMESLIDE; m.param = (m.param << 4) & 0xF0; break; case 0x03: // fine voslide down m.command = CMD_VOLUMESLIDE; m.param = 0xF0 | m.param; break; case 0x04: // volslide down m.command = CMD_VOLUMESLIDE; m.param = m.param & 0x0F; break; // Portamento case 0x0A: // fine portamento up m.command = CMD_PORTAMENTOUP; m.param |= 0xF0; break; case 0x0B: // portamento down m.command = CMD_PORTAMENTOUP; break; case 0x0C: // fine portamento down m.command = CMD_PORTAMENTODOWN; m.param |= 0xF0; break; case 0x0D: // portamento down m.command = CMD_PORTAMENTODOWN; break; case 0x0E: // tone portamento m.command = CMD_TONEPORTAMENTO; break; case 0x0F: // glissando control m.command = CMD_S3MCMDEX; m.param |= 0x10; break; case 0x10: // tone portamento + volslide up m.command = CMD_TONEPORTAVOL; m.param <<= 4; break; case 0x11: // tone portamento + volslide down m.command = CMD_TONEPORTAVOL; m.param &= 0x0F; break; // Vibrato case 0x14: // vibrato m.command = CMD_VIBRATO; break; case 0x15: // vibrato waveform m.command = CMD_S3MCMDEX; m.param |= 0x30; break; case 0x16: // vibrato + volslide up m.command = CMD_VIBRATOVOL; m.param <<= 4; break; case 0x17: // vibrato + volslide down m.command = CMD_VIBRATOVOL; m.param &= 0x0F; break; // Tremolo case 0x1E: // tremolo m.command = CMD_TREMOLO; break; case 0x1F: // tremolo waveform m.command = CMD_S3MCMDEX; m.param |= 0x40; break; // Sample commands case 0x28: // 3-byte offset - we only support the middle byte. m.command = CMD_OFFSET; m.param = patternChunk.ReadUint8(); patternChunk.Skip(1); break; case 0x29: // retrigger m.command = CMD_RETRIG; m.param &= 0x0F; break; case 0x2A: // note cut m.command = CMD_S3MCMDEX; #ifdef MODPLUG_TRACKER if(m.param == 0) // in S3M mode, SC0 is ignored, so we convert it to a note cut. { if(m.note == NOTE_NONE) { m.note = NOTE_NOTECUT; m.command = CMD_NONE; } else { m.param = 1; } } #endif // MODPLUG_TRACKER m.param |= 0xC0; break; case 0x2B: // note delay m.command = CMD_S3MCMDEX; m.param |= 0xD0; break; // Position change case 0x32: // position jump m.command = CMD_POSITIONJUMP; break; case 0x33: // pattern break m.command = CMD_PATTERNBREAK; break; case 0x34: // loop pattern m.command = CMD_S3MCMDEX; m.param |= 0xB0; break; case 0x35: // pattern delay m.command = CMD_S3MCMDEX; m.param |= 0xE0; break; // speed change case 0x3C: // set speed m.command = CMD_SPEED; break; case 0x3D: // set tempo m.command = CMD_TEMPO; break; // misc commands case 0x46: // arpeggio m.command = CMD_ARPEGGIO; break; case 0x47: // set finetune m.command = CMD_S3MCMDEX; m.param = 0x20 | (m.param & 0x0F); break; case 0x48: // set balance (panning?) m.command = CMD_S3MCMDEX; m.param = 0x80 | (m.param & 0x0F); break; default: m.command = CMD_NONE; break; } } } // Pattern break for short patterns (so saving the modules as S3M won't break it) if(patternHeader.numRows != 64) { Patterns[pat].WriteEffect(EffectWriter(CMD_PATTERNBREAK, 0).Row(patternHeader.numRows - 1).RetryNextRow()); } } } if(fileHeader.commentsOffset != 0) { file.Seek(fileHeader.commentsOffset); m_songMessage.Read(file, file.ReadUint16LE(), SongMessage::leAutodetect); } return true; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/tuningbase.cpp0000644000372100037210000000624113161656666020763 00000000000000/* * tuningbase.cpp * -------------- * Purpose: Alternative sample tuning. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "tuningbase.h" #include "tuning.h" #include "../common/mptIO.h" #include "../common/serialization_utils.h" #include #include #include OPENMPT_NAMESPACE_BEGIN namespace Tuning { /* Version history: 4->5: Lots of changes, finestep interpretation revamp, fileformat revamp. 3->4: Changed sizetypes in serialisation from size_t(uint32) to smaller types (uint8, USTEPTYPE) (March 2007) */ const char CTuningRTI::s_FileExtension[5] = ".tun"; void CTuningRTI::SetNoteName(const NOTEINDEXTYPE& n, const std::string& str) { if(!str.empty()) { m_NoteNameMap[n] = str; } else { const auto iter = m_NoteNameMap.find(n); if(iter != m_NoteNameMap.end()) { m_NoteNameMap.erase(iter); } } } bool CTuningRTI::Multiply(const RATIOTYPE& r) { if(r <= 0) return true; //Note: Multiplying ratios by constant doesn't //change, e.g. 'geometricness' status. for(auto & ratio : m_RatioTable) { ratio *= r; } return false; } bool CTuningRTI::CreateGroupGeometric(const NOTEINDEXTYPE& s, const RATIOTYPE& r, const NOTEINDEXTYPE& startindex) { if(s < 1 || r <= 0 || startindex < GetValidityRange().first) return true; std::vector v; v.reserve(s); for(NOTEINDEXTYPE i = startindex; i& v, const RATIOTYPE& r, const VRPAIR vr, const NOTEINDEXTYPE ratiostartpos) { { if(vr.first > vr.second || v.size() == 0) return true; if(ratiostartpos < vr.first || vr.second < ratiostartpos || static_cast(vr.second - ratiostartpos) < static_cast(v.size() - 1)) return true; if(GetFineStepCount() > FINESTEPCOUNT_MAX) return true; for(size_t i = 0; i vr.second) return true; if(s < 1 || r <= 0) return true; if(ProCreateGeometric(s,r,vr)) return true; else { m_TuningType = TT_GEOMETRIC; UpdateFineStepTable(); return false; } } } bool CTuningRTI::ChangeGroupsize(const NOTEINDEXTYPE& s) { if(s < 1) return true; if(m_TuningType == TT_GROUPGEOMETRIC) return CreateGroupGeometric(s, GetGroupRatio(), 0); if(m_TuningType == TT_GEOMETRIC) return CreateGeometric(s, GetGroupRatio()); return true; } bool CTuningRTI::ChangeGroupRatio(const RATIOTYPE& r) { if(r <= 0) return true; if(m_TuningType == TT_GROUPGEOMETRIC) return CreateGroupGeometric(GetGroupSize(), r, 0); if(m_TuningType == TT_GEOMETRIC) return CreateGeometric(GetGroupSize(), r); return true; } } // namespace Tuning OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/FloatMixer.h0000644000372100037210000002360313116241660020324 00000000000000/* * FloatMixer.h * ------------ * Purpose: Floating point mixer classes * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "MixerInterface.h" #include "Resampler.h" OPENMPT_NAMESPACE_BEGIN template struct IntToFloatTraits : public MixerTraits { static_assert(std::numeric_limits::is_integer, "Input must be integer"); static_assert(!std::numeric_limits::is_integer, "Output must be floating point"); static MPT_CONSTEXPR11_FUN output_t Convert(const input_t x) { return static_cast(x) * (static_cast(1) / static_cast(int2float)); } }; typedef IntToFloatTraits<2, 1, mixsample_t, int8, -int8_min> Int8MToFloatS; typedef IntToFloatTraits<2, 1, mixsample_t, int16, -int16_min> Int16MToFloatS; typedef IntToFloatTraits<2, 2, mixsample_t, int8, -int8_min> Int8SToFloatS; typedef IntToFloatTraits<2, 2, mixsample_t, int16, -int16_min> Int16SToFloatS; ////////////////////////////////////////////////////////////////////////// // Interpolation templates template struct LinearInterpolation { MPT_FORCEINLINE void Start(const ModChannel &, const CResampler &) { } MPT_FORCEINLINE void End(const ModChannel &) { } MPT_FORCEINLINE void operator() (typename Traits::outbuf_t &outSample, const typename Traits::input_t * const inBuffer, const uint32 posLo) { static_assert(Traits::numChannelsIn <= Traits::numChannelsOut, "Too many input channels"); const typename Traits::output_t fract = posLo / static_cast(0x100000000); //CResampler::LinearTablef[posLo >> 24]; for(int i = 0; i < Traits::numChannelsIn; i++) { typename Traits::output_t srcVol = Traits::Convert(inBuffer[i]); typename Traits::output_t destVol = Traits::Convert(inBuffer[i + Traits::numChannelsIn]); outSample[i] = srcVol + fract * (destVol - srcVol); } } }; template struct FastSincInterpolation { MPT_FORCEINLINE void Start(const ModChannel &, const CResampler &) { } MPT_FORCEINLINE void End(const ModChannel &) { } MPT_FORCEINLINE void operator() (typename Traits::outbuf_t &outSample, const typename Traits::input_t * const inBuffer, const uint32 posLo) { static_assert(Traits::numChannelsIn <= Traits::numChannelsOut, "Too many input channels"); const typename Traits::output_t *lut = CResampler::FastSincTablef + ((posLo >> 22) & 0x3FC); for(int i = 0; i < Traits::numChannelsIn; i++) { outSample[i] = lut[0] * Traits::Convert(inBuffer[i - Traits::numChannelsIn]) + lut[1] * Traits::Convert(inBuffer[i]) + lut[2] * Traits::Convert(inBuffer[i + Traits::numChannelsIn]) + lut[3] * Traits::Convert(inBuffer[i + 2 * Traits::numChannelsIn]); } } }; template struct PolyphaseInterpolation { const typename Traits::output_t *sinc; MPT_FORCEINLINE void Start(const ModChannel &chn, const CResampler &resampler) { sinc = (((chn.increment > SamplePosition(0x130000000ll)) || (chn.increment < -SamplePosition(-0x130000000ll))) ? (((chn.increment > SamplePosition(0x180000000ll)) || (chn.increment < SamplePosition(-0x180000000ll))) ? resampler.gDownsample2x : resampler.gDownsample13x) : resampler.gKaiserSinc); } MPT_FORCEINLINE void End(const ModChannel &) { } MPT_FORCEINLINE void operator() (typename Traits::outbuf_t &outSample, const typename Traits::input_t * const inBuffer, const uint32 posLo) { static_assert(Traits::numChannelsIn <= Traits::numChannelsOut, "Too many input channels"); const typename Traits::output_t *lut = sinc + ((posLo >> (32 - SINC_PHASES_BITS)) & SINC_MASK) * SINC_WIDTH; for(int i = 0; i < Traits::numChannelsIn; i++) { outSample[i] = lut[0] * Traits::Convert(inBuffer[i - 3 * Traits::numChannelsIn]) + lut[1] * Traits::Convert(inBuffer[i - 2 * Traits::numChannelsIn]) + lut[2] * Traits::Convert(inBuffer[i - Traits::numChannelsIn]) + lut[3] * Traits::Convert(inBuffer[i]) + lut[4] * Traits::Convert(inBuffer[i + Traits::numChannelsIn]) + lut[5] * Traits::Convert(inBuffer[i + 2 * Traits::numChannelsIn]) + lut[6] * Traits::Convert(inBuffer[i + 3 * Traits::numChannelsIn]) + lut[7] * Traits::Convert(inBuffer[i + 4 * Traits::numChannelsIn]); } } }; template struct FIRFilterInterpolation { const typename Traits::output_t *WFIRlut; MPT_FORCEINLINE void Start(const ModChannel &, const CResampler &resampler) { WFIRlut = resampler.m_WindowedFIR.lut; } MPT_FORCEINLINE void End(const ModChannel &) { } MPT_FORCEINLINE void operator() (typename Traits::outbuf_t &outSample, const typename Traits::input_t * const inBuffer, const uint32 posLo) { static_assert(Traits::numChannelsIn <= Traits::numChannelsOut, "Too many input channels"); const typename Traits::output_t * const lut = WFIRlut + ((((posLo >> 16) + WFIR_FRACHALVE) >> WFIR_FRACSHIFT) & WFIR_FRACMASK); for(int i = 0; i < Traits::numChannelsIn; i++) { outSample[i] = lut[0] * Traits::Convert(inBuffer[i - 3 * Traits::numChannelsIn]) + lut[1] * Traits::Convert(inBuffer[i - 2 * Traits::numChannelsIn]) + lut[2] * Traits::Convert(inBuffer[i - Traits::numChannelsIn]) + lut[3] * Traits::Convert(inBuffer[i]) + lut[4] * Traits::Convert(inBuffer[i + Traits::numChannelsIn]) + lut[5] * Traits::Convert(inBuffer[i + 2 * Traits::numChannelsIn]) + lut[6] * Traits::Convert(inBuffer[i + 3 * Traits::numChannelsIn]) + lut[7] * Traits::Convert(inBuffer[i + 4 * Traits::numChannelsIn]); } } }; ////////////////////////////////////////////////////////////////////////// // Mixing templates (add sample to stereo mix) template struct NoRamp { typename Traits::output_t lVol, rVol; MPT_FORCEINLINE void Start(const ModChannel &chn) { lVol = static_cast(chn.leftVol) * (1.0f / 4096.0f); rVol = static_cast(chn.rightVol) * (1.0f / 4096.0f); } MPT_FORCEINLINE void End(const ModChannel &) { } }; struct Ramp { int32 lRamp, rRamp; MPT_FORCEINLINE void Start(const ModChannel &chn) { lRamp = chn.rampLeftVol; rRamp = chn.rampRightVol; } MPT_FORCEINLINE void End(ModChannel &chn) { chn.rampLeftVol = lRamp; chn.leftVol = lRamp >> VOLUMERAMPPRECISION; chn.rampRightVol = rRamp; chn.rightVol = rRamp >> VOLUMERAMPPRECISION; } }; // Legacy optimization: If chn.nLeftVol == chn.nRightVol, save one multiplication instruction template struct MixMonoFastNoRamp : public NoRamp { MPT_FORCEINLINE void operator() (const typename Traits::outbuf_t &outSample, const ModChannel &chn, typename Traits::output_t * const outBuffer) { typename Traits::output_t vol = outSample[0] * lVol; for(int i = 0; i < Traits::numChannelsOut; i++) { outBuffer[i] += vol; } } }; template struct MixMonoNoRamp : public NoRamp { MPT_FORCEINLINE void operator() (const typename Traits::outbuf_t &outSample, const ModChannel &, typename Traits::output_t * const outBuffer) { outBuffer[0] += outSample[0] * lVol; outBuffer[1] += outSample[0] * rVol; } }; template struct MixMonoRamp : public Ramp { MPT_FORCEINLINE void operator() (const typename Traits::outbuf_t &outSample, const ModChannel &chn, typename Traits::output_t * const outBuffer) { // TODO volume is not float, can we optimize this? lRamp += chn.leftRamp; rRamp += chn.rightRamp; outBuffer[0] += outSample[0] * (lRamp >> VOLUMERAMPPRECISION) * (1.0f / 4096.0f); outBuffer[1] += outSample[0] * (rRamp >> VOLUMERAMPPRECISION) * (1.0f / 4096.0f); } }; template struct MixStereoNoRamp : public NoRamp { MPT_FORCEINLINE void operator() (const typename Traits::outbuf_t &outSample, const ModChannel &, typename Traits::output_t * const outBuffer) { outBuffer[0] += outSample[0] * lVol; outBuffer[1] += outSample[1] * rVol; } }; template struct MixStereoRamp : public Ramp { MPT_FORCEINLINE void operator() (const typename Traits::outbuf_t &outSample, const ModChannel &chn, typename Traits::output_t * const outBuffer) { // TODO volume is not float, can we optimize this? lRamp += chn.leftRamp; rRamp += chn.rightRamp; outBuffer[0] += outSample[0] * (lRamp >> VOLUMERAMPPRECISION) * (1.0f / 4096.0f); outBuffer[1] += outSample[1] * (rRamp >> VOLUMERAMPPRECISION) * (1.0f / 4096.0f); } }; ////////////////////////////////////////////////////////////////////////// // Filter templates template struct NoFilter { MPT_FORCEINLINE void Start(const ModChannel &) { } MPT_FORCEINLINE void End(const ModChannel &) { } MPT_FORCEINLINE void operator() (const typename Traits::outbuf_t &, const ModChannel &) { } }; // Resonant filter template struct ResonantFilter { // Filter history typename Traits::output_t fy[Traits::numChannelsIn][2]; MPT_FORCEINLINE void Start(const ModChannel &chn) { for(int i = 0; i < Traits::numChannelsIn; i++) { fy[i][0] = chn.nFilter_Y[i][0]; fy[i][1] = chn.nFilter_Y[i][1]; } } MPT_FORCEINLINE void End(ModChannel &chn) { for(int i = 0; i < Traits::numChannelsIn; i++) { chn.nFilter_Y[i][0] = fy[i][0]; chn.nFilter_Y[i][1] = fy[i][1]; } } // Filter values are clipped to double the input range #define ClipFilter(x) Clamp(x, static_cast(-2.0f), static_cast(2.0f)) MPT_FORCEINLINE void operator() (typename Traits::outbuf_t &outSample, const ModChannel &chn) { static_assert(Traits::numChannelsIn <= Traits::numChannelsOut, "Too many input channels"); for(int i = 0; i < Traits::numChannelsIn; i++) { typename Traits::output_t val = outSample[i] * chn.nFilter_A0 + ClipFilter(fy[i][0]) * chn.nFilter_B0 + ClipFilter(fy[i][1]) * chn.nFilter_B1; fy[i][1] = fy[i][0]; fy[i][0] = val - (outSample[i] * chn.nFilter_HP); outSample[i] = val; } } #undef ClipFilter }; OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/MixerInterface.h0000644000372100037210000000702013116241660021152 00000000000000/* * MixerInterface.h * ---------------- * Purpose: The basic mixer interface and main mixer loop, completely agnostic of the actual sample input / output formats. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "Snd_defs.h" #include "ModChannel.h" OPENMPT_NAMESPACE_BEGIN class CResampler; ////////////////////////////////////////////////////////////////////////// // Sample conversion traits template struct MixerTraits { static const int numChannelsIn = channelsIn; // Number of channels in sample static const int numChannelsOut = channelsOut; // Number of mixer output channels typedef out output_t; // Output buffer sample type typedef in input_t; // Input buffer sample type typedef out outbuf_t[channelsOut]; // Output buffer sampling point type // To perform sample conversion, add a function with the following signature to your derived classes: // static MPT_CONSTEXPR11_FUN output_t Convert(const input_t x) }; ////////////////////////////////////////////////////////////////////////// // Interpolation templates template struct NoInterpolation { MPT_FORCEINLINE void Start(const ModChannel &, const CResampler &) { } MPT_FORCEINLINE void End(const ModChannel &) { } MPT_FORCEINLINE void operator() (typename Traits::outbuf_t &outSample, const typename Traits::input_t * const inBuffer, const int32) { static_assert(Traits::numChannelsIn <= Traits::numChannelsOut, "Too many input channels"); for(int i = 0; i < Traits::numChannelsIn; i++) { outSample[i] = Traits::Convert(inBuffer[i]); } } }; // Other interpolation algorithms depend on the input format type (integer / float) and can thus be found in FloatMixer.h and IntMixer.h ////////////////////////////////////////////////////////////////////////// // Main sample render loop template // Template parameters: // Traits: A class derived from MixerTraits that defines the number of channels, sample buffer types, etc.. // InterpolationFunc: Functor for reading the sample data and doing the SRC // FilterFunc: Functor for applying the resonant filter // MixFunc: Functor for mixing the computed sample data into the output buffer template static void SampleLoop(ModChannel &chn, const CResampler &resampler, typename Traits::output_t * MPT_RESTRICT outBuffer, unsigned int numSamples) { ModChannel &c = chn; const typename Traits::input_t * MPT_RESTRICT inSample = static_cast(c.pCurrentSample); InterpolationFunc interpolate; FilterFunc filter; MixFunc mix; // Do initialisation if necessary interpolate.Start(c, resampler); filter.Start(c); mix.Start(c); unsigned int samples = numSamples; SamplePosition smpPos = c.position; // Fixed-point sample position const SamplePosition increment = c.increment; // Fixed-point sample increment while(samples--) { typename Traits::outbuf_t outSample; interpolate(outSample, inSample + smpPos.GetInt() * Traits::numChannelsIn, smpPos.GetFract()); filter(outSample, c); mix(outSample, c, outBuffer); outBuffer += Traits::numChannelsOut; smpPos += increment; } mix.End(c); filter.End(c); interpolate.End(c); c.position = smpPos; } // Type of the SampleLoop function above typedef void (*MixFuncInterface)(ModChannel &, const CResampler &, mixsample_t *, unsigned int); OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Load_itp.cpp0000644000372100037210000002611413161656666020360 00000000000000/* * Load_itp.cpp * ------------ * Purpose: Impulse Tracker Project (ITP) module loader * Notes : Despite its name, ITP is not a format supported by Impulse Tracker. * In fact, it's a format invented by the OpenMPT team to allow people to work * with the IT format, but keeping the instrument files with big samples separate * from the pattern data, to keep the work files small and handy. * The design of the format is quite flawed, though, so it was superseded by * extra functionality in the MPTM format in OpenMPT 1.24. * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "../common/version.h" #include "Loaders.h" #include "ITTools.h" #ifdef MODPLUG_TRACKER // For loading external instruments #include "../mptrack/Moddoc.h" #endif // MODPLUG_TRACKER #ifdef MPT_EXTERNAL_SAMPLES #include "../common/mptFileIO.h" #endif // MPT_EXTERNAL_SAMPLES OPENMPT_NAMESPACE_BEGIN // Version changelog: // v1.03: - Relative unicode instrument paths instead of absolute ANSI paths // - Per-path variable string length // - Embedded samples are IT-compressed // (rev. 3249) // v1.02: Explicitely updated format to use new instrument flags representation (rev. 483) // v1.01: Added option to embed instrument headers struct ITPModCommand { uint8le note; uint8le instr; uint8le volcmd; uint8le command; uint8le vol; uint8le param; operator ModCommand() const { ModCommand result; result.note = (ModCommand::IsNote(note) || ModCommand::IsSpecialNote(note)) ? note : NOTE_NONE; result.instr = instr; result.command = (command < MAX_EFFECTS) ? static_cast(command.get()) : CMD_NONE; result.volcmd = (volcmd < MAX_VOLCMDS) ? static_cast(volcmd.get()) : VOLCMD_NONE; result.vol = vol; result.param = param; return result; } }; MPT_BINARY_STRUCT(ITPModCommand, 6) struct ITPHeader { uint32le magic; uint32le version; }; MPT_BINARY_STRUCT(ITPHeader, 8) static bool ValidateHeader(const ITPHeader &hdr) { if(hdr.magic != MAGIC4BE('.','i','t','p')) { return false; } if(hdr.version > 0x00000103 || hdr.version < 0x00000100) { return false; } return true; } static uint64 GetHeaderMinimumAdditionalSize(const ITPHeader &hdr) { MPT_UNREFERENCED_PARAMETER(hdr); return 12 + 4 + 24 + 4 - sizeof(ITPHeader); } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderITP(MemoryFileReader file, const uint64 *pfilesize) { ITPHeader hdr; if(!file.ReadStruct(hdr)) { return ProbeWantMoreData; } if(!ValidateHeader(hdr)) { return ProbeFailure; } return ProbeAdditionalSize(file, pfilesize, GetHeaderMinimumAdditionalSize(hdr)); } bool CSoundFile::ReadITProject(FileReader &file, ModLoadingFlags loadFlags) { #if !defined(MPT_EXTERNAL_SAMPLES) && !defined(MPT_FUZZ_TRACKER) // Doesn't really make sense to support this format when there's no support for external files... MPT_UNREFERENCED_PARAMETER(file); MPT_UNREFERENCED_PARAMETER(loadFlags); return false; #else // !MPT_EXTERNAL_SAMPLES && !MPT_FUZZ_TRACKER enum ITPSongFlags { ITP_EMBEDMIDICFG = 0x00001, // Embed macros in file ITP_ITOLDEFFECTS = 0x00004, // Old Impulse Tracker effect implementations ITP_ITCOMPATGXX = 0x00008, // IT "Compatible Gxx" (IT's flag to behave more like other trackers w/r/t portamento effects) ITP_LINEARSLIDES = 0x00010, // Linear slides vs. Amiga slides ITP_EXFILTERRANGE = 0x08000, // Cutoff Filter has double frequency range (up to ~10Khz) ITP_ITPROJECT = 0x20000, // Is a project file ITP_ITPEMBEDIH = 0x40000, // Embed instrument headers in project file }; file.Rewind(); ITPHeader hdr; if(!file.ReadStruct(hdr)) { return false; } if(!ValidateHeader(hdr)) { return false; } if(!file.CanRead(mpt::saturate_cast(GetHeaderMinimumAdditionalSize(hdr)))) { return false; } if(loadFlags == onlyVerifyHeader) { return true; } uint32 version, size; version = hdr.version; InitializeGlobals(MOD_TYPE_IT); m_playBehaviour.reset(); file.ReadSizedString(m_songName); // Song comments m_songMessage.Read(file, file.ReadUint32LE(), SongMessage::leCR); // Song global config const uint32 songFlags = file.ReadUint32LE(); if(!(songFlags & ITP_ITPROJECT)) { return false; } if(songFlags & ITP_ITOLDEFFECTS) m_SongFlags.set(SONG_ITOLDEFFECTS); if(songFlags & ITP_ITCOMPATGXX) m_SongFlags.set(SONG_ITCOMPATGXX); if(songFlags & ITP_LINEARSLIDES) m_SongFlags.set(SONG_LINEARSLIDES); if(songFlags & ITP_EXFILTERRANGE) m_SongFlags.set(SONG_EXFILTERRANGE); m_nDefaultGlobalVolume = file.ReadUint32LE(); m_nSamplePreAmp = file.ReadUint32LE(); m_nDefaultSpeed = std::max(uint32(1), file.ReadUint32LE()); m_nDefaultTempo.Set(std::max(uint32(32), file.ReadUint32LE())); m_nChannels = static_cast(file.ReadUint32LE()); if(m_nChannels == 0 || m_nChannels > MAX_BASECHANNELS) { return false; } // channel name string length (=MAX_CHANNELNAME) size = file.ReadUint32LE(); // Channels' data for(CHANNELINDEX chn = 0; chn < m_nChannels; chn++) { ChnSettings[chn].nPan = std::min(static_cast(file.ReadUint32LE()), uint16(256)); ChnSettings[chn].dwFlags.reset(); uint32 flags = file.ReadUint32LE(); if(flags & 0x100) ChnSettings[chn].dwFlags.set(CHN_MUTE); if(flags & 0x800) ChnSettings[chn].dwFlags.set(CHN_SURROUND); ChnSettings[chn].nVolume = std::min(static_cast(file.ReadUint32LE()), uint16(64)); file.ReadString(ChnSettings[chn].szName, size); } // Song mix plugins { FileReader plugChunk = file.ReadChunk(file.ReadUint32LE()); LoadMixPlugins(plugChunk); } // MIDI Macro config file.ReadStructPartial(m_MidiCfg, file.ReadUint32LE()); m_MidiCfg.Sanitize(); // Song Instruments m_nInstruments = static_cast(file.ReadUint32LE()); if(m_nInstruments >= MAX_INSTRUMENTS) { m_nInstruments = 0; return false; } // Instruments' paths if(version <= 0x00000102) { size = file.ReadUint32LE(); // path string length } std::vector instrPaths(GetNumInstruments()); for(INSTRUMENTINDEX ins = 0; ins < GetNumInstruments(); ins++) { if(version > 0x00000102) { size = file.ReadUint32LE(); // path string length } std::string path; file.ReadString(path, size); #ifdef MODPLUG_TRACKER if(version <= 0x00000102) { instrPaths[ins] = mpt::PathString::FromLocaleSilent(path); } else #endif // MODPLUG_TRACKER { instrPaths[ins] = mpt::PathString::FromUTF8(path); } #ifdef MODPLUG_TRACKER if(!file.GetFileName().empty()) { instrPaths[ins] = instrPaths[ins].RelativePathToAbsolute(file.GetFileName().GetPath()); } else if(GetpModDoc() != nullptr) { instrPaths[ins] = instrPaths[ins].RelativePathToAbsolute(GetpModDoc()->GetPathNameMpt().GetPath()); } #endif // MODPLUG_TRACKER } // Song Orders size = file.ReadUint32LE(); ReadOrderFromFile(Order(), file, size, 0xFF, 0xFE); // Song Patterns const PATTERNINDEX numPats = static_cast(file.ReadUint32LE()); const PATTERNINDEX numNamedPats = static_cast(file.ReadUint32LE()); size_t patNameLen = file.ReadUint32LE(); // Size of each pattern name FileReader pattNames = file.ReadChunk(numNamedPats * patNameLen); // modcommand data length size = file.ReadUint32LE(); if(size != 6) { return false; } if(loadFlags & loadPatternData) Patterns.ResizeArray(numPats); for(PATTERNINDEX pat = 0; pat < numPats; pat++) { const ROWINDEX numRows = file.ReadUint32LE(); FileReader patternChunk = file.ReadChunk(numRows * size * GetNumChannels()); // Allocate pattern if(!(loadFlags & loadPatternData) || !Patterns.Insert(pat, numRows)) { pattNames.Skip(patNameLen); continue; } if(pat < numNamedPats) { char patName[32]; pattNames.ReadString(patName, patNameLen); Patterns[pat].SetName(patName); } // Pattern data size_t numCommands = GetNumChannels() * numRows; if(patternChunk.CanRead(sizeof(ITPModCommand) * numCommands)) { ModCommand *target = Patterns[pat].GetpModCommand(0, 0); while(numCommands-- != 0) { ITPModCommand data; patternChunk.ReadStruct(data); *(target++) = data; } } } // Load embedded samples // Read original number of samples m_nSamples = static_cast(file.ReadUint32LE()); LimitMax(m_nSamples, SAMPLEINDEX(MAX_SAMPLES - 1)); // Read number of embedded samples - at most as many as there are real samples in a valid file uint32 embeddedSamples = file.ReadUint32LE(); if(embeddedSamples > m_nSamples) { return false; } // Read samples for(uint32 smp = 0; smp < embeddedSamples && file.CanRead(8 + sizeof(ITSample)); smp++) { uint32 realSample = file.ReadUint32LE(); ITSample sampleHeader; file.ReadStruct(sampleHeader); FileReader sampleData = file.ReadChunk(file.ReadUint32LE()); if(realSample >= 1 && realSample <= GetNumSamples() && !memcmp(sampleHeader.id, "IMPS", 4) && (loadFlags & loadSampleData)) { sampleHeader.ConvertToMPT(Samples[realSample]); mpt::String::Read(m_szNames[realSample], sampleHeader.name); // Read sample data sampleHeader.GetSampleFormat().ReadSample(Samples[realSample], sampleData); } } // Load instruments for(INSTRUMENTINDEX ins = 0; ins < GetNumInstruments(); ins++) { if(instrPaths[ins].empty()) continue; #ifdef MPT_EXTERNAL_SAMPLES InputFile f(instrPaths[ins]); FileReader instrFile = GetFileReader(f); if(!ReadInstrumentFromFile(ins + 1, instrFile, true)) { AddToLog(LogWarning, MPT_USTRING("Unable to open instrument: ") + instrPaths[ins].ToUnicode()); } #else AddToLog(LogWarning, mpt::format(MPT_USTRING("Loading external instrument %1 ('%2') failed: External instruments are not supported."))(ins, instrPaths[ins].ToUnicode())); #endif // MPT_EXTERNAL_SAMPLES } // Extra info data uint32 code = file.ReadUint32LE(); // Embed instruments' header [v1.01] if(version >= 0x00000101 && (songFlags & ITP_ITPEMBEDIH) && code == MAGIC4BE('E', 'B', 'I', 'H')) { code = file.ReadUint32LE(); INSTRUMENTINDEX ins = 1; while(ins <= GetNumInstruments() && file.CanRead(4)) { if(code == MAGIC4BE('M', 'P', 'T', 'S')) { break; } else if(code == MAGIC4BE('S', 'E', 'P', '@') || code == MAGIC4BE('M', 'P', 'T', 'X')) { // jump code - switch to next instrument ins++; } else { ReadExtendedInstrumentProperty(Instruments[ins], code, file); } code = file.ReadUint32LE(); } } // Song extensions if(code == MAGIC4BE('M', 'P', 'T', 'S')) { file.SkipBack(4); LoadExtendedSongProperties(file); } m_nMaxPeriod = 0xF000; m_nMinPeriod = 8; // Before OpenMPT 1.20.01.09, the MIDI macros were always read from the file, even if the "embed" flag was not set. if(m_dwLastSavedWithVersion >= MAKE_VERSION_NUMERIC(1,20,01,09) && !(songFlags & ITP_EMBEDMIDICFG)) { m_MidiCfg.Reset(); } m_madeWithTracker = MPT_USTRING("OpenMPT ") + MptVersion::ToUString(m_dwLastSavedWithVersion); return true; #endif // MPT_EXTERNAL_SAMPLES } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/patternContainer.cpp0000644000372100037210000001075013161656666022144 00000000000000/* * PatternContainer.cpp * -------------------- * Purpose: Container class for managing patterns. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "patternContainer.h" #include "Sndfile.h" #include "mod_specifications.h" #include "../common/serialization_utils.h" #include "../common/version.h" OPENMPT_NAMESPACE_BEGIN void CPatternContainer::ClearPatterns() { DestroyPatterns(); m_Patterns.assign(m_Patterns.size(), CPattern(*this)); } void CPatternContainer::DestroyPatterns() { for(PATTERNINDEX i = 0; i < m_Patterns.size(); i++) { Remove(i); } } PATTERNINDEX CPatternContainer::Duplicate(PATTERNINDEX from, bool respectQtyLimits) { if(!IsValidPat(from)) { return PATTERNINDEX_INVALID; } PATTERNINDEX newPatIndex = InsertAny(m_Patterns[from].GetNumRows(), respectQtyLimits); if(newPatIndex != PATTERNINDEX_INVALID) { m_Patterns[newPatIndex] = m_Patterns[from]; } return newPatIndex; } PATTERNINDEX CPatternContainer::InsertAny(const ROWINDEX rows, bool respectQtyLimits) { PATTERNINDEX i = 0; for(i = 0; i < m_Patterns.size(); i++) if(!m_Patterns[i].IsValid()) break; if(respectQtyLimits && i >= m_rSndFile.GetModSpecifications().patternsMax) return PATTERNINDEX_INVALID; if(!Insert(i, rows)) return PATTERNINDEX_INVALID; else return i; } bool CPatternContainer::Insert(const PATTERNINDEX index, const ROWINDEX rows) { if(rows > MAX_PATTERN_ROWS || rows == 0) return false; if(IsValidPat(index)) return false; try { if(index >= m_Patterns.size()) { m_Patterns.resize(index + 1, CPattern(*this)); } m_Patterns[index].AllocatePattern(rows); m_Patterns[index].RemoveSignature(); m_Patterns[index].SetName(""); } MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e) { MPT_EXCEPTION_DELETE_OUT_OF_MEMORY(e); return false; } return m_Patterns[index].IsValid(); } void CPatternContainer::Remove(const PATTERNINDEX ipat) { if(ipat < m_Patterns.size()) m_Patterns[ipat].Deallocate(); } bool CPatternContainer::IsPatternEmpty(const PATTERNINDEX nPat) const { if(!IsValidPat(nPat)) return false; for(const auto &m : m_Patterns[nPat].m_ModCommands) { if(!m.IsEmpty()) return false; } return true; } void CPatternContainer::ResizeArray(const PATTERNINDEX newSize) { if(Size() <= newSize) { m_Patterns.resize(newSize, CPattern(*this)); } else { for(PATTERNINDEX i = Size(); i > newSize; i--) Remove(i - 1); m_Patterns.resize(newSize, CPattern(*this)); } } void CPatternContainer::OnModTypeChanged(const MODTYPE /*oldtype*/) { const CModSpecifications specs = m_rSndFile.GetModSpecifications(); //if(specs.patternsMax < Size()) // ResizeArray(specs.patternsMax); // remove pattern time signatures if(!specs.hasPatternSignatures) { for(PATTERNINDEX nPat = 0; nPat < m_Patterns.size(); nPat++) { m_Patterns[nPat].RemoveSignature(); m_Patterns[nPat].RemoveTempoSwing(); } } } PATTERNINDEX CPatternContainer::GetNumPatterns() const { if(Size() == 0) { return 0; } for(PATTERNINDEX nPat = Size(); nPat > 0; nPat--) { if(IsValidPat(nPat - 1)) { return nPat; } } return 0; } PATTERNINDEX CPatternContainer::GetNumNamedPatterns() const { if(Size() == 0) { return 0; } for(PATTERNINDEX nPat = Size(); nPat > 0; nPat--) { if(!m_Patterns[nPat - 1].GetName().empty()) { return nPat; } } return 0; } void WriteModPatterns(std::ostream& oStrm, const CPatternContainer& patc) { srlztn::SsbWrite ssb(oStrm); ssb.BeginWrite(FileIdPatterns, MptVersion::num); const PATTERNINDEX nPatterns = patc.Size(); uint16 nCount = 0; for(uint16 i = 0; i < nPatterns; i++) if (patc[i].IsValid()) { ssb.WriteItem(patc[i], srlztn::ID::FromInt(i), &WriteModPattern); nCount = i + 1; } ssb.WriteItem(nCount, "num"); // Index of last pattern + 1. ssb.FinishWrite(); } void ReadModPatterns(std::istream& iStrm, CPatternContainer& patc, const size_t) { srlztn::SsbRead ssb(iStrm); ssb.BeginRead(FileIdPatterns, MptVersion::num); if ((ssb.GetStatus() & srlztn::SNT_FAILURE) != 0) return; PATTERNINDEX nPatterns = patc.Size(); uint16 nCount = uint16_max; if (ssb.ReadItem(nCount, "num") != srlztn::SsbRead::EntryNotFound) nPatterns = nCount; LimitMax(nPatterns, ModSpecs::mptm.patternsMax); if (nPatterns > patc.Size()) patc.ResizeArray(nPatterns); for(uint16 i = 0; i < nPatterns; i++) { ssb.ReadItem(patc[i], srlztn::ID::FromInt(i), &ReadModPattern); } } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Load_med.cpp0000644000372100037210000006563513161656666020344 00000000000000/* * Load_med.cpp * ------------ * Purpose: OctaMed MED module loader * Notes : (currently none) * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" #include "../common/StringFixer.h" OPENMPT_NAMESPACE_BEGIN //#define MED_LOG #define MED_MAX_COMMENT_LENGTH 5*1024 //: Is 5 kB enough? // flags #define MMD_FLAG_FILTERON 0x1 #define MMD_FLAG_JUMPINGON 0x2 #define MMD_FLAG_JUMP8TH 0x4 #define MMD_FLAG_INSTRSATT 0x8 // instruments are attached (this is a module) #define MMD_FLAG_VOLHEX 0x10 #define MMD_FLAG_STSLIDE 0x20 // SoundTracker mode for slides #define MMD_FLAG_8CHANNEL 0x40 // OctaMED 8 channel song #define MMD_FLAG_SLOWHQ 0x80 // HQ slows playing speed (V2-V4 compatibility) // flags2 #define MMD_FLAG2_BMASK 0x1F #define MMD_FLAG2_BPM 0x20 #define MMD_FLAG2_MIX 0x80 // uses Mixing (V7+) // flags3: #define MMD_FLAG3_STEREO 0x1 // mixing in Stereo mode #define MMD_FLAG3_FREEPAN 0x2 // free panning #define MMD_FLAG3_GM 0x4 // module designed for GM/XG compatibility // generic MMD tags #define MMDTAG_END 0 #define MMDTAG_PTR 0x80000000 // data needs relocation #define MMDTAG_MUSTKNOW 0x40000000 // loader must fail if this isn't recognized #define MMDTAG_MUSTWARN 0x20000000 // loader must warn if this isn't recognized // ExpData tags // # of effect groups, including the global group (will // override settings in MMDSong struct), default = 1 #define MMDTAG_EXP_NUMFXGROUPS 1 #define MMDTAG_TRK_NAME (MMDTAG_PTR|1) // trackinfo tags #define MMDTAG_TRK_NAMELEN 2 // namelen includes zero term. #define MMDTAG_TRK_FXGROUP 3 // effectinfo tags #define MMDTAG_FX_ECHOTYPE 1 #define MMDTAG_FX_ECHOLEN 2 #define MMDTAG_FX_ECHODEPTH 3 #define MMDTAG_FX_STEREOSEP 4 #define MMDTAG_FX_GROUPNAME (MMDTAG_PTR|5) // the Global Effects group shouldn't have name saved! #define MMDTAG_FX_GRPNAMELEN 6 // namelen includes zero term. struct MEDMODULEHEADER { char id[4]; // MMD1-MMD3 uint32be modlen; // Size of file uint32be song; // Position in file for this song uint16be psecnum; uint16be pseq; uint32be blockarr; // Position in file for blocks uint32be mmdflags; uint32be smplarr; // Position in file for samples uint32be reserved; uint32be expdata; // Absolute offset in file for ExpData (0 if not present) uint32be reserved2; uint16be pstate; uint16be pblock; uint16be pline; uint16be pseqnum; uint16be actplayline; uint8be counter; uint8be extra_songs; // # of songs - 1 }; MPT_BINARY_STRUCT(MEDMODULEHEADER, 52) struct MMD0SAMPLE { uint16be rep, replen; uint8be midich; uint8be midipreset; uint8be svol; int8be strans; }; MPT_BINARY_STRUCT(MMD0SAMPLE, 8) // Sample header is immediately followed by sample data... struct MMDSAMPLEHEADER { uint32be length; // length of *one* *unpacked* channel in *bytes* uint16be type; // if non-negative // bits 0-3 reserved for multi-octave instruments, not supported on the PC // 0x10: 16 bit (otherwise 8 bit) // 0x20: Stereo (otherwise mono) // 0x40: Uses DeltaCode // 0x80: Packed data // -1: Synth // -2: Hybrid // if type indicates packed data, these fields follow, otherwise we go right to the data uint16be packtype; // Only 1 = ADPCM is supported uint16be subtype; // Packing subtype // ADPCM subtype // 1: g723_40 // 2: g721 // 3: g723_24 uint8be commonflags; // flags common to all packtypes (none defined so far) uint8be packerflags; // flags for the specific packtype uint32be leftchlen; // packed length of left channel in bytes uint32be rightchlen; // packed length of right channel in bytes (ONLY PRESENT IN STEREO SAMPLES) uint8be SampleData[1]; // Sample Data }; MPT_BINARY_STRUCT(MMDSAMPLEHEADER, 21) // MMD0/MMD1 song header struct MMD0SONGHEADER { MMD0SAMPLE sample[63]; uint16be numblocks; // # of blocks uint16be songlen; // # of entries used in playseq uint8be playseq[256]; // Play sequence uint16be deftempo; // BPM tempo int8be playtransp; // Play transpose uint8be flags; // 0x10: Hex Volumes | 0x20: ST/NT/PT Slides | 0x40: 8 Channels song uint8be flags2; // [b4-b0]+1: Tempo LPB, 0x20: tempo mode, 0x80: mix_conv=on uint8be tempo2; // tempo TPL uint8be trkvol[16]; // track volumes uint8be mastervol; // master volume uint8be numsamples; // # of samples (max=63) }; MPT_BINARY_STRUCT(MMD0SONGHEADER, 788) // MMD2/MMD3 song header struct MMD2SONGHEADER { MMD0SAMPLE sample[63]; uint16be numblocks; // # of blocks uint16be numsections; // # of sections uint32be playseqtable; // filepos of play sequence uint32be sectiontable; // filepos of sections table (uint16_be array) uint32be trackvols; // filepos of tracks volume (uint8_be array) uint16be numtracks; // # of tracks (max 64) uint16be numpseqs; // # of play sequences uint32be trackpans; // filepos of tracks pan values (uint8_be array) int32be flags3; // 0x1:stereo_mix, 0x2:free_panning, 0x4:GM/XG compatibility uint16be voladj; // vol_adjust (set to 100 if 0) uint16be channels; // # of channels (4 if =0) uint8be mix_echotype; // 1:normal,2:xecho uint8be mix_echodepth; // 1..6 uint16be mix_echolen; // > 0 int8be mix_stereosep; // -4..4 uint8be pad0[223]; uint16be deftempo; // BPM tempo int8be playtransp; // play transpose uint8be flags; // 0x1:filteron, 0x2:jumpingon, 0x4:jump8th, 0x8:instr_attached, 0x10:hex_vol, 0x20:PT_slides, 0x40:8ch_conv,0x80:hq slows playing speed uint8be flags2; // 0x80:mix_conv=on, [b4-b0]+1:tempo LPB, 0x20:tempo_mode uint8be tempo2; // tempo TPL uint8be pad1[16]; uint8be mastervol; // master volume uint8be numsamples; // # of samples (max 63) }; MPT_BINARY_STRUCT(MMD2SONGHEADER, 788) // For MMD0 the note information is held in 3 bytes, byte0, byte1, byte2. For reference we // number the bits in each byte 0..7, where 0 is the low bit. // The note is held as bits 5..0 of byte0 // The instrument is encoded in 6 bits, bits 7 and 6 of byte0 and bits 7,6,5,4 of byte1 // The command number is bits 3,2,1,0 of byte1, command data is in byte2: // For command 0, byte2 represents the second data byte, otherwise byte2 // represents the first data byte. struct MMD0BLOCK { uint8be numtracks; uint8be lines; // File value is 1 less than actual, so 0 -> 1 line }; // uint8_be data[lines+1][tracks][3]; MPT_BINARY_STRUCT(MMD0BLOCK, 2) // For MMD1,MMD2,MMD3 the note information is carried in 4 bytes, byte0, byte1, // byte2 and byte3 // The note is held as byte0 (values above 0x84 are ignored) // The instrument is held as byte1 // The command number is held as byte2, command data is in byte3 // For commands 0 and 0x19 byte3 represents the second data byte, // otherwise byte2 represents the first data byte. struct MMD1BLOCK { uint16be numtracks; // Number of tracks, may be > 64, but then that data is skipped. uint16be lines; // Stored value is 1 less than actual, so 0 -> 1 line uint32be info; // Offset of BlockInfo (if 0, no block_info is present) }; MPT_BINARY_STRUCT(MMD1BLOCK, 8) struct MMD1BLOCKINFO { uint32be hlmask; // Unimplemented - ignore uint32be blockname; // file offset of block name uint32be blocknamelen; // length of block name (including term. 0) uint32be pagetable; // file offset of command page table uint32be cmdexttable; // file offset of command extension table uint32be reserved[4]; // future expansion }; MPT_BINARY_STRUCT(MMD1BLOCKINFO, 36) // A set of play sequences is stored as an array of uint32_be files offsets // Each offset points to the play sequence itself. struct MMD2PLAYSEQ { char name[32]; uint32be command_offs; // filepos of command table uint32be reserved; uint16be length; uint16be seq[512]; // skip if > 0x8000 }; MPT_BINARY_STRUCT(MMD2PLAYSEQ, 1066) // A command table contains commands that effect a particular play sequence // entry. The only commands read in are STOP or POSJUMP, all others are ignored // POSJUMP is presumed to have extra bytes containing a uint16 for the position struct MMDCOMMAND { uint16be offset; // Offset within current sequence entry uint8be cmdnumber; // STOP (537) or POSJUMP (538) (others skipped) uint8be extra_count; uint8be extra_bytes[4]; // [extra_count]; }; // Last entry has offset == 0xFFFF, cmd_number == 0 and 0 extrabytes MPT_BINARY_STRUCT(MMDCOMMAND, 8) struct MMD0EXP { uint32be nextmod; // File offset of next Hdr uint32be exp_smp; // Pointer to extra instrument data uint16be s_ext_entries; // Number of extra instrument entries uint16be s_ext_entrsz; // Size of extra instrument data uint32be annotxt; uint32be annolen; uint32be iinfo; // Instrument names uint16be i_ext_entries; uint16be i_ext_entrsz; uint32be jumpmask; uint32be rgbtable; uint8be channelsplit[4]; // Only used if 8ch_conv (extra channel for every nonzero entry) uint32be n_info; uint32be songname; // Song name uint32be songnamelen; uint32be dumps; uint32be mmdinfo; uint32be mmdrexx; uint32be mmdcmd3x; uint32be trackinfo_ofs; // ptr to song->numtracks ptrs to tag lists uint32be effectinfo_ofs; // ptr to group ptrs uint32be tag_end; }; MPT_BINARY_STRUCT(MMD0EXP, 80) static const uint8 bpmvals[9] = { 179,164,152,141,131,123,116,110,104}; static void MedConvert(ModCommand &p, const MMD0SONGHEADER *pmsh) { ModCommand::COMMAND command = p.command; uint32 param = p.param; switch(command) { case 0x00: if (param) command = CMD_ARPEGGIO; else command = CMD_NONE; break; case 0x01: command = CMD_PORTAMENTOUP; break; case 0x02: command = CMD_PORTAMENTODOWN; break; case 0x03: command = CMD_TONEPORTAMENTO; break; case 0x04: command = CMD_VIBRATO; break; case 0x05: command = CMD_TONEPORTAVOL; break; case 0x06: command = CMD_VIBRATOVOL; break; case 0x07: command = CMD_TREMOLO; break; case 0x0A: if (param & 0xF0) param &= 0xF0; command = CMD_VOLUMESLIDE; if (!param) command = CMD_NONE; break; case 0x0B: command = CMD_POSITIONJUMP; break; case 0x0C: command = CMD_VOLUME; if (pmsh->flags & MMD_FLAG_VOLHEX) { if (param < 0x80) { param = (param+1) / 2; } else command = CMD_NONE; } else { if (param <= 0x99) { param = (param >> 4)*10+((param & 0x0F) % 10); if (param > 64) param = 64; } else command = CMD_NONE; } break; case 0x09: command = static_cast((param <= 0x20) ? CMD_SPEED : CMD_TEMPO); break; case 0x0D: if (param & 0xF0) param &= 0xF0; command = CMD_VOLUMESLIDE; if (!param) command = CMD_NONE; break; case 0x0F: // Set Tempo / Special // F.00 = Pattern Break if (!param) command = CMD_PATTERNBREAK; else // F.01 - F.F0: Set tempo/speed if (param <= 0xF0) { if (pmsh->flags & MMD_FLAG_8CHANNEL) { param = (param == 0 || param >= 10) ? 99 : bpmvals[param-1]; } else // F.01 - F.0A: Set Speed if (param <= 0x0A) { command = CMD_SPEED; } else // Old tempo if (!(pmsh->flags2 & MMD_FLAG2_BPM)) { param = Util::muldiv(param, 5*715909, 2*474326); } // F.0B - F.F0: Set Tempo (assumes LPB=4) if (param > 0x0A) { command = CMD_TEMPO; if (param < 0x21) param = 0x21; if (param > 240) param = 240; } } else switch(param) { // F.F1: Retrig 2x case 0xF1: command = CMD_MODCMDEX; param = 0x93; break; // F.F2: Note Delay 2x case 0xF2: command = CMD_MODCMDEX; param = 0xD3; break; // F.F3: Retrig 3x case 0xF3: command = CMD_MODCMDEX; param = 0x92; break; // F.F4: Note Delay 1/3 case 0xF4: command = CMD_MODCMDEX; param = 0xD2; break; // F.F5: Note Delay 2/3 case 0xF5: command = CMD_MODCMDEX; param = 0xD4; break; // F.F8: Filter Off case 0xF8: command = CMD_MODCMDEX; param = 0x00; break; // F.F9: Filter On case 0xF9: command = CMD_MODCMDEX; param = 0x01; break; // F.FD: Very fast tone-portamento case 0xFD: command = CMD_TONEPORTAMENTO; param = 0xFF; break; // F.FE: End Song case 0xFE: command = CMD_SPEED; param = 0; break; // F.FF: Note Cut case 0xFF: command = CMD_MODCMDEX; param = 0xC0; break; default: #ifdef MED_LOG Log("Unknown Fxx command: cmd=0x%02X param=0x%02X\n", command, param); #endif command = CMD_NONE; param = 0; } break; // 11.0x: Fine Slide Up case 0x11: command = CMD_MODCMDEX; if (param > 0x0F) param = 0x0F; param |= 0x10; break; // 12.0x: Fine Slide Down case 0x12: command = CMD_MODCMDEX; if (param > 0x0F) param = 0x0F; param |= 0x20; break; // 14.xx: Vibrato case 0x14: command = CMD_VIBRATO; break; // 15.xx: FineTune case 0x15: command = CMD_MODCMDEX; param &= 0x0F; param |= 0x50; break; // 16.xx: Pattern Loop case 0x16: command = CMD_MODCMDEX; if (param > 0x0F) param = 0x0F; param |= 0x60; break; // 18.xx: Note Cut case 0x18: command = CMD_MODCMDEX; if (param > 0x0F) param = 0x0F; param |= 0xC0; break; // 19.xx: Sample Offset case 0x19: command = CMD_OFFSET; break; // 1A.0x: Fine Volume Up case 0x1A: command = CMD_MODCMDEX; if (param > 0x0F) param = 0x0F; param |= 0xA0; break; // 1B.0x: Fine Volume Down case 0x1B: command = CMD_MODCMDEX; if (param > 0x0F) param = 0x0F; param |= 0xB0; break; // 1D.xx: Pattern Break case 0x1D: command = CMD_PATTERNBREAK; break; // 1E.0x: Pattern Delay case 0x1E: command = CMD_MODCMDEX; if (param > 0x0F) param = 0x0F; param |= 0xE0; break; // 1F.xy: Retrig case 0x1F: command = CMD_RETRIG; param &= 0x0F; break; // 2E.xx: set panning case 0x2E: command = CMD_MODCMDEX; param = ((param + 0x10) & 0xFF) >> 1; if (param > 0x0F) param = 0x0F; param |= 0x80; break; default: #ifdef MED_LOG // 0x2E ? Log("Unknown command: cmd=0x%02X param=0x%02X\n", command, param); #endif command = CMD_NONE; param = 0; } p.command = command; p.param = static_cast(param); } static bool ValidateHeader(const MEDMODULEHEADER &pmmh) { if(std::memcmp(pmmh.id, "MMD", 3) || pmmh.id[3] < '0' || pmmh.id[3] > '3' || pmmh.song == 0 ) { return false; } return true; } static uint64 GetHeaderMinimumAdditionalSize(const MEDMODULEHEADER &pmmh) { MPT_UNREFERENCED_PARAMETER(pmmh); return sizeof(MMD0SONGHEADER); } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderMED(MemoryFileReader file, const uint64 *pfilesize) { MEDMODULEHEADER pmmh; if(!file.ReadStruct(pmmh)) { return ProbeWantMoreData; } if(!ValidateHeader(pmmh)) { return ProbeFailure; } return ProbeAdditionalSize(file, pfilesize, GetHeaderMinimumAdditionalSize(pmmh)); } bool CSoundFile::ReadMed(FileReader &file, ModLoadingFlags loadFlags) { file.Rewind(); MEDMODULEHEADER pmmh; if(!file.ReadStruct(pmmh)) { return false; } if(!ValidateHeader(pmmh)) { return false; } if(!file.CanRead(mpt::saturate_cast(GetHeaderMinimumAdditionalSize(pmmh)))) { return false; } const uint32 dwSong = pmmh.song; if(!file.LengthIsAtLeast(dwSong + sizeof(MMD0SONGHEADER))) { return false; } if(loadFlags == onlyVerifyHeader) { return true; } file.Rewind(); const FileReader::off_t dwMemLength = file.GetLength(); const uint8 *lpStream = file.GetRawData(); const MMD0SONGHEADER *pmsh; const MMD2SONGHEADER *pmsh2; const MMD0EXP *pmex; uint32 dwBlockArr, dwSmplArr, dwExpData; const_unaligned_ptr_be pdwTable; int8 version = pmmh.id[3]; uint32 deftempo; int playtransp = 0; InitializeGlobals(MOD_TYPE_MED); InitializeChannels(); // Setup channel pan positions and volume SetupMODPanning(true); m_madeWithTracker = mpt::format(MPT_USTRING("OctaMED (MMD%1)"))(mpt::ToUnicode(mpt::CharsetISO8859_1, std::string(1, version))); m_nSamplePreAmp = 32; dwBlockArr = pmmh.blockarr; dwSmplArr = pmmh.smplarr; dwExpData = pmmh.expdata; if ((dwExpData) && (dwExpData < dwMemLength - sizeof(MMD0EXP))) pmex = (const MMD0EXP *)(lpStream+dwExpData); else pmex = NULL; pmsh = (const MMD0SONGHEADER *)(lpStream + dwSong); pmsh2 = (const MMD2SONGHEADER *)pmsh; uint16 wNumBlocks = pmsh->numblocks; m_nChannels = 4; m_nSamples = pmsh->numsamples; if (m_nSamples > 63) m_nSamples = 63; // Tempo m_nDefaultTempo.Set(125); deftempo = pmsh->deftempo; if (!deftempo) deftempo = 125; if (pmsh->flags2 & MMD_FLAG2_BPM) { uint32 tempo_tpl = (pmsh->flags2 & MMD_FLAG2_BMASK) + 1; if (!tempo_tpl) tempo_tpl = 4; deftempo *= tempo_tpl; deftempo /= 4; #ifdef MED_LOG Log("newtempo: %3d bpm (bpm=%3d lpb=%2d)\n", deftempo, pmsh->deftempo, (pmsh->flags2 & MMD_FLAG2_BMASK)+1); #endif } else { if((pmsh->flags & MMD_FLAG_8CHANNEL) && deftempo > 0 && deftempo <= 9) deftempo = bpmvals[deftempo-1]; else deftempo = Util::muldiv(deftempo, 5 * 715909, 2 * 474326); #ifdef MED_LOG Log("oldtempo: %3d bpm (bpm=%3d)\n", deftempo, pmsh->deftempo); #endif } // Speed m_nDefaultSpeed = pmsh->tempo2; if (!m_nDefaultSpeed) m_nDefaultSpeed = 6; if (deftempo < 0x21) deftempo = 0x21; m_nDefaultTempo.Set(deftempo); // Reading Samples for (uint32 iSHdr=0; iSHdrsample[iSHdr].rep * 2u; sample.nLoopEnd = sample.nLoopStart + (pmsh->sample[iSHdr].replen * 2u); sample.nVolume = (pmsh->sample[iSHdr].svol << 2); sample.nGlobalVol = 64; if (sample.nVolume > 256) sample.nVolume = 256; // Was: sample.RelativeTone = -12 * pmsh->sample[iSHdr].strans; // But that breaks MMD1 modules (e.g. "94' summer.mmd1" from Modland) - "automatic terminated to.mmd0" still sounds broken, probably "play transpose" is broken there. sample.RelativeTone = pmsh->sample[iSHdr].strans; sample.nPan = 128; if (sample.nLoopEnd <= 2) sample.nLoopEnd = 0; if (sample.nLoopEnd) sample.uFlags.set(CHN_LOOP); } // Common Flags m_SongFlags.set(SONG_FASTVOLSLIDES, !(pmsh->flags & 0x20)); // Reading play sequence if (version < '2') { uint32 nbo = pmsh->songlen; if (!nbo) nbo = 1; ReadOrderFromArray(Order(), pmsh->playseq, nbo); playtransp = pmsh->playtransp; } else { uint32 nSections; ORDERINDEX nOrders = 0; uint16 nTrks = pmsh2->numtracks; if ((nTrks >= 4) && (nTrks <= 32)) m_nChannels = nTrks; uint32 playseqtable = pmsh2->playseqtable; uint32 numplayseqs = pmsh2->numpseqs; if (!numplayseqs) numplayseqs = 1; nSections = pmsh2->numsections; uint32 sectiontable = pmsh2->sectiontable; if ((!nSections) || (!sectiontable) || (sectiontable >= dwMemLength-2)) nSections = 1; nOrders = 0; Order().clear(); for (uint32 iSection=0; iSection= dwMemLength - sectiontable) { nplayseq = *const_unaligned_ptr_be(lpStream + sectiontable); sectiontable += 2; } else { nSections = 0; } uint32 pseq = 0; if ((playseqtable) && (playseqtable < dwMemLength) && (nplayseq * 4 <= dwMemLength - playseqtable)) { pseq = (const_unaligned_ptr_be(lpStream+playseqtable))[nplayseq]; } if (pseq && pseq < dwMemLength && sizeof(MMD2PLAYSEQ) <= dwMemLength - pseq) { const MMD2PLAYSEQ *pmps = (const MMD2PLAYSEQ *)(lpStream + pseq); if(m_songName.empty()) mpt::String::Read(m_songName, pmps->name); ORDERINDEX n = std::min(pmps->length, MAX_ORDERS - nOrders); if (n <= (dwMemLength - pseq + 42) / 2u && n < MPT_ARRAY_COUNT(pmps->seq)) { Order().resize(nOrders + n); for (uint32 i=0; iseq[i]; if (seqval < wNumBlocks) { Order()[nOrders++] = static_cast(seqval); } } } } } playtransp = pmsh2->playtransp; } // Reading Expansion structure if (pmex) { // Channel Split if ((m_nChannels == 4) && (pmsh->flags & MMD_FLAG_8CHANNEL)) { for (uint32 i8ch=0; i8ch<4; i8ch++) { if (pmex->channelsplit[i8ch]) m_nChannels++; } } // Song Comments (null-terminated) uint32 annotxt = pmex->annotxt; uint32 annolen = pmex->annolen; annolen = std::min(annolen, MED_MAX_COMMENT_LENGTH); //Thanks to Luigi Auriemma for pointing out an overflow risk if ((annotxt) && (annolen) && (annolen <= dwMemLength) && (annotxt <= dwMemLength - annolen) ) { m_songMessage.Read(lpStream + annotxt, annolen - 1, SongMessage::leAutodetect); } // Song Name uint32 songname = pmex->songname; uint32 songnamelen = pmex->songnamelen; if ((songname) && (songnamelen) && (songname <= dwMemLength) && (songnamelen <= dwMemLength-songname)) { mpt::String::Read(m_songName, lpStream + songname, songnamelen); } // Sample Names uint32 smpinfoex = pmex->iinfo; if (smpinfoex) { uint32 iinfoptr = pmex->iinfo; uint32 ientries = pmex->i_ext_entries; uint32 ientrysz = pmex->i_ext_entrsz; if ((iinfoptr) && (ientrysz < 256) && (ientries*ientrysz < dwMemLength) && (iinfoptr < dwMemLength - ientries*ientrysz)) { const char *psznames = (const char *)(lpStream + iinfoptr); for (uint32 i=0; i(m_szNames[i + 1], (psznames + i * ientrysz), ientrysz); } } } // Track Names uint32 trackinfo_ofs = pmex->trackinfo_ofs; if ((trackinfo_ofs) && (trackinfo_ofs < dwMemLength) && (m_nChannels * 4u < dwMemLength - trackinfo_ofs)) { const_unaligned_ptr_be ptrktags = const_unaligned_ptr_be(lpStream + trackinfo_ofs); for (uint32 i=0; i(lpStream + trktagofs); if (ntag == MMDTAG_END) break; uint32 tagdata = *const_unaligned_ptr_be(lpStream + trktagofs + 4); switch(ntag) { case MMDTAG_TRK_NAMELEN: trknamelen = tagdata; break; case MMDTAG_TRK_NAME: trknameofs = tagdata; break; } trktagofs += 8; } if ((trknameofs) && (trknameofs < dwMemLength - trknamelen) && trknamelen < dwMemLength) { mpt::String::Read(ChnSettings[i].szName, lpStream + trknameofs, trknamelen); } } } } } // Reading samples if (dwSmplArr > dwMemLength - 4*m_nSamples) return true; pdwTable = const_unaligned_ptr_be(lpStream + dwSmplArr); for (uint32 iSmp=0; iSmp= dwMemLength) || (dwPos + sizeof(MMDSAMPLEHEADER) >= dwMemLength)) continue; const MMDSAMPLEHEADER *psdh = (const MMDSAMPLEHEADER *)(lpStream + dwPos); uint32 len = psdh->length; #ifdef MED_LOG Log("SampleData %d: stype=0x%02X len=%d\n", iSmp, psdh->type, len); #endif if(dwPos + len + 6 > dwMemLength) len = 0; uint32 stype = psdh->type; const char *psdata = (const char *)(lpStream + dwPos + 6); SampleIO sampleIO( SampleIO::_8bit, SampleIO::mono, SampleIO::bigEndian, SampleIO::signedPCM); if (stype & 0x80) { psdata += (stype & 0x20) ? 14 : 6; } else { if(stype & 0x10) { sampleIO |= SampleIO::_16bit; len /= 2; } if(stype & 0x20) { sampleIO |= SampleIO::stereoSplit; len /= 2; } } Samples[iSmp + 1].nLength = len; if(loadFlags & loadSampleData) { FileReader chunk(mpt::byte_cast(mpt::as_span(psdata, dwMemLength - dwPos - 6))); sampleIO.ReadSample(Samples[iSmp + 1], chunk); } } // Reading patterns (blocks) if(!(loadFlags & loadPatternData)) { return true; } if (wNumBlocks > MAX_PATTERNS) wNumBlocks = MAX_PATTERNS; if ((!dwBlockArr) || (dwBlockArr > dwMemLength - 4u*wNumBlocks) || (4u*wNumBlocks > dwMemLength)) return true; pdwTable = const_unaligned_ptr_be(lpStream + dwBlockArr); playtransp += (version == '3') ? 24 : 48; Patterns.ResizeArray(wNumBlocks); for (PATTERNINDEX iBlk=0; iBlk= dwMemLength) || (dwPos >= dwMemLength - 8)) continue; uint32 lines = 64, tracks = 4; if (version == '0') { const MMD0BLOCK *pmb = (const MMD0BLOCK *)(lpStream + dwPos); lines = pmb->lines + 1; tracks = pmb->numtracks; if (!tracks) tracks = m_nChannels; if(!Patterns.Insert(iBlk, lines)) continue; auto p = Patterns[iBlk].begin(); const uint8 * s = (const uint8 *)(lpStream + dwPos + 2); uint32 maxlen = tracks*lines*3; if (maxlen + dwPos > dwMemLength - 2) break; for (uint32 y=0; y> 4; if (s[0] & 0x80) instr |= 0x10; if (s[0] & 0x40) instr |= 0x20; if ((note) && (note <= 132)) p->note = static_cast(note + playtransp); p->instr = instr; p->command = s[1] & 0x0F; p->param = s[2]; // if (!iBlk) Log("%02X.%02X.%02X | ", s[0], s[1], s[2]); MedConvert(*p, pmsh); p++; } //if (!iBlk) Log("\n"); } } else { const MMD1BLOCK *pmb = (const MMD1BLOCK *)(lpStream + dwPos); #ifdef MED_LOG Log("MMD1BLOCK: lines=%2d, tracks=%2d, offset=0x%04X\n", pmb->lines, pmb->numtracks, pmb->info); #endif const MMD1BLOCKINFO *pbi = NULL; const uint8 *pcmdext = NULL; lines = pmb->lines + 1; tracks = pmb->numtracks; if (!tracks) tracks = m_nChannels; Patterns.Insert(iBlk, lines); uint32 dwBlockInfo = pmb->info; if ((dwBlockInfo) && (dwBlockInfo < dwMemLength - sizeof(MMD1BLOCKINFO))) { pbi = (const MMD1BLOCKINFO *)(lpStream + dwBlockInfo); #ifdef MED_LOG Log(" BLOCKINFO: blockname=0x%04X namelen=%d pagetable=0x%04X &cmdexttable=0x%04X\n", pbi->blockname, pbi->blocknamelen, pbi->pagetable, pbi->cmdexttable); #endif if ((pbi->blockname) && (pbi->blocknamelen)) { uint32 nameofs = pbi->blockname; uint32 namelen = pbi->blocknamelen; if ((nameofs < dwMemLength) && (namelen < dwMemLength - nameofs)) { Patterns[iBlk].SetName((const char *)(lpStream + nameofs), namelen); } } if (pbi->cmdexttable) { uint32 cmdexttable = pbi->cmdexttable; if (cmdexttable < dwMemLength - 4) { cmdexttable = *const_unaligned_ptr_be(lpStream + cmdexttable); if ((cmdexttable) && (cmdexttable <= dwMemLength - lines*tracks)) { pcmdext = (const uint8 *)(lpStream + cmdexttable); } } } } const uint8 * s = (const uint8 *)(lpStream + dwPos + 8); uint32 maxlen = tracks*lines*4; if (maxlen + dwPos > dwMemLength - 8 || !Patterns.IsValidPat(iBlk)) break; auto p = Patterns[iBlk].begin(); for (uint32 y=0; y NOTE_MAX) rnote = NOTE_MAX; p->note = (uint8)rnote; } p->instr = s[1]; p->command = s[2]; p->param = s[3]; if (pcmdext) p->vol = pcmdext[x]; MedConvert(*p, pmsh); p++; } if (pcmdext) pcmdext += tracks; } } } return true; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/MPEGFrame.cpp0000644000372100037210000000643313161656666020332 00000000000000/* * MPEGFrame.cpp * ------------- * Purpose: Basic MPEG frame parsing functionality * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "MPEGFrame.h" #include "../common/FileReader.h" OPENMPT_NAMESPACE_BEGIN // Samples per frame - for each MPEG version and all three layers static const uint16 samplesPerFrame[2][3] = { { 384, 1152, 1152 }, // MPEG 1 { 384, 1152, 576 } // MPEG 2 / 2.5 }; // Bit rates for each MPEG version and all three layers static const uint16 bitRates[2][3][15] = { // MPEG 1 { { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448 }, // Layer 1 { 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 }, // Layer 2 { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 } // Layer 3 }, // MPEG 2 / 2.5 { { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256 }, // Layer 1 { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 }, // Layer 2 { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 } // Layer 3 } }; // Sampling rates for each MPEG version and all three layers static const uint16 samplingRates[4][3] = { { 11025, 12000, 8000 }, // MPEG 2.5 { 0, 0, 0 }, // Invalid { 22050, 24000, 16000 }, // MPEG 2 { 44100, 48000, 32000 } // MPEG 1 }; // Samples per Frame / 8 static const uint8 mpegCoefficients[2][3] = { { 12, 144, 144 }, // MPEG 1 { 12, 144, 72 } // MPEG 2 / 2.5 }; // Side info size = Offset in frame where Xing/Info magic starts static const uint8 sideInfoSize[2][2] = { { 17, 32 }, // MPEG 1 { 9, 17 } // MPEG 2 / 2.5 }; bool MPEGFrame::IsMPEGHeader(const uint8 (&header)[3]) { return header[0] == 0xFF && (header[1] & 0xE0) == 0xE0 // Sync && (header[1] & 0x18) != 0x08 // Invalid MPEG version && (header[1] & 0x06) != 0x00 // Invalid MPEG layer && (header[2] & 0x0C) != 0x0C // Invalid frequency && (header[2] & 0xF0) != 0xF0; // Invalid bitrate } MPEGFrame::MPEGFrame(FileReader &file) : frameSize(0) , numSamples(0) , isValid(false) , isLAME(false) { uint8 header[4]; file.ReadArray(header); if(!IsMPEGHeader(reinterpret_cast(header))) return; uint8 version = (header[1] & 0x18) >> 3; uint8 mpeg1 = (version == 3) ? 0 : 1; uint8 layer = 3 - ((header[1] & 0x06) >> 1); uint8 bitRate = (header[2] & 0xF0) >> 4; uint8 sampleRate = (header[2] & 0x0C) >> 2; uint8 padding = (header[2] & 0x02) >> 1; bool stereo = ((header[3] & 0xC0) >> 6) != 3; isValid = true; frameSize = (((mpegCoefficients[mpeg1][layer] * (bitRates[mpeg1][layer][bitRate] * 1000) / samplingRates[version][sampleRate]) + padding)) * (layer == 0 ? 4 : 1); numSamples = samplesPerFrame[mpeg1][layer]; if(stereo) numSamples *= 2u; uint32 lameOffset = sideInfoSize[mpeg1][stereo ? 1 : 0]; if(frameSize < lameOffset + 8) return; uint8 frame[36]; file.ReadStructPartial(frame, lameOffset + 4); // Don't check first two bytes, might be CRC for(uint32 i = 2; i < lameOffset; i++) { if(frame[i] != 0) return; } // This is all we really need to know for our purposes in the MO3 decoder. isLAME = !memcmp(frame + lameOffset, "Info", 4) || !memcmp(frame + lameOffset, "Xing", 4); } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Load_amf.cpp0000644000372100037210000003633113161656666020331 00000000000000/* * Load_amf.cpp * ------------ * Purpose: AMF module loader * Notes : There are two types of AMF files, the ASYLUM Music Format (used in Crusader: No Remorse and Crusader: No Regret) * and Advanced Music Format (DSMI / Digital Sound And Music Interface, used in various games such as Pinball World). * Both module types are handled here. * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" #include OPENMPT_NAMESPACE_BEGIN // ASYLUM AMF File Header struct AsylumFileHeader { char signature[32]; uint8 defaultSpeed; uint8 defaultTempo; uint8 numSamples; uint8 numPatterns; uint8 numOrders; uint8 restartPos; }; MPT_BINARY_STRUCT(AsylumFileHeader, 38) // ASYLUM AMF Sample Header struct AsylumSampleHeader { char name[22]; uint8le finetune; uint8le defaultVolume; int8le transpose; uint32le length; uint32le loopStart; uint32le loopLength; // Convert an AMF sample header to OpenMPT's internal sample header. void ConvertToMPT(ModSample &mptSmp) const { mptSmp.Initialize(); mptSmp.nFineTune = MOD2XMFineTune(finetune); mptSmp.nVolume = std::min(defaultVolume, 64) * 4u; mptSmp.RelativeTone = transpose; mptSmp.nLength = length; if(loopLength > 2 && loopStart + loopLength <= length) { mptSmp.uFlags.set(CHN_LOOP); mptSmp.nLoopStart = loopStart; mptSmp.nLoopEnd = loopStart + loopLength; } } }; MPT_BINARY_STRUCT(AsylumSampleHeader, 37) // DSMI AMF File Header struct AMFFileHeader { char amf[3]; uint8le version; char title[32]; uint8le numSamples; uint8le numOrders; uint16le numTracks; uint8le numChannels; }; MPT_BINARY_STRUCT(AMFFileHeader, 41) static bool ValidateHeader(const AsylumFileHeader &fileHeader) { if(std::memcmp(fileHeader.signature, "ASYLUM Music Format V1.0\0", 25) || fileHeader.numSamples > 64 ) { return false; } return true; } static uint64 GetHeaderMinimumAdditionalSize(const AsylumFileHeader &fileHeader) { return 256 + 64 * sizeof(AsylumSampleHeader) + 64 * 4 * 8 * fileHeader.numPatterns; } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderAMF_Asylum(MemoryFileReader file, const uint64 *pfilesize) { AsylumFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return ProbeWantMoreData; } if(!ValidateHeader(fileHeader)) { return ProbeFailure; } return ProbeAdditionalSize(file, pfilesize, GetHeaderMinimumAdditionalSize(fileHeader)); } bool CSoundFile::ReadAMF_Asylum(FileReader &file, ModLoadingFlags loadFlags) { file.Rewind(); AsylumFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return false; } if(!ValidateHeader(fileHeader)) { return false; } if(!file.CanRead(mpt::saturate_cast(GetHeaderMinimumAdditionalSize(fileHeader)))) { return false; } if(loadFlags == onlyVerifyHeader) { return true; } InitializeGlobals(MOD_TYPE_AMF0); InitializeChannels(); m_nChannels = 8; m_nDefaultSpeed = fileHeader.defaultSpeed; m_nDefaultTempo.Set(fileHeader.defaultTempo); m_nSamples = fileHeader.numSamples; if(fileHeader.restartPos < fileHeader.numOrders) { Order().SetRestartPos(fileHeader.restartPos); } m_songName.clear(); uint8 orders[256]; file.ReadArray(orders); ReadOrderFromArray(Order(), orders, fileHeader.numOrders); // Read Sample Headers for(SAMPLEINDEX smp = 1; smp <= GetNumSamples(); smp++) { AsylumSampleHeader sampleHeader; file.ReadStruct(sampleHeader); sampleHeader.ConvertToMPT(Samples[smp]); mpt::String::Read(m_szNames[smp], sampleHeader.name); } file.Skip((64 - fileHeader.numSamples) * sizeof(AsylumSampleHeader)); // Read Patterns Patterns.ResizeArray(fileHeader.numPatterns); for(PATTERNINDEX pat = 0; pat < fileHeader.numPatterns; pat++) { if(!(loadFlags & loadPatternData) || !Patterns.Insert(pat, 64)) { file.Skip(64 * 4 * 8); continue; } for(auto &m : Patterns[pat]) { uint8 data[4]; file.ReadArray(data); if(data[0] && data[0] + 12 + NOTE_MIN <= NOTE_MAX) { m.note = data[0] + 12 + NOTE_MIN; } m.instr = data[1]; m.command = data[2]; m.param = data[3]; ConvertModCommand(m); } } if(loadFlags & loadSampleData) { // Read Sample Data const SampleIO sampleIO( SampleIO::_8bit, SampleIO::mono, SampleIO::littleEndian, SampleIO::signedPCM); for(SAMPLEINDEX smp = 1; smp <= GetNumSamples(); smp++) { sampleIO.ReadSample(Samples[smp], file); } } return true; } // Read a single AMF track (channel) into a pattern. static void AMFReadPattern(CPattern &pattern, CHANNELINDEX chn, FileReader &fileChunk) { fileChunk.Rewind(); ModCommand::INSTR lastInstr = 0; while(fileChunk.CanRead(3)) { const uint8 row = fileChunk.ReadUint8(); const uint8 command = fileChunk.ReadUint8(); const uint8 value = fileChunk.ReadUint8(); if(row >= pattern.GetNumRows()) { break; } ModCommand &m = *pattern.GetpModCommand(row, chn); if(command < 0x7F) { // Note + Volume if(command == 0 && value == 0) { m.note = NOTE_NOTECUT; } else { m.note = command + NOTE_MIN; if(value != 0xFF) { if(!m.instr) m.instr = lastInstr; m.volcmd = VOLCMD_VOLUME; m.vol = value; } } } else if(command == 0x7F) { // Duplicate row int8 rowDelta = static_cast(value); int16 copyRow = static_cast(row) + rowDelta; if(copyRow >= 0 && copyRow < static_cast(pattern.GetNumRows())) { m = *pattern.GetpModCommand(copyRow, chn); } } else if(command == 0x80) { // Instrument m.instr = value + 1; lastInstr = m.instr; } else { // Effect static const ModCommand::COMMAND effTrans[] = { CMD_NONE, CMD_SPEED, CMD_VOLUMESLIDE, CMD_VOLUME, CMD_PORTAMENTOUP, CMD_NONE, CMD_TONEPORTAMENTO, CMD_TREMOR, CMD_ARPEGGIO, CMD_VIBRATO, CMD_TONEPORTAVOL, CMD_VIBRATOVOL, CMD_PATTERNBREAK, CMD_POSITIONJUMP, CMD_NONE, CMD_RETRIG, CMD_OFFSET, CMD_VOLUMESLIDE, CMD_PORTAMENTOUP, CMD_S3MCMDEX, CMD_S3MCMDEX, CMD_TEMPO, CMD_PORTAMENTOUP, CMD_PANNING8, }; uint8 cmd = (command & 0x7F); uint8 param = value; if(cmd < CountOf(effTrans)) { cmd = effTrans[cmd]; } else { cmd = CMD_NONE; } // Fix some commands... switch(command & 0x7F) { // 02: Volume Slide // 0A: Tone Porta + Vol Slide // 0B: Vibrato + Vol Slide case 0x02: case 0x0A: case 0x0B: if(param & 0x80) param = (-static_cast(param)) & 0x0F; else param = (param & 0x0F) << 4; break; // 03: Volume case 0x03: param = std::min(param, uint8(64)); if(m.volcmd == VOLCMD_NONE || m.volcmd == VOLCMD_VOLUME) { m.volcmd = VOLCMD_VOLUME; m.vol = param; cmd = CMD_NONE; } break; // 04: Porta Up/Down case 0x04: if(param & 0x80) param = (-static_cast(param)) & 0x7F; else cmd = CMD_PORTAMENTODOWN; break; // 11: Fine Volume Slide case 0x11: if(param) { if(param & 0x80) param = 0xF0 | ((-static_cast(param)) & 0x0F); else param = 0x0F | ((param & 0x0F) << 4); } else { cmd = CMD_NONE; } break; // 12: Fine Portamento // 16: Extra Fine Portamento case 0x12: case 0x16: if(param) { cmd = static_cast((param & 0x80) ? CMD_PORTAMENTOUP : CMD_PORTAMENTODOWN); if(param & 0x80) { param = ((-static_cast(param)) & 0x0F); } param |= (command == 0x16) ? 0xE0 : 0xF0; } else { cmd = CMD_NONE; } break; // 13: Note Delay case 0x13: param = 0xD0 | (param & 0x0F); break; // 14: Note Cut case 0x14: param = 0xC0 | (param & 0x0F); break; // 17: Panning case 0x17: param = (param + 64) & 0x7F; if(m.command != CMD_NONE) { if(m.volcmd == VOLCMD_NONE || m.volcmd == VOLCMD_PANNING) { m.volcmd = VOLCMD_PANNING; m.vol = param / 2; } cmd = CMD_NONE; } break; } if(cmd != CMD_NONE) { m.command = cmd; m.param = param; } } } } static bool ValidateHeader(const AMFFileHeader &fileHeader) { if(std::memcmp(fileHeader.amf, "AMF", 3) || fileHeader.version < 8 || fileHeader.version > 14 || ((fileHeader.numChannels < 1 || fileHeader.numChannels > 32) && fileHeader.version >= 10) ) { return false; } return true; } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderAMF_DSMI(MemoryFileReader file, const uint64 *pfilesize) { AMFFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return ProbeWantMoreData; } if(!ValidateHeader(fileHeader)) { return ProbeFailure; } MPT_UNREFERENCED_PARAMETER(pfilesize); return ProbeSuccess; } bool CSoundFile::ReadAMF_DSMI(FileReader &file, ModLoadingFlags loadFlags) { file.Rewind(); AMFFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return false; } if(!ValidateHeader(fileHeader)) { return false; } if(loadFlags == onlyVerifyHeader) { return true; } InitializeGlobals(MOD_TYPE_AMF); InitializeChannels(); m_nChannels = fileHeader.numChannels; m_nSamples = fileHeader.numSamples; mpt::String::Read(m_songName, fileHeader.title); if(fileHeader.version < 10) { // Old format revisions are fixed to 4 channels m_nChannels = 4; file.SkipBack(1); SetupMODPanning(true); } // Setup Channel Pan Positions if(fileHeader.version >= 11) { const CHANNELINDEX readChannels = fileHeader.version >= 12 ? 32 : 16; for(CHANNELINDEX chn = 0; chn < readChannels; chn++) { int16 pan = (file.ReadInt8() + 64) * 2; if(pan < 0) pan = 0; if(pan > 256) { pan = 128; ChnSettings[chn].dwFlags = CHN_SURROUND; } ChnSettings[chn].nPan = static_cast(pan); } } else if(fileHeader.version == 10) { uint8 panPos[16]; file.ReadArray(panPos); for(CHANNELINDEX chn = 0; chn < 16; chn++) { ChnSettings[chn].nPan = (panPos[chn] & 1) ? 0x40 : 0xC0; } } // To check: Was the channel table introduced in revision 1.0 or 0.9? I only have 0.8 files, in which it is missing... MPT_ASSERT(fileHeader.version != 9); // Get Tempo/Speed if(fileHeader.version >= 13) { uint8 tempo = file.ReadUint8(); if(tempo < 32) tempo = 125; m_nDefaultTempo.Set(tempo); m_nDefaultSpeed = file.ReadUint8(); } else { m_nDefaultTempo.Set(125); m_nDefaultSpeed = 6; } // Setup Order List Order().resize(fileHeader.numOrders); std::vector patternLength; const FileReader::off_t trackStartPos = file.GetPosition() + (fileHeader.version >= 14 ? 2 : 0); if(fileHeader.version >= 14) { patternLength.resize(fileHeader.numOrders); } for(ORDERINDEX ord = 0; ord < fileHeader.numOrders; ord++) { Order()[ord] = ord; if(fileHeader.version >= 14) { patternLength[ord] = file.ReadUint16LE(); } // Track positions will be read as needed. file.Skip(m_nChannels * 2); } // Read Sample Headers std::vector samplePos(GetNumSamples(), 0); uint32 maxSamplePos = 0; for(SAMPLEINDEX smp = 1; smp <= GetNumSamples(); smp++) { ModSample &sample = Samples[smp]; sample.Initialize(); uint8 type = file.ReadUint8(); file.ReadString(m_szNames[smp], 32); file.ReadString(sample.filename, 13); samplePos[smp - 1] = file.ReadUint32LE(); if(fileHeader.version < 10) { sample.nLength = file.ReadUint16LE(); } else { sample.nLength = file.ReadUint32LE(); } sample.nC5Speed = file.ReadUint16LE(); sample.nVolume = std::min(file.ReadUint8(), uint8(64)) * 4u; if(fileHeader.version < 10) { // Various sources (Miodrag Vallat's amf.txt, old ModPlug code) suggest that the loop information // format revision 1.0 should only consist of a 16-bit value for the loop start (loop end would // automatically equal sample length), but the only v1.0 files I have ("the tribal zone" and // "the way its gonna b" by Maelcum) do not confirm this - the sample headers are laid out exactly // as in the newer revisions in these two files. Even in format revision 0.8 (output by MOD2AMF v1.02) // There are loop start and loop end values (although they are 16-Bit). Maybe this only applies to // even older revision of the format? sample.nLoopStart = file.ReadUint16LE(); sample.nLoopEnd = file.ReadUint16LE(); } else { sample.nLoopStart = file.ReadUint32LE(); sample.nLoopEnd = file.ReadUint32LE(); } // Length of v1.0+ sample header: 65 bytes // Length of old sample header: 59 bytes if(type != 0) { if(sample.nLoopEnd > sample.nLoopStart + 2 && sample.nLoopEnd <= sample.nLength) { sample.uFlags.set(CHN_LOOP); } else { sample.nLoopStart = sample.nLoopEnd = 0; } maxSamplePos = std::max(maxSamplePos, samplePos[smp - 1]); } } // Read Track Mapping Table std::vector trackMap; if(!file.ReadVector(trackMap, fileHeader.numTracks)) { return false; } uint16 trackCount = 0; if(!trackMap.empty()) trackCount = *std::max_element(trackMap.cbegin(), trackMap.cend()); // Store Tracks Positions std::vector trackData(trackCount); for(uint16 i = 0; i < trackCount; i++) { // Track size is a 24-Bit value describing the number of byte triplets in this track. uint32 trackSize = file.ReadUint16LE() | (file.ReadUint8() << 16); trackData[i] = file.ReadChunk(trackSize * 3); } if(loadFlags & loadSampleData) { // Read Sample Data const SampleIO sampleIO( SampleIO::_8bit, SampleIO::mono, SampleIO::littleEndian, SampleIO::unsignedPCM); // Why is all of this sample loading business so weird in AMF? // Surely there must be some great idea behind it which isn't handled here or used in the wild // (re-using the same sample data for different sample slots maybe?) // First, try compacting the sample indices so that the loop won't have 2^32 iterations in the worst case. std::vector samplePosCompact = samplePos; std::sort(samplePosCompact.begin(), samplePosCompact.end()); auto end = std::unique(samplePosCompact.begin(), samplePosCompact.end()); for(auto pos = samplePosCompact.begin(); pos != end && file.CanRead(1); pos++) { for(SAMPLEINDEX smp = 0; smp < GetNumSamples() && file.CanRead(1); smp++) { if(*pos == samplePos[smp]) { sampleIO.ReadSample(Samples[smp + 1], file); break; } } } } if(!(loadFlags & loadPatternData)) { return true; } // Create the patterns from the list of tracks Patterns.ResizeArray(fileHeader.numOrders); for(PATTERNINDEX pat = 0; pat < fileHeader.numOrders; pat++) { uint16 patLength = pat < patternLength.size() ? patternLength[pat] : 64; if(!Patterns.Insert(pat, patLength)) { continue; } // Get table with per-channel track assignments file.Seek(trackStartPos + pat * (GetNumChannels() * 2 + (fileHeader.version >= 14 ? 2 : 0))); std::vector tracks; if(!file.ReadVector(tracks, GetNumChannels())) { continue; } for(CHANNELINDEX chn = 0; chn < GetNumChannels(); chn++) { if(tracks[chn] > 0 && tracks[chn] <= fileHeader.numTracks) { uint16 realTrack = trackMap[tracks[chn] - 1]; if(realTrack > 0 && realTrack <= trackCount) { realTrack--; AMFReadPattern(Patterns[pat], chn, trackData[realTrack]); } } } } return true; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/modcommand.h0000644000372100037210000002021613161656666020405 00000000000000/* * ModCommand.h * ------------ * Purpose: ModCommand declarations and helpers. One ModCommand corresponds to one pattern cell. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "Snd_defs.h" #include "../common/misc_util.h" OPENMPT_NAMESPACE_BEGIN class CSoundFile; // Note definitions #define NOTE_NONE (ModCommand::NOTE(0)) #define NOTE_MIN (ModCommand::NOTE(1)) #define NOTE_MAX (ModCommand::NOTE(120)) // Defines maximum notevalue(with index starting from 1) as well as maximum number of notes. #define NOTE_MIDDLEC (ModCommand::NOTE(5 * 12 + NOTE_MIN)) #define NOTE_KEYOFF (ModCommand::NOTE(0xFF)) // 255 #define NOTE_NOTECUT (ModCommand::NOTE(0xFE)) // 254 #define NOTE_FADE (ModCommand::NOTE(0xFD)) // 253, IT's action for illegal notes - DO NOT SAVE AS 253 as this is IT's internal representation of "no note"! #define NOTE_PC (ModCommand::NOTE(0xFC)) // 252, Param Control 'note'. Changes param value on first tick. #define NOTE_PCS (ModCommand::NOTE(0xFB)) // 251, Param Control (Smooth) 'note'. Interpolates param value during the whole row. #define NOTE_MAX_SPECIAL NOTE_KEYOFF #define NOTE_MIN_SPECIAL NOTE_PCS // Volume Column commands enum VolumeCommand : uint8 { VOLCMD_NONE = 0, VOLCMD_VOLUME = 1, VOLCMD_PANNING = 2, VOLCMD_VOLSLIDEUP = 3, VOLCMD_VOLSLIDEDOWN = 4, VOLCMD_FINEVOLUP = 5, VOLCMD_FINEVOLDOWN = 6, VOLCMD_VIBRATOSPEED = 7, VOLCMD_VIBRATODEPTH = 8, VOLCMD_PANSLIDELEFT = 9, VOLCMD_PANSLIDERIGHT = 10, VOLCMD_TONEPORTAMENTO = 11, VOLCMD_PORTAUP = 12, VOLCMD_PORTADOWN = 13, VOLCMD_DELAYCUT = 14, //currently unused VOLCMD_OFFSET = 15, MAX_VOLCMDS = 16 }; // Effect column commands enum EffectCommand : uint8 { CMD_NONE = 0, CMD_ARPEGGIO = 1, CMD_PORTAMENTOUP = 2, CMD_PORTAMENTODOWN = 3, CMD_TONEPORTAMENTO = 4, CMD_VIBRATO = 5, CMD_TONEPORTAVOL = 6, CMD_VIBRATOVOL = 7, CMD_TREMOLO = 8, CMD_PANNING8 = 9, CMD_OFFSET = 10, CMD_VOLUMESLIDE = 11, CMD_POSITIONJUMP = 12, CMD_VOLUME = 13, CMD_PATTERNBREAK = 14, CMD_RETRIG = 15, CMD_SPEED = 16, CMD_TEMPO = 17, CMD_TREMOR = 18, CMD_MODCMDEX = 19, CMD_S3MCMDEX = 20, CMD_CHANNELVOLUME = 21, CMD_CHANNELVOLSLIDE = 22, CMD_GLOBALVOLUME = 23, CMD_GLOBALVOLSLIDE = 24, CMD_KEYOFF = 25, CMD_FINEVIBRATO = 26, CMD_PANBRELLO = 27, CMD_XFINEPORTAUPDOWN = 28, CMD_PANNINGSLIDE = 29, CMD_SETENVPOSITION = 30, CMD_MIDI = 31, CMD_SMOOTHMIDI = 32, CMD_DELAYCUT = 33, CMD_XPARAM = 34, CMD_NOTESLIDEUP = 35, // IMF Gxy / PTM Jxy (Slide y notes up every x ticks) CMD_NOTESLIDEDOWN = 36, // IMF Hxy / PTM Kxy (Slide y notes down every x ticks) CMD_NOTESLIDEUPRETRIG = 37, // PTM Lxy (Slide y notes up every x ticks + retrigger note) CMD_NOTESLIDEDOWNRETRIG = 38, // PTM Mxy (Slide y notes down every x ticks + retrigger note) CMD_REVERSEOFFSET = 39, // PTM Nxx Revert sample + offset CMD_DBMECHO = 40, // DBM enable/disable echo CMD_OFFSETPERCENTAGE = 41, // PLM Percentage Offset MAX_EFFECTS = 42 }; enum EffectType : uint8 { EFFECT_TYPE_NORMAL = 0, EFFECT_TYPE_GLOBAL = 1, EFFECT_TYPE_VOLUME = 2, EFFECT_TYPE_PANNING = 3, EFFECT_TYPE_PITCH = 4, MAX_EFFECT_TYPE = 5 }; class ModCommand { public: typedef uint8 NOTE; typedef uint8 INSTR; typedef uint8 VOL; typedef uint8 VOLCMD; typedef uint8 COMMAND; typedef uint8 PARAM; // Defines the maximum value for column data when interpreted as 2-byte value // (for example volcmd and vol). The valid value range is [0, maxColumnValue]. static const int maxColumnValue = 999; // Returns empty modcommand. static ModCommand Empty() { ModCommand m = { 0, 0, VOLCMD_NONE, CMD_NONE, 0, 0 }; return m; } bool operator==(const ModCommand& mc) const { return (note == mc.note) && (instr == mc.instr) && (volcmd == mc.volcmd) && (command == mc.command) && ((volcmd == VOLCMD_NONE && !IsPcNote()) || vol == mc.vol) && ((command == CMD_NONE && !IsPcNote()) || param == mc.param); } bool operator!=(const ModCommand& mc) const { return !(*this == mc); } void Set(NOTE n, INSTR ins, uint16 volcol, uint16 effectcol) { note = n; instr = ins; SetValueVolCol(volcol); SetValueEffectCol(effectcol); } uint16 GetValueVolCol() const { return GetValueVolCol(volcmd, vol); } static uint16 GetValueVolCol(uint8 volcmd, uint8 vol) { return (volcmd << 8) + vol; } void SetValueVolCol(const uint16 val) { volcmd = static_cast(val >> 8); vol = static_cast(val & 0xFF); } uint16 GetValueEffectCol() const { return GetValueEffectCol(command, param); } static uint16 GetValueEffectCol(uint8 command, uint8 param) { return (command << 8) + param; } void SetValueEffectCol(const uint16 val) { command = static_cast(val >> 8); param = static_cast(val & 0xFF); } // Clears modcommand. void Clear() { memset(this, 0, sizeof(ModCommand)); } // Returns true if modcommand is empty, false otherwise. bool IsEmpty() const { return (note == NOTE_NONE && instr == 0 && volcmd == VOLCMD_NONE && command == CMD_NONE); } // Returns true if instrument column represents plugin index. bool IsInstrPlug() const { return IsPcNote(); } // Returns true if and only if note is NOTE_PC or NOTE_PCS. bool IsPcNote() const { return note == NOTE_PC || note == NOTE_PCS; } static bool IsPcNote(const NOTE note_id) { return note_id == NOTE_PC || note_id == NOTE_PCS; } // Returns true if and only if note is a valid musical note. bool IsNote() const { return IsInRange(note, NOTE_MIN, NOTE_MAX); } static bool IsNote(NOTE note) { return IsInRange(note, NOTE_MIN, NOTE_MAX); } // Returns true if and only if note is a valid special note. bool IsSpecialNote() const { return IsInRange(note, NOTE_MIN_SPECIAL, NOTE_MAX_SPECIAL); } static bool IsSpecialNote(NOTE note) { return IsInRange(note, NOTE_MIN_SPECIAL, NOTE_MAX_SPECIAL); } // Returns true if and only if note is a valid musical note or the note entry is empty. bool IsNoteOrEmpty() const { return note == NOTE_NONE || IsNote(); } static bool IsNoteOrEmpty(NOTE note) { return note == NOTE_NONE || IsNote(note); } // Returns true if any of the commands in this cell trigger a tone portamento. bool IsPortamento() const { return command == CMD_TONEPORTAMENTO || command == CMD_TONEPORTAVOL || volcmd == VOLCMD_TONEPORTAMENTO; } // Returns true if the cell contains an effect command that may affect the global state of the module. bool IsGlobalCommand() const; // Returns true if the note is inside the Amiga frequency range bool IsAmigaNote() const { return IsAmigaNote(note); } static bool IsAmigaNote(NOTE note) { return !IsNote(note) || (note >= NOTE_MIDDLEC - 12 && note < NOTE_MIDDLEC + 24); } static EffectType GetEffectType(COMMAND cmd); EffectType GetEffectType() const { return GetEffectType(command); } static EffectType GetVolumeEffectType(VOLCMD volcmd); EffectType GetVolumeEffectType() const { return GetVolumeEffectType(volcmd); } // Convert a complete ModCommand item from one format to another void Convert(MODTYPE fromType, MODTYPE toType, const CSoundFile &sndFile); // Convert MOD/XM Exx to S3M/IT Sxx void ExtendedMODtoS3MEffect(); // Convert S3M/IT Sxx to MOD/XM Exx void ExtendedS3MtoMODEffect(); // "Importance" of every FX command. Table is used for importing from formats with multiple effect columns // and is approximately the same as in SchismTracker. static size_t GetEffectWeight(COMMAND cmd); // Try to convert a an effect into a volume column effect. Returns true on success. static bool ConvertVolEffect(uint8 &effect, uint8 ¶m, bool force); // Takes two "normal" effect commands and converts them to volume column + effect column commands. Returns true on success, false (if one effect was lost) otherwise. static bool TwoRegularCommandsToMPT(uint8 &effect1, uint8 ¶m1, uint8 &effect2, uint8 ¶m2); // Try to combine two commands into one. Returns true on success and the combined command is placed in eff1 / param1. static bool CombineEffects(uint8 &eff1, uint8 ¶m1, uint8 &eff2, uint8 ¶m2); public: uint8 note; uint8 instr; uint8 volcmd; uint8 command; uint8 vol; uint8 param; }; OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Dlsbank.cpp0000644000372100037210000015624013161656666020207 00000000000000/* * DLSBank.cpp * ----------- * Purpose: Sound bank loading. * Notes : Supported sound bank types: DLS (including embedded DLS in MSS & RMI), SF2 * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Sndfile.h" #ifdef MODPLUG_TRACKER #include "../mptrack/mptrack.h" #include "../common/mptFileIO.h" #endif #include "Dlsbank.h" #include "../common/StringFixer.h" #include "../common/FileReader.h" #include "../common/Endianness.h" #include "SampleIO.h" #include "modsmp_ctrl.h" #include OPENMPT_NAMESPACE_BEGIN #ifdef MODPLUG_TRACKER //#define DLSBANK_LOG //#define DLSINSTR_LOG #define F_RGN_OPTION_SELFNONEXCLUSIVE 0x0001 /////////////////////////////////////////////////////////////////////////// // Articulation connection graph definitions // Generic Sources #define CONN_SRC_NONE 0x0000 #define CONN_SRC_LFO 0x0001 #define CONN_SRC_KEYONVELOCITY 0x0002 #define CONN_SRC_KEYNUMBER 0x0003 #define CONN_SRC_EG1 0x0004 #define CONN_SRC_EG2 0x0005 #define CONN_SRC_PITCHWHEEL 0x0006 #define CONN_SRC_POLYPRESSURE 0x0007 #define CONN_SRC_CHANNELPRESSURE 0x0008 #define CONN_SRC_VIBRATO 0x0009 // Midi Controllers 0-127 #define CONN_SRC_CC1 0x0081 #define CONN_SRC_CC7 0x0087 #define CONN_SRC_CC10 0x008a #define CONN_SRC_CC11 0x008b #define CONN_SRC_CC91 0x00db #define CONN_SRC_CC93 0x00dd #define CONN_SRC_RPN0 0x0100 #define CONN_SRC_RPN1 0x0101 #define CONN_SRC_RPN2 0x0102 // Generic Destinations #define CONN_DST_NONE 0x0000 #define CONN_DST_ATTENUATION 0x0001 #define CONN_DST_RESERVED 0x0002 #define CONN_DST_PITCH 0x0003 #define CONN_DST_PAN 0x0004 // LFO Destinations #define CONN_DST_LFO_FREQUENCY 0x0104 #define CONN_DST_LFO_STARTDELAY 0x0105 #define CONN_DST_KEYNUMBER 0x0005 // EG1 Destinations #define CONN_DST_EG1_ATTACKTIME 0x0206 #define CONN_DST_EG1_DECAYTIME 0x0207 #define CONN_DST_EG1_RESERVED 0x0208 #define CONN_DST_EG1_RELEASETIME 0x0209 #define CONN_DST_EG1_SUSTAINLEVEL 0x020a #define CONN_DST_EG1_DELAYTIME 0x020b #define CONN_DST_EG1_HOLDTIME 0x020c #define CONN_DST_EG1_SHUTDOWNTIME 0x020d // EG2 Destinations #define CONN_DST_EG2_ATTACKTIME 0x030a #define CONN_DST_EG2_DECAYTIME 0x030b #define CONN_DST_EG2_RESERVED 0x030c #define CONN_DST_EG2_RELEASETIME 0x030d #define CONN_DST_EG2_SUSTAINLEVEL 0x030e #define CONN_DST_EG2_DELAYTIME 0x030f #define CONN_DST_EG2_HOLDTIME 0x0310 #define CONN_TRN_NONE 0x0000 #define CONN_TRN_CONCAVE 0x0001 ////////////////////////////////////////////////////////// // Supported DLS1 Articulations #define MAKE_ART(src, ctl, dst) ( ((dst)<<16) | ((ctl)<<8) | (src) ) // Vibrato / Tremolo #define ART_LFO_FREQUENCY MAKE_ART (CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_LFO_FREQUENCY) #define ART_LFO_STARTDELAY MAKE_ART (CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_LFO_STARTDELAY) #define ART_LFO_ATTENUATION MAKE_ART (CONN_SRC_LFO, CONN_SRC_NONE, CONN_DST_ATTENUATION) #define ART_LFO_PITCH MAKE_ART (CONN_SRC_LFO, CONN_SRC_NONE, CONN_DST_PITCH) #define ART_LFO_MODWTOATTN MAKE_ART (CONN_SRC_LFO, CONN_SRC_CC1, CONN_DST_ATTENUATION) #define ART_LFO_MODWTOPITCH MAKE_ART (CONN_SRC_LFO, CONN_SRC_CC1, CONN_DST_PITCH) // Volume Envelope #define ART_VOL_EG_ATTACKTIME MAKE_ART(CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_ATTACKTIME) #define ART_VOL_EG_DECAYTIME MAKE_ART(CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_DECAYTIME) #define ART_VOL_EG_SUSTAINLEVEL MAKE_ART(CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_SUSTAINLEVEL) #define ART_VOL_EG_RELEASETIME MAKE_ART(CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_RELEASETIME) #define ART_VOL_EG_DELAYTIME MAKE_ART(CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_DELAYTIME) #define ART_VOL_EG_HOLDTIME MAKE_ART(CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_HOLDTIME) #define ART_VOL_EG_SHUTDOWNTIME MAKE_ART(CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_SHUTDOWNTIME) #define ART_VOL_EG_VELTOATTACK MAKE_ART(CONN_SRC_KEYONVELOCITY, CONN_SRC_NONE, CONN_DST_EG1_ATTACKTIME) #define ART_VOL_EG_KEYTODECAY MAKE_ART(CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_EG1_DECAYTIME) // Pitch Envelope #define ART_PITCH_EG_ATTACKTIME MAKE_ART(CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_ATTACKTIME) #define ART_PITCH_EG_DECAYTIME MAKE_ART(CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_DECAYTIME) #define ART_PITCH_EG_SUSTAINLEVEL MAKE_ART(CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_SUSTAINLEVEL) #define ART_PITCH_EG_RELEASETIME MAKE_ART(CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_RELEASETIME) #define ART_PITCH_EG_VELTOATTACK MAKE_ART(CONN_SRC_KEYONVELOCITY, CONN_SRC_NONE, CONN_DST_EG2_ATTACKTIME) #define ART_PITCH_EG_KEYTODECAY MAKE_ART(CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_EG2_DECAYTIME) // Default Pan #define ART_DEFAULTPAN MAKE_ART (CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_PAN) ////////////////////////////////////////////////////////// // DLS IFF Chunk IDs // Standard IFF chunks IDs #define IFFID_FORM 0x4d524f46 #define IFFID_RIFF 0x46464952 #define IFFID_LIST 0x5453494C #define IFFID_INFO 0x4F464E49 // IFF Info fields #define IFFID_ICOP 0x504F4349 #define IFFID_INAM 0x4D414E49 #define IFFID_ICMT 0x544D4349 #define IFFID_IENG 0x474E4549 #define IFFID_ISFT 0x54465349 #define IFFID_ISBJ 0x4A425349 // Wave IFF chunks IDs #define IFFID_wave 0x65766177 #define IFFID_wsmp 0x706D7377 #define IFFID_XDLS 0x534c4458 #define IFFID_DLS 0x20534C44 #define IFFID_MLS 0x20534C4D #define IFFID_RMID 0x44494D52 #define IFFID_colh 0x686C6F63 #define IFFID_ins 0x20736E69 #define IFFID_insh 0x68736E69 #define IFFID_ptbl 0x6C627470 #define IFFID_wvpl 0x6C707677 #define IFFID_rgn 0x206E6772 #define IFFID_rgn2 0x326E6772 #define IFFID_rgnh 0x686E6772 #define IFFID_wlnk 0x6B6E6C77 #define IFFID_art1 0x31747261 #define IFFID_art2 0x32747261 ////////////////////////////////////////////////////////// // DLS Structures definitions struct IFFCHUNK { uint32le id; uint32le len; }; MPT_BINARY_STRUCT(IFFCHUNK, 8) struct RIFFCHUNKID { uint32le id_RIFF; uint32le riff_len; uint32le id_DLS; }; MPT_BINARY_STRUCT(RIFFCHUNKID, 12) struct LISTCHUNK { uint32le id; uint32le len; uint32le listid; }; MPT_BINARY_STRUCT(LISTCHUNK, 12) struct DLSRGNRANGE { uint16le usLow; uint16le usHigh; }; MPT_BINARY_STRUCT(DLSRGNRANGE, 4) struct VERSCHUNK { uint32le id; uint32le len; uint16le version[4]; }; MPT_BINARY_STRUCT(VERSCHUNK, 16) struct PTBLCHUNK { uint32le cbSize; uint32le cCues; }; MPT_BINARY_STRUCT(PTBLCHUNK, 8) struct INSHCHUNK { uint32le id; uint32le len; uint32le cRegions; uint32le ulBank; uint32le ulInstrument; }; MPT_BINARY_STRUCT(INSHCHUNK, 20) struct RGNHCHUNK { uint32le id; uint32le len; DLSRGNRANGE RangeKey; DLSRGNRANGE RangeVelocity; uint16le fusOptions; uint16le usKeyGroup; }; MPT_BINARY_STRUCT(RGNHCHUNK, 20) struct WLNKCHUNK { uint32le id; uint32le len; uint16le fusOptions; uint16le usPhaseGroup; uint32le ulChannel; uint32le ulTableIndex; }; MPT_BINARY_STRUCT(WLNKCHUNK, 20) struct ART1CHUNK { uint32le id; uint32le len; uint32le cbSize; uint32le cConnectionBlocks; }; MPT_BINARY_STRUCT(ART1CHUNK, 16) struct CONNECTIONBLOCK { uint16le usSource; uint16le usControl; uint16le usDestination; uint16le usTransform; int32le lScale; }; MPT_BINARY_STRUCT(CONNECTIONBLOCK, 12) struct WSMPCHUNK { uint32le id; uint32le len; uint32le cbSize; uint16le usUnityNote; int16le sFineTune; int32le lAttenuation; uint32le fulOptions; uint32le cSampleLoops; }; MPT_BINARY_STRUCT(WSMPCHUNK, 28) struct WSMPSAMPLELOOP { uint32le cbSize; uint32le ulLoopType; uint32le ulLoopStart; uint32le ulLoopLength; }; MPT_BINARY_STRUCT(WSMPSAMPLELOOP, 16) ///////////////////////////////////////////////////////////////////// // SF2 IFF Chunk IDs #define IFFID_sfbk 0x6b626673 #define IFFID_sdta 0x61746473 #define IFFID_pdta 0x61746470 #define IFFID_phdr 0x72646870 #define IFFID_pbag 0x67616270 #define IFFID_pgen 0x6E656770 #define IFFID_inst 0x74736E69 #define IFFID_ibag 0x67616269 #define IFFID_igen 0x6E656769 #define IFFID_shdr 0x72646873 /////////////////////////////////////////// // SF2 Generators IDs enum SF2Generators { SF2_GEN_MODENVTOFILTERFC = 11, SF2_GEN_PAN = 17, SF2_GEN_DECAYMODENV = 28, SF2_GEN_ATTACKVOLENV = 34, SF2_GEN_HOLDVOLENV = 34, SF2_GEN_DECAYVOLENV = 36, SF2_GEN_SUSTAINVOLENV = 37, SF2_GEN_RELEASEVOLENV = 38, SF2_GEN_INSTRUMENT = 41, SF2_GEN_KEYRANGE = 43, SF2_GEN_ATTENUATION = 48, SF2_GEN_COARSETUNE = 51, SF2_GEN_FINETUNE = 52, SF2_GEN_SAMPLEID = 53, SF2_GEN_SAMPLEMODES = 54, SF2_GEN_KEYGROUP = 57, SF2_GEN_UNITYNOTE = 58, }; ///////////////////////////////////////////////////////////////////// // SF2 Structures Definitions struct SFPRESETHEADER { char achPresetName[20]; uint16le wPreset; uint16le wBank; uint16le wPresetBagNdx; uint32le dwLibrary; uint32le dwGenre; uint32le dwMorphology; }; MPT_BINARY_STRUCT(SFPRESETHEADER, 38) struct SFPRESETBAG { uint16le wGenNdx; uint16le wModNdx; }; MPT_BINARY_STRUCT(SFPRESETBAG, 4) struct SFGENLIST { uint16le sfGenOper; uint16le genAmount; }; MPT_BINARY_STRUCT(SFGENLIST, 4) struct SFINST { char achInstName[20]; uint16le wInstBagNdx; }; MPT_BINARY_STRUCT(SFINST, 22) struct SFINSTBAG { uint16le wGenNdx; uint16le wModNdx; }; MPT_BINARY_STRUCT(SFINSTBAG, 4) struct SFINSTGENLIST { uint16le sfGenOper; uint16le genAmount; }; MPT_BINARY_STRUCT(SFINSTGENLIST, 4) struct SFSAMPLE { char achSampleName[20]; uint32le dwStart; uint32le dwEnd; uint32le dwStartloop; uint32le dwEndloop; uint32le dwSampleRate; uint8le byOriginalPitch; int8le chPitchCorrection; uint16le wSampleLink; uint16le sfSampleType; }; MPT_BINARY_STRUCT(SFSAMPLE, 46) // End of structures definitions ///////////////////////////////////////////////////////////////////// struct SF2LOADERINFO { uint32 nPresetBags; const SFPRESETBAG *pPresetBags; uint32 nPresetGens; const SFGENLIST *pPresetGens; uint32 nInsts; const SFINST *pInsts; uint32 nInstBags; const SFINSTBAG *pInstBags; uint32 nInstGens; const SFINSTGENLIST *pInstGens; }; ///////////////////////////////////////////////////////////////////// // Unit conversion static uint8 DLSSustainLevelToLinear(int32 sustain) { // 0.1% units if(sustain >= 0) { int32 l = sustain / (1000 * 512); if(l >= 0 || l <= 128) return static_cast(l); } return 128; } static uint8 SF2SustainLevelToLinear(int32 sustain) { // 0.1% units int32 l = 128 * (1000 - Clamp(sustain, 0, 1000)) / 1000; return static_cast(l); } int32 CDLSBank::DLS32BitTimeCentsToMilliseconds(int32 lTimeCents) { // tc = log2(time[secs]) * 1200*65536 // time[secs] = 2^(tc/(1200*65536)) if ((uint32)lTimeCents == 0x80000000) return 0; double fmsecs = 1000.0 * pow(2.0, ((double)lTimeCents)/(1200.0*65536.0)); if (fmsecs < -32767) return -32767; if (fmsecs > 32767) return 32767; return (int32)fmsecs; } // 0dB = 0x10000 int32 CDLSBank::DLS32BitRelativeGainToLinear(int32 lCentibels) { // v = 10^(cb/(200*65536)) * V return (int32)(65536.0 * pow(10.0, ((double)lCentibels)/(200*65536.0)) ); } int32 CDLSBank::DLS32BitRelativeLinearToGain(int32 lGain) { // cb = log10(v/V) * 200 * 65536 if (lGain <= 0) return -960 * 65536; return (int32)( 200*65536.0 * log10( ((double)lGain)/65536.0 ) ); } int32 CDLSBank::DLSMidiVolumeToLinear(uint32 nMidiVolume) { return (nMidiVolume * nMidiVolume << 16) / (127*127); } ///////////////////////////////////////////////////////////////////// // Implementation CDLSBank::CDLSBank() { m_nMaxWaveLink = 0; m_nType = SOUNDBANK_TYPE_INVALID; } bool CDLSBank::IsDLSBank(const mpt::PathString &filename) { RIFFCHUNKID riff; FILE *f; if(filename.empty()) return false; if((f = mpt_fopen(filename, "rb")) == nullptr) return false; MemsetZero(riff); fread(&riff, sizeof(RIFFCHUNKID), 1, f); // Check for embedded DLS sections if (riff.id_RIFF == IFFID_FORM) { // Miles Sound System do { uint32 len = riff.riff_len; len = SwapBytesBE(len); if (len <= 4) break; if (riff.id_DLS == IFFID_XDLS) { fread(&riff, sizeof(RIFFCHUNKID), 1, f); break; } if((len % 2u) != 0) len++; if (fseek(f, len-4, SEEK_CUR) != 0) break; } while (fread(&riff, sizeof(RIFFCHUNKID), 1, f) != 0); } else if ((riff.id_RIFF == IFFID_RIFF) && (riff.id_DLS == IFFID_RMID)) { for (;;) { if(!fread(&riff, sizeof(RIFFCHUNKID), 1, f)) break; if (riff.id_DLS == IFFID_DLS) break; // found it int len = riff.riff_len; if((len % 2u) != 0) len++; if ((len <= 4) || (fseek(f, len-4, SEEK_CUR) != 0)) break; } } fclose(f); return ((riff.id_RIFF == IFFID_RIFF) && ((riff.id_DLS == IFFID_DLS) || (riff.id_DLS == IFFID_MLS) || (riff.id_DLS == IFFID_sfbk)) && (riff.riff_len >= 256)); } /////////////////////////////////////////////////////////////// // Find an instrument based on the given parameters DLSINSTRUMENT *CDLSBank::FindInstrument(bool bDrum, uint32 nBank, uint32 dwProgram, uint32 dwKey, uint32 *pInsNo) { if (m_Instruments.empty()) return NULL; for (uint32 iIns=0; iInsulBank & 0x7F00) >> 1) | (pDlsIns->ulBank & 0x7F); if ((nBank >= 0x4000) || (insbank == nBank)) { if (bDrum) { if (pDlsIns->ulBank & F_INSTRUMENT_DRUMS) { if ((dwProgram >= 0x80) || (dwProgram == (pDlsIns->ulInstrument & 0x7F))) { for (uint32 iRgn=0; iRgnnRegions; iRgn++) { if ((!dwKey) || (dwKey >= 0x80) || ((dwKey >= pDlsIns->Regions[iRgn].uKeyMin) && (dwKey <= pDlsIns->Regions[iRgn].uKeyMax))) { if (pInsNo) *pInsNo = iIns; return pDlsIns; } } } } } else { if (!(pDlsIns->ulBank & F_INSTRUMENT_DRUMS)) { if ((dwProgram >= 0x80) || (dwProgram == (pDlsIns->ulInstrument & 0x7F))) { if (pInsNo) *pInsNo = iIns; return pDlsIns; } } } } } return NULL; } /////////////////////////////////////////////////////////////// // Update DLS instrument definition from an IFF chunk bool CDLSBank::UpdateInstrumentDefinition(DLSINSTRUMENT *pDlsIns, const IFFCHUNK *pchunk, uint32 dwMaxLen) { if ((!pchunk->len) || (pchunk->len+8 > dwMaxLen)) return false; if (pchunk->id == IFFID_LIST) { LISTCHUNK *plist = (LISTCHUNK *)pchunk; uint32 dwPos = 12; while (dwPos < plist->len) { const IFFCHUNK *p = (const IFFCHUNK *)(((uint8 *)plist) + dwPos); if (!(p->id & 0xFF)) { p = (const IFFCHUNK *)( ((uint8 *)p)+1 ); dwPos++; } if (dwPos + p->len + 8 <= plist->len + 12) { UpdateInstrumentDefinition(pDlsIns, p, p->len+8); } dwPos += p->len + 8; } switch(plist->listid) { case IFFID_rgn: // Level 1 region case IFFID_rgn2: // Level 2 region if (pDlsIns->nRegions < DLSMAXREGIONS) pDlsIns->nRegions++; break; } } else { switch(pchunk->id) { case IFFID_insh: pDlsIns->ulBank = ((INSHCHUNK *)pchunk)->ulBank; pDlsIns->ulInstrument = ((INSHCHUNK *)pchunk)->ulInstrument; //Log("%3d regions, bank 0x%04X instrument %3d\n", ((INSHCHUNK *)pchunk)->cRegions, pDlsIns->ulBank, pDlsIns->ulInstrument); break; case IFFID_rgnh: if (pDlsIns->nRegions < DLSMAXREGIONS) { RGNHCHUNK *p = (RGNHCHUNK *)pchunk; DLSREGION *pregion = &pDlsIns->Regions[pDlsIns->nRegions]; pregion->uKeyMin = (uint8)p->RangeKey.usLow; pregion->uKeyMax = (uint8)p->RangeKey.usHigh; pregion->fuOptions = (uint8)(p->usKeyGroup & DLSREGION_KEYGROUPMASK); if (p->fusOptions & F_RGN_OPTION_SELFNONEXCLUSIVE) pregion->fuOptions |= DLSREGION_SELFNONEXCLUSIVE; //Log(" Region %d: fusOptions=0x%02X usKeyGroup=0x%04X ", pDlsIns->nRegions, p->fusOptions, p->usKeyGroup); //Log("KeyRange[%3d,%3d] ", p->RangeKey.usLow, p->RangeKey.usHigh); } break; case IFFID_wlnk: if (pDlsIns->nRegions < DLSMAXREGIONS) { DLSREGION *pregion = &pDlsIns->Regions[pDlsIns->nRegions]; WLNKCHUNK *p = (WLNKCHUNK *)pchunk; pregion->nWaveLink = (uint16)p->ulTableIndex; if ((pregion->nWaveLink < uint16_max) && (pregion->nWaveLink >= m_nMaxWaveLink)) m_nMaxWaveLink = pregion->nWaveLink + 1; //Log(" WaveLink %d: fusOptions=0x%02X usPhaseGroup=0x%04X ", pDlsIns->nRegions, p->fusOptions, p->usPhaseGroup); //Log("ulChannel=%d ulTableIndex=%4d\n", p->ulChannel, p->ulTableIndex); } break; case IFFID_wsmp: if (pDlsIns->nRegions < DLSMAXREGIONS) { DLSREGION *pregion = &pDlsIns->Regions[pDlsIns->nRegions]; WSMPCHUNK *p = (WSMPCHUNK *)pchunk; pregion->fuOptions |= DLSREGION_OVERRIDEWSMP; pregion->uUnityNote = (uint8)p->usUnityNote; pregion->sFineTune = p->sFineTune; int32 lVolume = DLS32BitRelativeGainToLinear(p->lAttenuation) / 256; if (lVolume > 256) lVolume = 256; if (lVolume < 4) lVolume = 4; pregion->usVolume = (uint16)lVolume; //Log(" WaveSample %d: usUnityNote=%2d sFineTune=%3d ", pDlsEnv->nRegions, p->usUnityNote, p->sFineTune); //Log("fulOptions=0x%04X loops=%d\n", p->fulOptions, p->cSampleLoops); if ((p->cSampleLoops) && (p->cbSize + sizeof(WSMPSAMPLELOOP) <= p->len)) { WSMPSAMPLELOOP *ploop = (WSMPSAMPLELOOP *)(((uint8 *)p)+8+p->cbSize); //Log("looptype=%2d loopstart=%5d loopend=%5d\n", ploop->ulLoopType, ploop->ulLoopStart, ploop->ulLoopLength); if (ploop->ulLoopLength > 3) { pregion->fuOptions |= DLSREGION_SAMPLELOOP; //if (ploop->ulLoopType) pregion->fuOptions |= DLSREGION_PINGPONGLOOP; pregion->ulLoopStart = ploop->ulLoopStart; pregion->ulLoopEnd = ploop->ulLoopStart + ploop->ulLoopLength; } } } break; case IFFID_art1: case IFFID_art2: { ART1CHUNK *p = (ART1CHUNK *)pchunk; if (pDlsIns->ulBank & F_INSTRUMENT_DRUMS) { if (pDlsIns->nRegions >= DLSMAXREGIONS) break; } else { pDlsIns->nMelodicEnv = m_Envelopes.size() + 1; } if (p->cbSize+p->cConnectionBlocks*sizeof(CONNECTIONBLOCK) > p->len) break; DLSENVELOPE dlsEnv; MemsetZero(dlsEnv); dlsEnv.nDefPan = 128; dlsEnv.nVolSustainLevel = 128; //Log(" art1 (%3d bytes): cbSize=%d cConnectionBlocks=%d\n", p->len, p->cbSize, p->cConnectionBlocks); CONNECTIONBLOCK *pblk = (CONNECTIONBLOCK *)( ((uint8 *)p)+8+p->cbSize ); for (uint32 iblk=0; iblkcConnectionBlocks; iblk++, pblk++) { // [4-bit transform][12-bit dest][8-bit control][8-bit source] = 32-bit ID uint32 dwArticulation = pblk->usTransform; dwArticulation = (dwArticulation << 12) | (pblk->usDestination & 0x0FFF); dwArticulation = (dwArticulation << 8) | (pblk->usControl & 0x00FF); dwArticulation = (dwArticulation << 8) | (pblk->usSource & 0x00FF); switch(dwArticulation) { case ART_DEFAULTPAN: { int32 pan = 128 + pblk->lScale / (65536000/128); if (pan < 0) pan = 0; if (pan > 255) pan = 255; dlsEnv.nDefPan = (uint8)pan; } break; case ART_VOL_EG_ATTACKTIME: // 32-bit time cents units. range = [0s, 20s] dlsEnv.wVolAttack = 0; if (pblk->lScale > -0x40000000) { int32 l = pblk->lScale - 78743200; // maximum velocity if (l > 0) l = 0; int32 attacktime = DLS32BitTimeCentsToMilliseconds(l); if (attacktime < 0) attacktime = 0; if (attacktime > 20000) attacktime = 20000; if (attacktime >= 20) dlsEnv.wVolAttack = (uint16)(attacktime / 20); //Log("%3d: Envelope Attack Time set to %d (%d time cents)\n", (uint32)(dlsEnv.ulInstrument & 0x7F)|((dlsEnv.ulBank >> 16) & 0x8000), attacktime, pblk->lScale); } break; case ART_VOL_EG_DECAYTIME: // 32-bit time cents units. range = [0s, 20s] dlsEnv.wVolDecay = 0; if (pblk->lScale > -0x40000000) { int32 decaytime = DLS32BitTimeCentsToMilliseconds(pblk->lScale); if (decaytime > 20000) decaytime = 20000; if (decaytime >= 20) dlsEnv.wVolDecay = (uint16)(decaytime / 20); //Log("%3d: Envelope Decay Time set to %d (%d time cents)\n", (uint32)(dlsEnv.ulInstrument & 0x7F)|((dlsEnv.ulBank >> 16) & 0x8000), decaytime, pblk->lScale); } break; case ART_VOL_EG_RELEASETIME: // 32-bit time cents units. range = [0s, 20s] dlsEnv.wVolRelease = 0; if (pblk->lScale > -0x40000000) { int32 releasetime = DLS32BitTimeCentsToMilliseconds(pblk->lScale); if (releasetime > 20000) releasetime = 20000; if (releasetime >= 20) dlsEnv.wVolRelease = (uint16)(releasetime / 20); //Log("%3d: Envelope Release Time set to %d (%d time cents)\n", (uint32)(dlsEnv.ulInstrument & 0x7F)|((dlsEnv.ulBank >> 16) & 0x8000), dlsEnv.wVolRelease, pblk->lScale); } break; case ART_VOL_EG_SUSTAINLEVEL: // 0.1% units if (pblk->lScale >= 0) { dlsEnv.nVolSustainLevel = DLSSustainLevelToLinear(pblk->lScale); } break; //default: // Log(" Articulation = 0x%08X value=%d\n", dwArticulation, pblk->lScale); } } m_Envelopes.push_back(dlsEnv); } break; case IFFID_INAM: mpt::String::CopyN(pDlsIns->szName, ((const char *)pchunk) + 8, pchunk->len); break; #if 0 default: { char sid[5]; memcpy(sid, &pchunk->id, 4); sid[4] = 0; Log(" \"%s\": %d bytes\n", (uint32)sid, pchunk->len.get()); } #endif } } return true; } /////////////////////////////////////////////////////////////// // Converts SF2 chunks to DLS bool CDLSBank::UpdateSF2PresetData(SF2LOADERINFO &sf2info, const IFFCHUNK &header, FileReader &chunk) { if (!chunk.IsValid()) return false; switch(header.id) { case IFFID_phdr: if (m_Instruments.empty()) { uint32 numIns = chunk.GetLength() / sizeof(SFPRESETHEADER); if(numIns <= 1) break; // The terminal sfPresetHeader record should never be accessed, and exists only to provide a terminal wPresetBagNdx with which to determine the number of zones in the last preset. numIns--; m_Instruments.resize(numIns); #ifdef DLSBANK_LOG Log("phdr: %d instruments\n", m_Instruments.size()); #endif SFPRESETHEADER psfh; chunk.ReadStruct(psfh); for (auto &dlsIns : m_Instruments) { mpt::String::Copy(dlsIns.szName, psfh.achPresetName); dlsIns.ulInstrument = psfh.wPreset & 0x7F; dlsIns.ulBank = (psfh.wBank >= 128) ? F_INSTRUMENT_DRUMS : (psfh.wBank << 8); dlsIns.wPresetBagNdx = psfh.wPresetBagNdx; dlsIns.wPresetBagNum = 1; chunk.ReadStruct(psfh); if (psfh.wPresetBagNdx > dlsIns.wPresetBagNdx) dlsIns.wPresetBagNum = static_cast(psfh.wPresetBagNdx - dlsIns.wPresetBagNdx); } } break; case IFFID_pbag: if (!m_Instruments.empty()) { uint32 nBags = chunk.GetLength() / sizeof(SFPRESETBAG); if (nBags) { sf2info.nPresetBags = nBags; sf2info.pPresetBags = reinterpret_cast(chunk.GetRawData()); } } #ifdef DLSINSTR_LOG else Log("pbag: no instruments!\n"); #endif break; case IFFID_pgen: if (!m_Instruments.empty()) { uint32 nGens = chunk.GetLength() / sizeof(SFGENLIST); if (nGens) { sf2info.nPresetGens = nGens; sf2info.pPresetGens = reinterpret_cast(chunk.GetRawData()); } } #ifdef DLSINSTR_LOG else Log("pgen: no instruments!\n"); #endif break; case IFFID_inst: if (!m_Instruments.empty()) { uint32 nIns = chunk.GetLength() / sizeof(SFINST); sf2info.nInsts = nIns; sf2info.pInsts = reinterpret_cast(chunk.GetRawData()); } break; case IFFID_ibag: if (!m_Instruments.empty()) { uint32 nBags = chunk.GetLength() / sizeof(SFINSTBAG); if (nBags) { sf2info.nInstBags = nBags; sf2info.pInstBags = reinterpret_cast(chunk.GetRawData()); } } break; case IFFID_igen: if (!m_Instruments.empty()) { uint32 nGens = chunk.GetLength() / sizeof(SFINSTGENLIST); if (nGens) { sf2info.nInstGens = nGens; sf2info.pInstGens = reinterpret_cast(chunk.GetRawData()); } } break; case IFFID_shdr: if (m_SamplesEx.empty()) { uint32 numSmp = chunk.GetLength() / sizeof(SFSAMPLE); if (numSmp < 1) break; m_SamplesEx.resize(numSmp); m_WaveForms.resize(numSmp); #ifdef DLSINSTR_LOG Log("shdr: %d samples\n", m_SamplesEx.size()); #endif for (uint32 i = 0; i < numSmp; i++) { SFSAMPLE p; chunk.ReadStruct(p); DLSSAMPLEEX &dlsSmp = m_SamplesEx[i]; mpt::String::Copy(dlsSmp.szName, p.achSampleName); dlsSmp.dwLen = 0; dlsSmp.dwSampleRate = p.dwSampleRate; dlsSmp.byOriginalPitch = p.byOriginalPitch; dlsSmp.chPitchCorrection = static_cast(Util::muldivr(p.chPitchCorrection, 128, 100)); if (((p.sfSampleType & 0x7FFF) <= 4) && (p.dwStart < 0x08000000) && (p.dwEnd >= p.dwStart+8)) { dlsSmp.dwLen = (p.dwEnd - p.dwStart) * 2; if ((p.dwEndloop > p.dwStartloop + 7) && (p.dwStartloop >= p.dwStart)) { dlsSmp.dwStartloop = p.dwStartloop - p.dwStart; dlsSmp.dwEndloop = p.dwEndloop - p.dwStart; } m_WaveForms[i] = p.dwStart * 2; //Log(" offset[%d]=%d len=%d\n", i, p.dwStart*2, psmp->dwLen); } } } break; #ifdef DLSINSTR_LOG default: { char sdbg[5]; memcpy(sdbg, &header.id, 4); sdbg[4] = 0; Log("Unsupported SF2 chunk: %s (%d bytes)\n", sdbg, header.len.get()); } #endif } return true; } static int16 SF2TimeToDLS(int16 amount) { int32 time = CDLSBank::DLS32BitTimeCentsToMilliseconds(static_cast(amount) << 16); return static_cast(Clamp(time, 20, 20000) / 20); } // Convert all instruments to the DLS format bool CDLSBank::ConvertSF2ToDLS(SF2LOADERINFO &sf2info) { if (m_Instruments.empty() || m_SamplesEx.empty()) return false; for (auto &dlsIns : m_Instruments) { DLSENVELOPE dlsEnv; uint32 nInstrNdx = 0; int32 lAttenuation = 0; // Default Envelope Values dlsEnv.wVolAttack = 0; dlsEnv.wVolDecay = 0; dlsEnv.wVolRelease = 0; dlsEnv.nVolSustainLevel = 128; dlsEnv.nDefPan = 128; // Load Preset Bags for (uint32 ipbagcnt=0; ipbagcnt<(uint32)dlsIns.wPresetBagNum; ipbagcnt++) { uint32 ipbagndx = dlsIns.wPresetBagNdx + ipbagcnt; if ((ipbagndx+1 >= sf2info.nPresetBags) || (!sf2info.pPresetBags)) break; // Load generators for each preset bag const SFPRESETBAG *pbag = sf2info.pPresetBags + ipbagndx; for (uint32 ipgenndx=pbag[0].wGenNdx; ipgenndx= sf2info.nPresetGens)) break; const SFGENLIST *pgen = sf2info.pPresetGens + ipgenndx; switch(pgen->sfGenOper) { case SF2_GEN_ATTACKVOLENV: dlsEnv.wVolAttack = SF2TimeToDLS(pgen->genAmount); break; case SF2_GEN_DECAYVOLENV: dlsEnv.wVolDecay = SF2TimeToDLS(pgen->genAmount); break; case SF2_GEN_SUSTAINVOLENV: // 0.1% units if(pgen->genAmount >= 0) { dlsEnv.nVolSustainLevel = SF2SustainLevelToLinear(pgen->genAmount); } break; case SF2_GEN_RELEASEVOLENV: dlsEnv.wVolRelease = SF2TimeToDLS(pgen->genAmount); break; case SF2_GEN_INSTRUMENT: nInstrNdx = pgen->genAmount + 1; break; case SF2_GEN_ATTENUATION: lAttenuation = - (int)(uint16)(pgen->genAmount); break; #if 0 default: Log("Ins %3d: bag %3d gen %3d: ", nIns, ipbagndx, ipgenndx); Log("genoper=%d amount=0x%04X ", pgen->sfGenOper, pgen->genAmount); Log((pSmp->ulBank & F_INSTRUMENT_DRUMS) ? "(drum)\n" : "\n"); #endif } } } // Envelope if (!(dlsIns.ulBank & F_INSTRUMENT_DRUMS)) { m_Envelopes.push_back(dlsEnv); dlsIns.nMelodicEnv = m_Envelopes.size(); } // Load Instrument Bags if ((!nInstrNdx) || (nInstrNdx >= sf2info.nInsts) || (!sf2info.pInsts)) continue; nInstrNdx--; dlsIns.nRegions = sf2info.pInsts[nInstrNdx+1].wInstBagNdx - sf2info.pInsts[nInstrNdx].wInstBagNdx; //Log("\nIns %3d, %2d regions:\n", nIns, pSmp->nRegions); if (dlsIns.nRegions > DLSMAXREGIONS) dlsIns.nRegions = DLSMAXREGIONS; DLSREGION *pRgn = dlsIns.Regions; for (uint32 nRgn = 0; nRgn < dlsIns.nRegions; nRgn++, pRgn++) { uint32 ibagcnt = sf2info.pInsts[nInstrNdx].wInstBagNdx + nRgn; if ((ibagcnt >= sf2info.nInstBags) || (!sf2info.pInstBags)) break; // Create a new envelope for drums DLSENVELOPE *pDlsEnv = &dlsEnv; if (!(dlsIns.ulBank & F_INSTRUMENT_DRUMS) && dlsIns.nMelodicEnv > 0 && dlsIns.nMelodicEnv <= m_Envelopes.size()) { pDlsEnv = &m_Envelopes[dlsIns.nMelodicEnv - 1]; } // Region Default Values int32 lAttn = lAttenuation; pRgn->uUnityNote = 0xFF; // 0xFF means undefined -> use sample pRgn->sFineTune = 0; pRgn->nWaveLink = Util::MaxValueOfType(pRgn->nWaveLink); // Load Generators const SFINSTBAG *pbag = sf2info.pInstBags + ibagcnt; for (uint32 igenndx=pbag[0].wGenNdx; igenndx= sf2info.nInstGens) || (!sf2info.pInstGens)) break; const SFINSTGENLIST *pgen = sf2info.pInstGens + igenndx; uint16 value = pgen->genAmount; switch(pgen->sfGenOper) { case SF2_GEN_KEYRANGE: pRgn->uKeyMin = (uint8)(value & 0xFF); pRgn->uKeyMax = (uint8)(value >> 8); if (pRgn->uKeyMin > pRgn->uKeyMax) { std::swap(pRgn->uKeyMin, pRgn->uKeyMax); } //if (nIns == 9) Log(" keyrange: %d-%d\n", pRgn->uKeyMin, pRgn->uKeyMax); break; case SF2_GEN_UNITYNOTE: if (value < 128) pRgn->uUnityNote = (uint8)value; break; case SF2_GEN_ATTACKVOLENV: pDlsEnv->wVolAttack = SF2TimeToDLS(pgen->genAmount); break; case SF2_GEN_DECAYVOLENV: pDlsEnv->wVolDecay = SF2TimeToDLS(pgen->genAmount); break; case SF2_GEN_SUSTAINVOLENV: // 0.1% units if(pgen->genAmount >= 0) { pDlsEnv->nVolSustainLevel = SF2SustainLevelToLinear(pgen->genAmount); } break; case SF2_GEN_RELEASEVOLENV: pDlsEnv->wVolRelease = SF2TimeToDLS(pgen->genAmount); break; case SF2_GEN_PAN: { int pan = (short int)value; pan = (((pan + 500) * 127) / 500) + 128; if (pan < 0) pan = 0; if (pan > 255) pan = 255; pDlsEnv->nDefPan = (uint8)pan; } break; case SF2_GEN_ATTENUATION: lAttn = -(int)value; break; case SF2_GEN_SAMPLEID: if (value < m_SamplesEx.size()) { pRgn->nWaveLink = value; pRgn->ulLoopStart = m_SamplesEx[value].dwStartloop; pRgn->ulLoopEnd = m_SamplesEx[value].dwEndloop; } break; case SF2_GEN_SAMPLEMODES: value &= 3; pRgn->fuOptions &= uint16(~(DLSREGION_SAMPLELOOP|DLSREGION_PINGPONGLOOP|DLSREGION_SUSTAINLOOP)); if (value == 1) pRgn->fuOptions |= DLSREGION_SAMPLELOOP; else if (value == 2) pRgn->fuOptions |= DLSREGION_SAMPLELOOP|DLSREGION_PINGPONGLOOP; else if (value == 3) pRgn->fuOptions |= DLSREGION_SAMPLELOOP|DLSREGION_SUSTAINLOOP; pRgn->fuOptions |= DLSREGION_OVERRIDEWSMP; break; case SF2_GEN_KEYGROUP: pRgn->fuOptions |= (uint8)(value & DLSREGION_KEYGROUPMASK); break; case SF2_GEN_COARSETUNE: pRgn->sFineTune += static_cast(value) * 128; break; case SF2_GEN_FINETUNE: pRgn->sFineTune += static_cast(Util::muldiv(static_cast(value), 128, 100)); break; //default: // Log(" gen=%d value=%04X\n", pgen->sfGenOper, pgen->genAmount); } } int32 lVolume = DLS32BitRelativeGainToLinear((lAttn/10) << 16) / 256; if (lVolume < 16) lVolume = 16; if (lVolume > 256) lVolume = 256; pRgn->usVolume = (uint16)lVolume; //Log("\n"); } } return true; } /////////////////////////////////////////////////////////////// // Open: opens a DLS bank bool CDLSBank::Open(const mpt::PathString &filename) { if(filename.empty()) return false; m_szFileName = filename; InputFile f(filename); if(!f.IsValid()) return false; return Open(GetFileReader(f)); } bool CDLSBank::Open(FileReader file) { SF2LOADERINFO sf2info; uint32 nInsDef; if(!file.GetFileName().empty()) m_szFileName = file.GetFileName(); file.Rewind(); const uint8 *lpMemFile = file.GetRawData(); uint32 dwMemLength = file.GetLength(); uint32 dwMemPos = 0; if(!file.CanRead(256)) { return false; } RIFFCHUNKID riff; file.ReadStruct(riff); // Check DLS sections embedded in RMI midi files if(riff.id_RIFF == IFFID_RIFF && riff.id_DLS == IFFID_RMID) { while(file.ReadStruct(riff)) { if(riff.id_RIFF == IFFID_RIFF && riff.id_DLS == IFFID_DLS) { file.SkipBack(sizeof(riff)); break; } uint32 len = riff.riff_len; if((len % 2u) != 0) len++; file.SkipBack(4); file.Skip(len); } } // Check XDLS sections embedded in big endian IFF files (Miles Sound System) if (riff.id_RIFF == IFFID_FORM) { do { if(riff.id_DLS == IFFID_XDLS) { file.ReadStruct(riff); break; } uint32 len = SwapBytesBE(riff.riff_len); if((len % 2u) != 0) len++; file.SkipBack(4); file.Skip(len); } while(file.ReadStruct(riff)); } if (riff.id_RIFF != IFFID_RIFF || (riff.id_DLS != IFFID_DLS && riff.id_DLS != IFFID_MLS && riff.id_DLS != IFFID_sfbk) || !file.CanRead(riff.riff_len - 4)) { #ifdef DLSBANK_LOG Log("Invalid DLS bank!\n"); #endif return false; } MemsetZero(sf2info); m_nType = (riff.id_DLS == IFFID_sfbk) ? SOUNDBANK_TYPE_SF2 : SOUNDBANK_TYPE_DLS; m_dwWavePoolOffset = 0; m_Instruments.clear(); m_WaveForms.clear(); m_Envelopes.clear(); nInsDef = 0; if (dwMemLength > 8 + riff.riff_len + dwMemPos) dwMemLength = 8 + riff.riff_len + dwMemPos; while(file.CanRead(sizeof(IFFCHUNK))) { IFFCHUNK chunkHeader; file.ReadStruct(chunkHeader); dwMemPos = file.GetPosition(); FileReader chunk = file.ReadChunk(chunkHeader.len); if(chunkHeader.len % 2u) file.Skip(1); if(!chunk.LengthIsAtLeast(chunkHeader.len)) break; switch(chunkHeader.id) { // DLS 1.0: Instruments Collection Header case IFFID_colh: #ifdef DLSBANK_LOG Log("colh (%d bytes)\n", chunkHeader.len); #endif if (m_Instruments.empty()) { m_Instruments.resize(chunk.ReadUint32LE()); #ifdef DLSBANK_LOG Log(" %d instruments\n", m_Instruments.size()); #endif } break; // DLS 1.0: Instruments Pointers Table case IFFID_ptbl: #ifdef DLSBANK_LOG Log("ptbl (%d bytes)\n", chunkHeader.len); #endif if (m_WaveForms.empty()) { PTBLCHUNK ptbl; chunk.ReadStruct(ptbl); chunk.Skip(ptbl.cbSize - 8); uint32 cues = std::min(ptbl.cCues.get(), mpt::saturate_cast(chunk.BytesLeft() / sizeof(uint32))); m_WaveForms.reserve(cues); for(uint32 i = 0; i < cues; i++) { m_WaveForms.push_back(chunk.ReadUint32LE()); } #ifdef DLSBANK_LOG Log(" %d waveforms\n", m_WaveForms.size()); #endif } break; // DLS 1.0: LIST section case IFFID_LIST: #ifdef DLSBANK_LOG Log("LIST\n"); #endif { uint32 listid = chunk.ReadUint32LE(); if (((listid == IFFID_wvpl) && (m_nType & SOUNDBANK_TYPE_DLS)) || ((listid == IFFID_sdta) && (m_nType & SOUNDBANK_TYPE_SF2))) { m_dwWavePoolOffset = dwMemPos + 4; #ifdef DLSBANK_LOG Log("Wave Pool offset: %d\n", m_dwWavePoolOffset); #endif break; } while (chunk.CanRead(12)) { IFFCHUNK listHeader; const void *subData = chunk.GetRawData(); chunk.ReadStruct(listHeader); if(!chunk.CanRead(listHeader.len)) break; FileReader listChunk = chunk.ReadChunk(listHeader.len); if(listHeader.len % 2u) chunk.Skip(1); // DLS Instrument Headers if (listHeader.id == IFFID_LIST && (m_nType & SOUNDBANK_TYPE_DLS)) { uint32 subID = listChunk.ReadUint32LE(); if ((subID == IFFID_ins) && (nInsDef < m_Instruments.size())) { DLSINSTRUMENT *pDlsIns = &m_Instruments[nInsDef]; //Log("Instrument %d:\n", nInsDef); UpdateInstrumentDefinition(pDlsIns, static_cast(subData), listHeader.len + 8); nInsDef++; } } else // DLS/SF2 Bank Information if (listid == IFFID_INFO && listHeader.len) { switch(listHeader.id) { case IFFID_INAM: listChunk.ReadString(m_BankInfo.szBankName, listChunk.BytesLeft()); break; case IFFID_IENG: listChunk.ReadString(m_BankInfo.szEngineer, listChunk.BytesLeft()); break; case IFFID_ICOP: listChunk.ReadString(m_BankInfo.szCopyRight, listChunk.BytesLeft()); break; case IFFID_ICMT: listChunk.ReadString(m_BankInfo.szComments, listChunk.BytesLeft()); break; case IFFID_ISFT: listChunk.ReadString(m_BankInfo.szSoftware, listChunk.BytesLeft()); break; case IFFID_ISBJ: listChunk.ReadString(m_BankInfo.szDescription, listChunk.BytesLeft()); break; } } else if ((listid == IFFID_pdta) && (m_nType & SOUNDBANK_TYPE_SF2)) { UpdateSF2PresetData(sf2info, listHeader, listChunk); } } } break; #ifdef DLSBANK_LOG default: { char sdbg[5]; memcpy(sdbg, &chunkHeader.id, 4); sdbg[4] = 0; Log("Unsupported chunk: %s (%d bytes)\n", sdbg, chunkHeader.len); } break; #endif } } // Build the ptbl is not present in file if ((m_WaveForms.empty()) && (m_dwWavePoolOffset) && (m_nType & SOUNDBANK_TYPE_DLS) && (m_nMaxWaveLink > 0)) { #ifdef DLSBANK_LOG Log("ptbl not present: building table (%d wavelinks)...\n", m_nMaxWaveLink); #endif m_WaveForms.reserve(m_nMaxWaveLink); dwMemPos = m_dwWavePoolOffset; while (dwMemPos + sizeof(IFFCHUNK) < dwMemLength) { IFFCHUNK *pchunk = (IFFCHUNK *)(lpMemFile + dwMemPos); if (pchunk->id == IFFID_LIST) m_WaveForms.push_back(dwMemPos - m_dwWavePoolOffset); dwMemPos += 8 + pchunk->len; if (m_WaveForms.size() >= m_nMaxWaveLink) break; } #ifdef DLSBANK_LOG Log("Found %d waveforms\n", m_WaveForms.size()); #endif } // Convert the SF2 data to DLS if ((m_nType & SOUNDBANK_TYPE_SF2) && !m_SamplesEx.empty() && !m_Instruments.empty()) { ConvertSF2ToDLS(sf2info); } #ifdef DLSBANK_LOG Log("DLS bank closed\n"); #endif return true; } //////////////////////////////////////////////////////////////////////////////////////// // Extracts the WaveForms from a DLS bank uint32 CDLSBank::GetRegionFromKey(uint32 nIns, uint32 nKey) { DLSINSTRUMENT *pDlsIns; if (nIns >= m_Instruments.size()) return 0; pDlsIns = &m_Instruments[nIns]; for (uint32 rgn=0; rgnnRegions; rgn++) { if ((nKey >= pDlsIns->Regions[rgn].uKeyMin) && (nKey <= pDlsIns->Regions[rgn].uKeyMax)) { return rgn; } } return 0; } bool CDLSBank::ExtractWaveForm(uint32 nIns, uint32 nRgn, std::vector &waveData, uint32 &length) { waveData.clear(); length = 0; if (nIns >= m_Instruments.size() || !m_dwWavePoolOffset) { #ifdef DLSBANK_LOG Log("ExtractWaveForm(%d) failed: m_Instruments.size()=%d m_dwWavePoolOffset=%d m_WaveForms.size()=%d\n", nIns, m_Instruments.size(), m_dwWavePoolOffset, m_WaveForms.size()); #endif return false; } DLSINSTRUMENT &dlsIns = m_Instruments[nIns]; if (nRgn >= dlsIns.nRegions) { #ifdef DLSBANK_LOG Log("invalid waveform region: nIns=%d nRgn=%d pSmp->nRegions=%d\n", nIns, nRgn, pSmp->nRegions); #endif return false; } uint32 nWaveLink = dlsIns.Regions[nRgn].nWaveLink; if(nWaveLink >= m_WaveForms.size()) { #ifdef DLSBANK_LOG Log("Invalid wavelink id: nWaveLink=%d nWaveForms=%d\n", nWaveLink, m_WaveForms.size()); #endif return false; } uint32 dwOffset = m_WaveForms[nWaveLink] + m_dwWavePoolOffset; FILE *f = mpt_fopen(m_szFileName, "rb"); if(f == nullptr) return false; if (fseek(f, dwOffset, SEEK_SET) == 0) { if (m_nType & SOUNDBANK_TYPE_SF2) { if (m_SamplesEx[nWaveLink].dwLen) { if (fseek(f, 8, SEEK_CUR) == 0) { length = m_SamplesEx[nWaveLink].dwLen; try { waveData.assign(length + 8, 0); fread(waveData.data(), 1, length, f); } MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e) { MPT_EXCEPTION_DELETE_OUT_OF_MEMORY(e); } } } } else { LISTCHUNK chunk; if (fread(&chunk, 1, 12, f) == 12) { if ((chunk.id == IFFID_LIST) && (chunk.listid == IFFID_wave) && (chunk.len > 4)) { length = chunk.len + 8; try { waveData.assign(chunk.len + 8, 0); memcpy(waveData.data(), &chunk, 12); fread(&waveData[12], 1, length - 12, f); } MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e) { MPT_EXCEPTION_DELETE_OUT_OF_MEMORY(e); } } } } } fclose(f); return !waveData.empty(); } bool CDLSBank::ExtractSample(CSoundFile &sndFile, SAMPLEINDEX nSample, uint32 nIns, uint32 nRgn, int transpose) { DLSINSTRUMENT *pDlsIns; std::vector pWaveForm; uint32 dwLen = 0; bool bOk, bWaveForm; if (nIns >= m_Instruments.size()) return false; pDlsIns = &m_Instruments[nIns]; if (nRgn >= pDlsIns->nRegions) return false; if (!ExtractWaveForm(nIns, nRgn, pWaveForm, dwLen)) return false; if (dwLen < 16) return false; bOk = false; FileReader wsmpChunk; if (m_nType & SOUNDBANK_TYPE_SF2) { sndFile.DestroySample(nSample); uint32 nWaveLink = pDlsIns->Regions[nRgn].nWaveLink; ModSample &sample = sndFile.GetSample(nSample); if (sndFile.m_nSamples < nSample) sndFile.m_nSamples = nSample; if (nWaveLink < m_SamplesEx.size()) { DLSSAMPLEEX *p = &m_SamplesEx[nWaveLink]; #ifdef DLSINSTR_LOG Log(" SF2 WaveLink #%3d: %5dHz\n", nWaveLink, p->dwSampleRate); #endif sample.Initialize(); sample.nLength = dwLen / 2; sample.nLoopStart = pDlsIns->Regions[nRgn].ulLoopStart; sample.nLoopEnd = pDlsIns->Regions[nRgn].ulLoopEnd; sample.nC5Speed = p->dwSampleRate; sample.RelativeTone = p->byOriginalPitch; sample.nFineTune = p->chPitchCorrection; if (p->szName[0]) mpt::String::Copy(sndFile.m_szNames[nSample], p->szName); else if(pDlsIns->szName[0]) mpt::String::Copy(sndFile.m_szNames[nSample], pDlsIns->szName); FileReader chunk(mpt::as_span(pWaveForm.data(), dwLen)); SampleIO( SampleIO::_16bit, SampleIO::mono, SampleIO::littleEndian, SampleIO::signedPCM) .ReadSample(sample, chunk); } bWaveForm = sample.pSample != nullptr; } else { FileReader file(mpt::as_span(pWaveForm.data(), dwLen)); bWaveForm = sndFile.ReadWAVSample(nSample, file, false, &wsmpChunk); if(pDlsIns->szName[0]) mpt::String::Copy(sndFile.m_szNames[nSample], pDlsIns->szName); } if (bWaveForm) { ModSample &sample = sndFile.GetSample(nSample); DLSREGION *pRgn = &pDlsIns->Regions[nRgn]; sample.uFlags.reset(CHN_LOOP | CHN_PINGPONGLOOP | CHN_SUSTAINLOOP | CHN_PINGPONGSUSTAIN); if (pRgn->fuOptions & DLSREGION_SAMPLELOOP) sample.uFlags.set(CHN_LOOP); if (pRgn->fuOptions & DLSREGION_SUSTAINLOOP) sample.uFlags.set(CHN_SUSTAINLOOP); if (pRgn->fuOptions & DLSREGION_PINGPONGLOOP) sample.uFlags.set(CHN_PINGPONGLOOP); if (sample.uFlags[CHN_LOOP | CHN_SUSTAINLOOP]) { if (pRgn->ulLoopEnd > pRgn->ulLoopStart) { if (sample.uFlags[CHN_SUSTAINLOOP]) { sample.nSustainStart = pRgn->ulLoopStart; sample.nSustainEnd = pRgn->ulLoopEnd; } else { sample.nLoopStart = pRgn->ulLoopStart; sample.nLoopEnd = pRgn->ulLoopEnd; } } else { sample.uFlags.reset(CHN_LOOP|CHN_SUSTAINLOOP); } } // WSMP chunk { uint32 usUnityNote = pRgn->uUnityNote; int sFineTune = pRgn->sFineTune; int lVolume = pRgn->usVolume; WSMPCHUNK wsmp; if(!(pRgn->fuOptions & DLSREGION_OVERRIDEWSMP) && wsmpChunk.IsValid() && wsmpChunk.ReadStructPartial(wsmp)) { usUnityNote = wsmp.usUnityNote; sFineTune = wsmp.sFineTune; lVolume = DLS32BitRelativeGainToLinear(wsmp.lAttenuation) / 256; if(wsmp.cSampleLoops) { WSMPSAMPLELOOP loop; wsmpChunk.Skip(8 + wsmp.cbSize); wsmpChunk.ReadStruct(loop); if(loop.ulLoopLength > 3) { sample.uFlags.set(CHN_LOOP); //if (loop.ulLoopType) sample.uFlags |= CHN_PINGPONGLOOP; sample.nLoopStart = loop.ulLoopStart; sample.nLoopEnd = loop.ulLoopStart + loop.ulLoopLength; } } } else if (m_nType & SOUNDBANK_TYPE_SF2) { usUnityNote = (usUnityNote < 0x80) ? usUnityNote : sample.RelativeTone; sFineTune += sample.nFineTune; } #ifdef DLSINSTR_LOG Log("WSMP: usUnityNote=%d.%d, %dHz (transp=%d)\n", usUnityNote, sFineTune, sample.nC5Speed, transpose); #endif if (usUnityNote > 0x7F) usUnityNote = 60; int steps = (60 + transpose - usUnityNote) * 128 + sFineTune; sample.Transpose(steps * (1.0 / (12.0 * 128.0))); Limit(lVolume, 16, 256); sample.nGlobalVol = (uint8)(lVolume / 4); // 0-64 } sample.nPan = GetPanning(nIns, nRgn); sample.Convert(MOD_TYPE_IT, sndFile.GetType()); sample.PrecomputeLoops(sndFile, false); bOk = true; } return bOk; } static uint16 ScaleEnvelope(uint32 time, float tempoScale) { return std::max(Util::Round(time * tempoScale), 1); } bool CDLSBank::ExtractInstrument(CSoundFile &sndFile, INSTRUMENTINDEX nInstr, uint32 nIns, uint32 nDrumRgn) { SAMPLEINDEX RgnToSmp[DLSMAXREGIONS]; DLSINSTRUMENT *pDlsIns; ModInstrument *pIns; uint32 nRgnMin, nRgnMax, nEnv; if (nIns >= m_Instruments.size()) return false; pDlsIns = &m_Instruments[nIns]; if (pDlsIns->ulBank & F_INSTRUMENT_DRUMS) { if (nDrumRgn >= pDlsIns->nRegions) return false; nRgnMin = nDrumRgn; nRgnMax = nDrumRgn+1; nEnv = pDlsIns->Regions[nDrumRgn].uPercEnv; } else { if (!pDlsIns->nRegions) return false; nRgnMin = 0; nRgnMax = pDlsIns->nRegions; nEnv = pDlsIns->nMelodicEnv; } #ifdef DLSINSTR_LOG Log("DLS Instrument #%d: %s\n", nIns, pDlsIns->szName); Log(" Bank=0x%04X Instrument=0x%04X\n", pDlsIns->ulBank, pDlsIns->ulInstrument); Log(" %2d regions, nMelodicEnv=%d\n", pDlsIns->nRegions, pDlsIns->nMelodicEnv); for (uint32 iDbg=0; iDbgnRegions; iDbg++) { DLSREGION *prgn = &pDlsIns->Regions[iDbg]; Log(" Region %d:\n", iDbg); Log(" WaveLink = %d (loop [%5d, %5d])\n", prgn->nWaveLink, prgn->ulLoopStart, prgn->ulLoopEnd); Log(" Key Range: [%2d, %2d]\n", prgn->uKeyMin, prgn->uKeyMax); Log(" fuOptions = 0x%04X\n", prgn->fuOptions); Log(" usVolume = %3d, Unity Note = %d\n", prgn->usVolume, prgn->uUnityNote); } #endif pIns = new (std::nothrow) ModInstrument(); if(pIns == nullptr) { return false; } if (sndFile.Instruments[nInstr]) { sndFile.DestroyInstrument(nInstr, deleteAssociatedSamples); } // Initializes Instrument if (pDlsIns->ulBank & F_INSTRUMENT_DRUMS) { char s[64] = ""; uint32 key = pDlsIns->Regions[nDrumRgn].uKeyMin; if ((key >= 24) && (key <= 84)) lstrcpyA(s, szMidiPercussionNames[key-24]); if (pDlsIns->szName[0]) { sprintf(&s[strlen(s)], " (%s", pDlsIns->szName); size_t n = strlen(s); while ((n) && (s[n-1] == ' ')) { n--; s[n] = 0; } lstrcatA(s, ")"); } mpt::String::Copy(pIns->name, s); } else { mpt::String::Copy(pIns->name, pDlsIns->szName); } int nTranspose = 0; if (pDlsIns->ulBank & F_INSTRUMENT_DRUMS) { for (uint32 iNoteMap=0; iNoteMapRegions[nDrumRgn].uKeyMin) pIns->NoteMap[iNoteMap] = (uint8)(pDlsIns->Regions[nDrumRgn].uKeyMin + 1); if (iNoteMap > pDlsIns->Regions[nDrumRgn].uKeyMax) pIns->NoteMap[iNoteMap] = (uint8)(pDlsIns->Regions[nDrumRgn].uKeyMax + 1); } else { if (iNoteMap == pDlsIns->Regions[nDrumRgn].uKeyMin) { nTranspose = (pDlsIns->Regions[nDrumRgn].uKeyMin + (pDlsIns->Regions[nDrumRgn].uKeyMax - pDlsIns->Regions[nDrumRgn].uKeyMin) / 2) - 60; } } } } pIns->nFadeOut = 1024; pIns->nMidiProgram = (uint8)(pDlsIns->ulInstrument & 0x7F) + 1; pIns->nMidiChannel = (uint8)((pDlsIns->ulBank & F_INSTRUMENT_DRUMS) ? 10 : 0); pIns->wMidiBank = (uint16)(((pDlsIns->ulBank & 0x7F00) >> 1) | (pDlsIns->ulBank & 0x7F)); pIns->nNNA = NNA_NOTEOFF; pIns->nDCT = DCT_NOTE; pIns->nDNA = DNA_NOTEFADE; sndFile.Instruments[nInstr] = pIns; uint32 nLoadedSmp = 0; SAMPLEINDEX nextSample = 0; // Extract Samples for (uint32 nRgn=nRgnMin; nRgnRegions[nRgn]; // Elimitate Duplicate Regions uint32 iDup; for (iDup=nRgnMin; iDupRegions[iDup]; if (((pRgn2->nWaveLink == pRgn->nWaveLink) && (pRgn2->ulLoopEnd == pRgn->ulLoopEnd) && (pRgn2->ulLoopStart == pRgn->ulLoopStart)) || ((pRgn2->uKeyMin == pRgn->uKeyMin) && (pRgn2->uKeyMax == pRgn->uKeyMax))) { bDupRgn = true; nSmp = RgnToSmp[iDup]; break; } } // Create a new sample if (!bDupRgn) { uint32 nmaxsmp = (m_nType & MOD_TYPE_XM) ? 16 : 32; if (nLoadedSmp >= nmaxsmp) { nSmp = RgnToSmp[nRgn-1]; } else { nextSample = sndFile.GetNextFreeSample(nInstr, nextSample + 1); if (nextSample == SAMPLEINDEX_INVALID) break; if (nextSample > sndFile.GetNumSamples()) sndFile.m_nSamples = nextSample; nSmp = nextSample; nLoadedSmp++; } } RgnToSmp[nRgn] = nSmp; // Map all notes to the right sample if (nSmp) { for (uint32 iKey=0; iKey= pRgn->uKeyMin) && (iKey <= pRgn->uKeyMax))) { pIns->Keyboard[iKey] = nSmp; } } // Load the sample if(!bDupRgn || sndFile.GetSample(nSmp).pSample == nullptr) { ExtractSample(sndFile, nSmp, nIns, nRgn, nTranspose); } else if(sndFile.GetSample(nSmp).GetNumChannels() == 1) { // Try to combine stereo samples uint8 pan1 = GetPanning(nIns, nRgn), pan2 = GetPanning(nIns, iDup); if((pan1 == 0 || pan1 == 255) && (pan2 == 0 || pan2 == 255)) { ModSample &sample = sndFile.GetSample(nSmp); ctrlSmp::ConvertToStereo(sample, sndFile); std::vector pWaveForm; uint32 dwLen = 0; if(ExtractWaveForm(nIns, nRgn, pWaveForm, dwLen) && dwLen >= sample.GetSampleSizeInBytes() / 2) { SmpLength len = sample.nLength; const int16 *src = reinterpret_cast(pWaveForm.data()); int16 *dst = sample.pSample16 + ((pan1 == 0) ? 0 : 1); while(len--) { *dst = *src; src++; dst += 2; } } } } } } float tempoScale = 1.0f; if(sndFile.m_nTempoMode == tempoModeModern) { uint32 ticksPerBeat = sndFile.m_nDefaultRowsPerBeat * sndFile.m_nDefaultSpeed; if(ticksPerBeat == 0) ticksPerBeat = 24; tempoScale = ticksPerBeat / 24.0f; } // Initializes Envelope if ((nEnv) && (nEnv <= m_Envelopes.size())) { DLSENVELOPE *part = &m_Envelopes[nEnv-1]; // Volume Envelope if ((part->wVolAttack) || (part->wVolDecay < 20*50) || (part->nVolSustainLevel) || (part->wVolRelease < 20*50)) { pIns->VolEnv.dwFlags.set(ENV_ENABLED); // Delay section // -> DLS level 2 // Attack section pIns->VolEnv.clear(); if (part->wVolAttack) { pIns->VolEnv.push_back(0, (uint8)(ENVELOPE_MAX / (part->wVolAttack / 2 + 2) + 8)); // /----- pIns->VolEnv.push_back(ScaleEnvelope(part->wVolAttack, tempoScale), ENVELOPE_MAX); // | } else { pIns->VolEnv.push_back(0, ENVELOPE_MAX); } // Hold section // -> DLS Level 2 // Sustain Level if (part->nVolSustainLevel > 0) { if (part->nVolSustainLevel < 128) { uint16 lStartTime = pIns->VolEnv.back().tick; int32 lSusLevel = - DLS32BitRelativeLinearToGain(part->nVolSustainLevel << 9) / 65536; int32 lDecayTime = 1; if (lSusLevel > 0) { lDecayTime = (lSusLevel * (int32)part->wVolDecay) / 960; for (uint32 i=0; i<7; i++) { int32 lFactor = 128 - (1 << i); if (lFactor <= part->nVolSustainLevel) break; int32 lev = - DLS32BitRelativeLinearToGain(lFactor << 9) / 65536; if (lev > 0) { int32 ltime = (lev * (int32)part->wVolDecay) / 960; if ((ltime > 1) && (ltime < lDecayTime)) { uint16 tick = lStartTime + ScaleEnvelope(ltime, tempoScale); if(tick > pIns->VolEnv.back().tick) { pIns->VolEnv.push_back(tick, (uint8)(lFactor / 2)); } } } } } uint16 decayEnd = lStartTime + ScaleEnvelope(lDecayTime, tempoScale); if (decayEnd > pIns->VolEnv.back().tick) { pIns->VolEnv.push_back(decayEnd, (uint8)((part->nVolSustainLevel+1) / 2)); } } pIns->VolEnv.dwFlags.set(ENV_SUSTAIN); } else { pIns->VolEnv.dwFlags.set(ENV_SUSTAIN); pIns->VolEnv.push_back(pIns->VolEnv.back().tick + 1u, pIns->VolEnv.back().value); } pIns->VolEnv.nSustainStart = pIns->VolEnv.nSustainEnd = (uint8)(pIns->VolEnv.size() - 1); // Release section if ((part->wVolRelease) && (pIns->VolEnv.back().value > 1)) { int32 lReleaseTime = part->wVolRelease; uint16 lStartTime = pIns->VolEnv.back().tick; int32 lStartFactor = pIns->VolEnv.back().value; int32 lSusLevel = - DLS32BitRelativeLinearToGain(lStartFactor << 10) / 65536; int32 lDecayEndTime = (lReleaseTime * lSusLevel) / 960; lReleaseTime -= lDecayEndTime; for (uint32 i=0; i<5; i++) { int32 lFactor = 1 + ((lStartFactor * 3) >> (i+2)); if ((lFactor <= 1) || (lFactor >= lStartFactor)) continue; int32 lev = - DLS32BitRelativeLinearToGain(lFactor << 10) / 65536; if (lev > 0) { int32 ltime = (((int32)part->wVolRelease * lev) / 960) - lDecayEndTime; if ((ltime > 1) && (ltime < lReleaseTime)) { uint16 tick = lStartTime + ScaleEnvelope(ltime, tempoScale); if(tick > pIns->VolEnv.back().tick) { pIns->VolEnv.push_back(tick, (uint8)lFactor); } } } } if (lReleaseTime < 1) lReleaseTime = 1; auto releaseTicks = ScaleEnvelope(lReleaseTime, tempoScale); pIns->VolEnv.push_back(lStartTime + releaseTicks, ENVELOPE_MIN); if(releaseTicks > 0) { pIns->nFadeOut = 32768 / releaseTicks; } } else { pIns->VolEnv.push_back(pIns->VolEnv.back().tick + 1u, ENVELOPE_MIN); } } } if (pDlsIns->ulBank & F_INSTRUMENT_DRUMS) { // Create a default envelope for drums pIns->VolEnv.dwFlags.reset(ENV_SUSTAIN); if(!pIns->VolEnv.dwFlags[ENV_ENABLED]) { pIns->VolEnv.dwFlags.set(ENV_ENABLED); pIns->VolEnv.resize(4); pIns->VolEnv[0] = EnvelopeNode(0, ENVELOPE_MAX); pIns->VolEnv[1] = EnvelopeNode(ScaleEnvelope(5, tempoScale), ENVELOPE_MAX); pIns->VolEnv[2] = EnvelopeNode(pIns->VolEnv[1].tick * 2u, ENVELOPE_MID); pIns->VolEnv[3] = EnvelopeNode(pIns->VolEnv[2].tick * 2u, ENVELOPE_MIN); // 1 second max. for drums } } return true; } const char *CDLSBank::GetRegionName(uint32 nIns, uint32 nRgn) const { if (nIns >= m_Instruments.size()) return nullptr; const DLSINSTRUMENT &dlsIns = m_Instruments[nIns]; if (nRgn >= dlsIns.nRegions) return nullptr; if (m_nType & SOUNDBANK_TYPE_SF2) { uint32 nWaveLink = dlsIns.Regions[nRgn].nWaveLink; if (nWaveLink < m_SamplesEx.size()) { return m_SamplesEx[nWaveLink].szName; } } return nullptr; } uint8 CDLSBank::GetPanning(uint32 ins, uint32 region) const { const DLSINSTRUMENT &dlsIns = m_Instruments[ins]; if(region >= CountOf(dlsIns.Regions)) return 128; const DLSREGION &rgn = dlsIns.Regions[region]; if(dlsIns.ulBank & F_INSTRUMENT_DRUMS) { if(rgn.uPercEnv > 0 && rgn.uPercEnv <= m_Envelopes.size()) { return m_Envelopes[rgn.uPercEnv - 1].nDefPan; } } else { if(dlsIns.nMelodicEnv > 0 && dlsIns.nMelodicEnv <= m_Envelopes.size()) { return m_Envelopes[dlsIns.nMelodicEnv - 1].nDefPan; } } return 128; } #else // !MODPLUG_TRACKER MPT_MSVC_WORKAROUND_LNK4221(Dlsbank) #endif // MODPLUG_TRACKER OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/MixerLoops.h0000644000372100037210000000316612342405040020347 00000000000000/* * MixerLoops.h * ------------ * Purpose: Utility inner loops for mixer-related functionality. * Notes : none. * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "Mixer.h" OPENMPT_NAMESPACE_BEGIN struct ModChannel; void StereoMixToFloat(const int32 *pSrc, float *pOut1, float *pOut2, uint32 nCount, const float _i2fc); void FloatToStereoMix(const float *pIn1, const float *pIn2, int32 *pOut, uint32 uint32, const float _f2ic); void MonoMixToFloat(const int32 *pSrc, float *pOut, uint32 uint32, const float _i2fc); void FloatToMonoMix(const float *pIn, int32 *pOut, uint32 uint32, const float _f2ic); #ifndef MODPLUG_TRACKER void ApplyGain(int32 *soundBuffer, std::size_t channels, std::size_t countChunk, int32 gainFactor16_16); void ApplyGain(float *outputBuffer, float * const *outputBuffers, std::size_t offset, std::size_t channels, std::size_t countChunk, float gainFactor); #endif // !MODPLUG_TRACKER void InitMixBuffer(mixsample_t *pBuffer, uint32 nSamples); void InterleaveFrontRear(mixsample_t *pFrontBuf, mixsample_t *pRearBuf, uint32 nFrames); void MonoFromStereo(mixsample_t *pMixBuf, uint32 nSamples); void InterleaveStereo(const mixsample_t *inputL, const mixsample_t *inputR, mixsample_t *output, size_t numSamples); void DeinterleaveStereo(const mixsample_t *input, mixsample_t *outputL, mixsample_t *outputR, size_t numSamples); void EndChannelOfs(ModChannel &chn, mixsample_t *pBuffer, uint32 nSamples); void StereoFill(mixsample_t *pBuffer, uint32 nSamples, mixsample_t &rofs, mixsample_t &lofs); OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/UpgradeModule.cpp0000644000372100037210000006066713161656666021375 00000000000000/* * UpdateModule.cpp * ---------------- * Purpose: CSoundFile functions for correcting modules made with previous versions of OpenMPT. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Sndfile.h" #include "../common/StringFixer.h" #include "../common/version.h" OPENMPT_NAMESPACE_BEGIN struct UpgradePatternData { UpgradePatternData(CSoundFile &sf) : sndFile(sf) , chn(0) , compatPlay(sf.m_playBehaviour[MSF_COMPATIBLE_PLAY]) { } void operator() (ModCommand &m) { const CHANNELINDEX curChn = chn; chn++; if(chn >= sndFile.GetNumChannels()) { chn = 0; } if(m.IsPcNote()) { return; } const auto version = sndFile.m_dwLastSavedWithVersion; const auto modType = sndFile.GetType(); if(modType == MOD_TYPE_S3M) { // Out-of-range global volume commands should be ignored in S3M. Fixed in OpenMPT 1.19 (r831). // So for tracks made with older versions of OpenMPT, we limit invalid global volume commands. if(version < MAKE_VERSION_NUMERIC(1, 19, 00, 00) && m.command == CMD_GLOBALVOLUME) { LimitMax(m.param, ModCommand::PARAM(64)); } } else if(modType & (MOD_TYPE_IT | MOD_TYPE_MPT)) { if(version < MAKE_VERSION_NUMERIC(1, 17, 03, 02) || (!compatPlay && version < MAKE_VERSION_NUMERIC(1, 20, 00, 00))) { if(m.command == CMD_GLOBALVOLUME) { // Out-of-range global volume commands should be ignored in IT. // OpenMPT 1.17.03.02 fixed this in compatible mode, OpenMPT 1.20 fixes it in normal mode as well. // So for tracks made with older versions than OpenMPT 1.17.03.02 or tracks made with 1.17.03.02 <= version < 1.20, we limit invalid global volume commands. LimitMax(m.param, ModCommand::PARAM(128)); } // SC0 and SD0 should be interpreted as SC1 and SD1 in IT files. // OpenMPT 1.17.03.02 fixed this in compatible mode, OpenMPT 1.20 fixes it in normal mode as well. else if(m.command == CMD_S3MCMDEX) { if(m.param == 0xC0) { m.command = CMD_NONE; m.note = NOTE_NOTECUT; } else if(m.param == 0xD0) { m.command = CMD_NONE; } } } // In the IT format, slide commands with both nibbles set should be ignored. // For note volume slides, OpenMPT 1.18 fixes this in compatible mode, OpenMPT 1.20 fixes this in normal mode as well. const bool noteVolSlide = (version < MAKE_VERSION_NUMERIC(1, 18, 00, 00) || (!compatPlay && version < MAKE_VERSION_NUMERIC(1, 20, 00, 00))) && (m.command == CMD_VOLUMESLIDE || m.command == CMD_VIBRATOVOL || m.command == CMD_TONEPORTAVOL || m.command == CMD_PANNINGSLIDE); // OpenMPT 1.20 also fixes this for global volume and channel volume slides. const bool chanVolSlide = (version < MAKE_VERSION_NUMERIC(1, 20, 00, 00)) && (m.command == CMD_GLOBALVOLSLIDE || m.command == CMD_CHANNELVOLSLIDE); if(noteVolSlide || chanVolSlide) { if((m.param & 0x0F) != 0x00 && (m.param & 0x0F) != 0x0F && (m.param & 0xF0) != 0x00 && (m.param & 0xF0) != 0xF0) { m.param &= 0x0F; } } if(version < MAKE_VERSION_NUMERIC(1, 22, 01, 04) && version != MAKE_VERSION_NUMERIC(1, 22, 00, 00)) // Ignore compatibility export { // OpenMPT 1.22.01.04 fixes illegal (out of range) instrument numbers; they should do nothing. In previous versions, they stopped the playing sample. if(sndFile.GetNumInstruments() && m.instr > sndFile.GetNumInstruments() && !compatPlay) { m.volcmd = VOLCMD_VOLUME; m.vol = 0; } } } else if(modType == MOD_TYPE_XM) { // Something made be believe that out-of-range global volume commands are ignored in XM // just like they are ignored in IT, but apparently they are not. Aaaaaargh! if(((version >= MAKE_VERSION_NUMERIC(1, 17, 03, 02) && compatPlay) || (version >= MAKE_VERSION_NUMERIC(1, 20, 00, 00))) && version < MAKE_VERSION_NUMERIC(1, 24, 02, 02) && m.command == CMD_GLOBALVOLUME && m.param > 64) { m.command = CMD_NONE; } if(version < MAKE_VERSION_NUMERIC(1, 19, 00, 00) || (!compatPlay && version < MAKE_VERSION_NUMERIC(1, 20, 00, 00))) { if(m.command == CMD_OFFSET && m.volcmd == VOLCMD_TONEPORTAMENTO) { // If there are both a portamento and an offset effect, the portamento should be preferred in XM files. // OpenMPT 1.19 fixed this in compatible mode, OpenMPT 1.20 fixes it in normal mode as well. m.command = CMD_NONE; } } if(version < MAKE_VERSION_NUMERIC(1, 20, 01, 10) && m.volcmd == VOLCMD_TONEPORTAMENTO && m.command == CMD_TONEPORTAMENTO && (m.vol != 0 || compatPlay) && m.param != 0) { // Mx and 3xx on the same row does weird things in FT2: 3xx is completely ignored and the Mx parameter is doubled. Fixed in revision 1312 / OpenMPT 1.20.01.10 // Previously the values were just added up, so let's fix this! m.volcmd = VOLCMD_NONE; const uint16 param = static_cast(m.param) + static_cast(m.vol << 4); m.param = mpt::saturate_cast(param); } if(version < MAKE_VERSION_NUMERIC(1, 22, 07, 09) && m.command == CMD_SPEED && m.param == 0) { // OpenMPT can emulate FT2's F00 behaviour now. m.command = CMD_NONE; } } if(version < MAKE_VERSION_NUMERIC(1, 20, 00, 00)) { // Pattern Delay fixes const bool fixS6x = (m.command == CMD_S3MCMDEX && (m.param & 0xF0) == 0x60); // We also fix X6x commands in hacked XM files, since they are treated identically to the S6x command in IT/S3M files. // We don't treat them in files made with OpenMPT 1.18+ that have compatible play enabled, though, since they are ignored there anyway. const bool fixX6x = (m.command == CMD_XFINEPORTAUPDOWN && (m.param & 0xF0) == 0x60 && (!(compatPlay && modType == MOD_TYPE_XM) || version < MAKE_VERSION_NUMERIC(1, 18, 00, 00))); if(fixS6x || fixX6x) { // OpenMPT 1.20 fixes multiple fine pattern delays on the same row. Previously, only the last command was considered, // but all commands should be added up. Since Scream Tracker 3 itself doesn't support S6x, we also use Impulse Tracker's behaviour here, // since we can assume that most S3Ms that make use of S6x were composed with Impulse Tracker. for(ModCommand *fixCmd = (&m) - curChn; fixCmd < &m; fixCmd++) { if((fixCmd->command == CMD_S3MCMDEX || fixCmd->command == CMD_XFINEPORTAUPDOWN) && (fixCmd->param & 0xF0) == 0x60) { fixCmd->command = CMD_NONE; } } } if(m.command == CMD_S3MCMDEX && (m.param & 0xF0) == 0xE0) { // OpenMPT 1.20 fixes multiple pattern delays on the same row. Previously, only the *last* command was considered, // but Scream Tracker 3 and Impulse Tracker only consider the *first* command. for(ModCommand *fixCmd = (&m) - curChn; fixCmd < &m; fixCmd++) { if(fixCmd->command == CMD_S3MCMDEX && (fixCmd->param & 0xF0) == 0xE0) { fixCmd->command = CMD_NONE; } } } } if(m.volcmd == VOLCMD_VIBRATODEPTH && version < MAKE_VERSION_NUMERIC(1, 27, 00, 37) && version != MAKE_VERSION_NUMERIC(1, 27, 00, 00)) { // Fix handling of double vibrato commands - previously only one of them was applied at a time if(m.command == CMD_VIBRATOVOL && m.vol > 0) { m.command = CMD_VOLUMESLIDE; } else if((m.command == CMD_VIBRATO || m.command == CMD_FINEVIBRATO) && (m.param & 0x0F) == 0) { m.command = CMD_VIBRATO; m.param |= (m.vol & 0x0F); m.volcmd = VOLCMD_NONE; } else if(m.command == CMD_VIBRATO || m.command == CMD_VIBRATOVOL || m.command == CMD_FINEVIBRATO) { m.volcmd = VOLCMD_NONE; } } // Volume column offset in IT/XM is bad, mkay? if(modType != MOD_TYPE_MPT && m.volcmd == VOLCMD_OFFSET && m.command == CMD_NONE) { m.command = CMD_OFFSET; m.param = m.vol << 3; m.volcmd = VOLCMD_NONE; } } const CSoundFile &sndFile; CHANNELINDEX chn; const bool compatPlay; }; void CSoundFile::UpgradeModule() { if(m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 17, 02, 46) && m_dwLastSavedWithVersion != MAKE_VERSION_NUMERIC(1, 17, 00, 00)) { // Compatible playback mode didn't exist in earlier versions, so definitely disable it. m_playBehaviour.reset(MSF_COMPATIBLE_PLAY); } const bool compatModeIT = m_playBehaviour[MSF_COMPATIBLE_PLAY] && (GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)); const bool compatModeXM = m_playBehaviour[MSF_COMPATIBLE_PLAY] && GetType() == MOD_TYPE_XM; if(m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 20, 00, 00)) { for(INSTRUMENTINDEX i = 1; i <= GetNumInstruments(); i++) if(Instruments[i] != nullptr) { ModInstrument *ins = Instruments[i]; // Previously, volume swing values ranged from 0 to 64. They should reach from 0 to 100 instead. ins->nVolSwing = static_cast(std::min(ins->nVolSwing * 100 / 64, 100)); if(!compatModeIT || m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 18, 00, 00)) { // Previously, Pitch/Pan Separation was only half depth. // This was corrected in compatible mode in OpenMPT 1.18, and in OpenMPT 1.20 it is corrected in normal mode as well. ins->nPPS = (ins->nPPS + (ins->nPPS >= 0 ? 1 : -1)) / 2; } if(!compatModeIT || m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 17, 03, 02)) { // IT compatibility 24. Short envelope loops // Previously, the pitch / filter envelope loop handling was broken, the loop was shortened by a tick (like in XM). // This was corrected in compatible mode in OpenMPT 1.17.03.02, and in OpenMPT 1.20 it is corrected in normal mode as well. ins->GetEnvelope(ENV_PITCH).Convert(MOD_TYPE_XM, GetType()); } if(m_dwLastSavedWithVersion >= MAKE_VERSION_NUMERIC(1, 17, 00, 00) && m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 17, 02, 50)) { // If there are any plugins that can receive volume commands, enable volume bug emulation. if(ins->nMixPlug && ins->HasValidMIDIChannel()) { m_playBehaviour.set(kMIDICCBugEmulation); } } if(m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 17, 02, 50) && (ins->nVolSwing | ins->nPanSwing | ins->nCutSwing | ins->nResSwing)) { // If there are any instruments with random variation, enable the old random variation behaviour. m_playBehaviour.set(kMPTOldSwingBehaviour); break; } } if((GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) && (m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 17, 03, 02) || !compatModeIT)) { // In the IT format, a sweep value of 0 shouldn't apply vibrato at all. Previously, a value of 0 was treated as "no sweep". // In OpenMPT 1.17.03.02, this was corrected in compatible mode, in OpenMPT 1.20 it is corrected in normal mode as well, // so we have to fix the setting while loading. for(SAMPLEINDEX i = 1; i <= GetNumSamples(); i++) { if(Samples[i].nVibSweep == 0 && (Samples[i].nVibDepth | Samples[i].nVibRate)) { Samples[i].nVibSweep = 255; } } } // Fix old nasty broken (non-standard) MIDI configs in files. m_MidiCfg.UpgradeMacros(); } if(m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 20, 02, 10) && m_dwLastSavedWithVersion != MAKE_VERSION_NUMERIC(1, 20, 00, 00) && (GetType() & (MOD_TYPE_XM | MOD_TYPE_IT | MOD_TYPE_MPT))) { bool instrPlugs = false; // Old pitch wheel commands were closest to sample pitch bend commands if the PWD is 13. for(INSTRUMENTINDEX i = 1; i <= GetNumInstruments(); i++) { if(Instruments[i] != nullptr && Instruments[i]->nMidiChannel != MidiNoChannel) { Instruments[i]->midiPWD = 13; instrPlugs = true; } } if(instrPlugs) { m_playBehaviour.set(kOldMIDIPitchBends); } } if(m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 22, 03, 12) && m_dwLastSavedWithVersion != MAKE_VERSION_NUMERIC(1, 22, 00, 00) && (GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) && (m_playBehaviour[MSF_COMPATIBLE_PLAY] || m_playBehaviour[kMPTOldSwingBehaviour])) { // The "correct" pan swing implementation did nothing if the instrument also had a pan envelope. // If there's a pan envelope, disable pan swing for such modules. for(INSTRUMENTINDEX i = 1; i <= GetNumInstruments(); i++) { if(Instruments[i] != nullptr && Instruments[i]->nPanSwing != 0 && Instruments[i]->PanEnv.dwFlags[ENV_ENABLED]) { Instruments[i]->nPanSwing = 0; } } } #ifndef NO_PLUGINS if(m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 22, 07, 01)) { // Convert ANSI plugin path names to UTF-8 (irrelevant in probably 99% of all cases anyway, I think I've never seen a VST plugin with a non-ASCII file name) for(PLUGINDEX i = 0; i < MAX_MIXPLUGINS; i++) { #if defined(MODPLUG_TRACKER) const std::string name = mpt::ToCharset(mpt::CharsetUTF8, mpt::CharsetLocale, m_MixPlugins[i].Info.szLibraryName); #else const std::string name = mpt::ToCharset(mpt::CharsetUTF8, mpt::CharsetWindows1252, m_MixPlugins[i].Info.szLibraryName); #endif mpt::String::Copy(m_MixPlugins[i].Info.szLibraryName, name); } } #endif // NO_PLUGINS // Starting from OpenMPT 1.22.07.19, FT2-style panning was applied in compatible mix mode. // Starting from OpenMPT 1.23.01.04, FT2-style panning has its own mix mode instead. if(GetType() == MOD_TYPE_XM) { if(m_dwLastSavedWithVersion >= MAKE_VERSION_NUMERIC(1, 22, 07, 19) && m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 23, 01, 04) && GetMixLevels() == mixLevelsCompatible) { SetMixLevels(mixLevelsCompatibleFT2); } } if(m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 25, 00, 07) && m_dwLastSavedWithVersion != MAKE_VERSION_NUMERIC(1, 25, 00, 00)) { // Instrument plugins can now receive random volume variation. // For old instruments, disable volume swing in case there was no sample associated. for(INSTRUMENTINDEX i = 1; i <= GetNumInstruments(); i++) { if(Instruments[i] != nullptr && Instruments[i]->nVolSwing != 0 && Instruments[i]->nMidiChannel != MidiNoChannel) { bool hasSample = false; for(size_t k = 0; k < CountOf(Instruments[k]->Keyboard); k++) { if(Instruments[i]->Keyboard[k] != 0) { hasSample = true; break; } } if(!hasSample) { Instruments[i]->nVolSwing = 0; } } } } if(m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 26, 00, 00)) { for(INSTRUMENTINDEX i = 1; i <= GetNumInstruments(); i++) if(Instruments[i] != nullptr) { ModInstrument *ins = Instruments[i]; // Even after fixing it in OpenMPT 1.18, instrument PPS was only half the depth. ins->nPPS = (ins->nPPS + (ins->nPPS >= 0 ? 1 : -1)) / 2; // OpenMPT 1.18 fixed the depth of random pan in compatible mode. // OpenMPT 1.26 fixes it in normal mode too. if(!compatModeIT || m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 18, 00, 00)) { ins->nPanSwing = (ins->nPanSwing + 3) / 4u; } } } Patterns.ForEachModCommand(UpgradePatternData(*this)); // Convert compatibility flags // NOTE: Some of these version numbers are just approximations. // Sometimes a quirk flag is shared by several code locations which might have been fixed at different times. // Sometimes the quirk behaviour has been revised over time, in which case the first version that emulated the quirk enables it. struct PlayBehaviourVersion { PlayBehaviour behaviour; MptVersion::VersionNum version; }; if(compatModeIT && m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 26, 00, 00)) { // Pre-1.26: Detailed compatibility flags did not exist. static constexpr PlayBehaviourVersion behaviours[] = { { kTempoClamp, MAKE_VERSION_NUMERIC(1, 17, 03, 02) }, { kPerChannelGlobalVolSlide, MAKE_VERSION_NUMERIC(1, 17, 03, 02) }, { kPanOverride, MAKE_VERSION_NUMERIC(1, 17, 03, 02) }, { kITInstrWithoutNote, MAKE_VERSION_NUMERIC(1, 17, 02, 46) }, { kITVolColFinePortamento, MAKE_VERSION_NUMERIC(1, 17, 02, 49) }, { kITArpeggio, MAKE_VERSION_NUMERIC(1, 17, 02, 49) }, { kITOutOfRangeDelay, MAKE_VERSION_NUMERIC(1, 17, 02, 49) }, { kITPortaMemoryShare, MAKE_VERSION_NUMERIC(1, 17, 02, 49) }, { kITPatternLoopTargetReset, MAKE_VERSION_NUMERIC(1, 17, 02, 49) }, { kITFT2PatternLoop, MAKE_VERSION_NUMERIC(1, 17, 02, 49) }, { kITPingPongNoReset, MAKE_VERSION_NUMERIC(1, 17, 02, 51) }, { kITEnvelopeReset, MAKE_VERSION_NUMERIC(1, 17, 02, 51) }, { kITClearOldNoteAfterCut, MAKE_VERSION_NUMERIC(1, 17, 02, 52) }, { kITVibratoTremoloPanbrello, MAKE_VERSION_NUMERIC(1, 17, 03, 02) }, { kITTremor, MAKE_VERSION_NUMERIC(1, 17, 03, 02) }, { kITRetrigger, MAKE_VERSION_NUMERIC(1, 17, 03, 02) }, { kITMultiSampleBehaviour, MAKE_VERSION_NUMERIC(1, 17, 03, 02) }, { kITPortaTargetReached, MAKE_VERSION_NUMERIC(1, 17, 03, 02) }, { kITPatternLoopBreak, MAKE_VERSION_NUMERIC(1, 17, 03, 02) }, { kITOffset, MAKE_VERSION_NUMERIC(1, 17, 03, 02) }, { kITSwingBehaviour, MAKE_VERSION_NUMERIC(1, 18, 00, 00) }, { kITNNAReset, MAKE_VERSION_NUMERIC(1, 18, 00, 00) }, { kITSCxStopsSample, MAKE_VERSION_NUMERIC(1, 18, 00, 01) }, { kITEnvelopePositionHandling, MAKE_VERSION_NUMERIC(1, 18, 01, 00) }, { kITPortamentoInstrument, MAKE_VERSION_NUMERIC(1, 19, 00, 01) }, { kITPingPongMode, MAKE_VERSION_NUMERIC(1, 19, 00, 21) }, { kITRealNoteMapping, MAKE_VERSION_NUMERIC(1, 19, 00, 30) }, { kITHighOffsetNoRetrig, MAKE_VERSION_NUMERIC(1, 20, 00, 14) }, { kITFilterBehaviour, MAKE_VERSION_NUMERIC(1, 20, 00, 35) }, { kITNoSurroundPan, MAKE_VERSION_NUMERIC(1, 20, 00, 53) }, { kITShortSampleRetrig, MAKE_VERSION_NUMERIC(1, 20, 00, 54) }, { kITPortaNoNote, MAKE_VERSION_NUMERIC(1, 20, 00, 56) }, { kRowDelayWithNoteDelay, MAKE_VERSION_NUMERIC(1, 20, 00, 76) }, { kITDontResetNoteOffOnPorta, MAKE_VERSION_NUMERIC(1, 20, 02, 06) }, { kITVolColMemory, MAKE_VERSION_NUMERIC(1, 21, 01, 16) }, { kITPortamentoSwapResetsPos, MAKE_VERSION_NUMERIC(1, 21, 01, 25) }, { kITEmptyNoteMapSlot, MAKE_VERSION_NUMERIC(1, 21, 01, 25) }, { kITFirstTickHandling, MAKE_VERSION_NUMERIC(1, 22, 07, 09) }, { kITSampleAndHoldPanbrello, MAKE_VERSION_NUMERIC(1, 22, 07, 19) }, { kITClearPortaTarget, MAKE_VERSION_NUMERIC(1, 23, 04, 03) }, { kITPanbrelloHold, MAKE_VERSION_NUMERIC(1, 24, 01, 06) }, { kITPanningReset, MAKE_VERSION_NUMERIC(1, 24, 01, 06) }, { kITPatternLoopWithJumps, MAKE_VERSION_NUMERIC(1, 25, 00, 19) }, }; for(const auto &b : behaviours) { m_playBehaviour.set(b.behaviour, (m_dwLastSavedWithVersion >= b.version || m_dwLastSavedWithVersion == (b.version & 0xFFFF0000))); } } else if(compatModeXM && m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 26, 00, 00)) { // Pre-1.26: Detailed compatibility flags did not exist. static constexpr PlayBehaviourVersion behaviours[] = { { kTempoClamp, MAKE_VERSION_NUMERIC(1, 17, 03, 02) }, { kPerChannelGlobalVolSlide, MAKE_VERSION_NUMERIC(1, 17, 03, 02) }, { kPanOverride, MAKE_VERSION_NUMERIC(1, 17, 03, 02) }, { kITFT2PatternLoop, MAKE_VERSION_NUMERIC(1, 17, 03, 02) }, { kFT2Arpeggio, MAKE_VERSION_NUMERIC(1, 17, 03, 02) }, { kFT2Retrigger, MAKE_VERSION_NUMERIC(1, 17, 03, 02) }, { kFT2VolColVibrato, MAKE_VERSION_NUMERIC(1, 17, 03, 02) }, { kFT2PortaNoNote, MAKE_VERSION_NUMERIC(1, 17, 03, 02) }, { kFT2KeyOff, MAKE_VERSION_NUMERIC(1, 17, 03, 02) }, { kFT2PanSlide, MAKE_VERSION_NUMERIC(1, 17, 03, 02) }, { kFT2OffsetOutOfRange, MAKE_VERSION_NUMERIC(1, 17, 03, 02) }, { kFT2RestrictXCommand, MAKE_VERSION_NUMERIC(1, 18, 00, 00) }, { kFT2RetrigWithNoteDelay, MAKE_VERSION_NUMERIC(1, 18, 00, 00) }, { kFT2SetPanEnvPos, MAKE_VERSION_NUMERIC(1, 18, 00, 00) }, { kFT2PortaIgnoreInstr, MAKE_VERSION_NUMERIC(1, 18, 00, 01) }, { kFT2VolColMemory, MAKE_VERSION_NUMERIC(1, 18, 01, 00) }, { kFT2LoopE60Restart, MAKE_VERSION_NUMERIC(1, 18, 02, 01) }, { kFT2ProcessSilentChannels, MAKE_VERSION_NUMERIC(1, 18, 02, 01) }, { kFT2ReloadSampleSettings, MAKE_VERSION_NUMERIC(1, 20, 00, 36) }, { kFT2PortaDelay, MAKE_VERSION_NUMERIC(1, 20, 00, 40) }, { kFT2Transpose, MAKE_VERSION_NUMERIC(1, 20, 00, 62) }, { kFT2PatternLoopWithJumps, MAKE_VERSION_NUMERIC(1, 20, 00, 69) }, { kFT2PortaTargetNoReset, MAKE_VERSION_NUMERIC(1, 20, 00, 69) }, { kFT2EnvelopeEscape, MAKE_VERSION_NUMERIC(1, 20, 00, 77) }, { kFT2Tremor, MAKE_VERSION_NUMERIC(1, 20, 01, 11) }, { kFT2OutOfRangeDelay, MAKE_VERSION_NUMERIC(1, 20, 02, 02) }, { kFT2Periods, MAKE_VERSION_NUMERIC(1, 22, 03, 01) }, { kFT2PanWithDelayedNoteOff, MAKE_VERSION_NUMERIC(1, 22, 03, 02) }, { kFT2VolColDelay, MAKE_VERSION_NUMERIC(1, 22, 07, 19) }, { kFT2FinetunePrecision, MAKE_VERSION_NUMERIC(1, 22, 07, 19) }, }; for(const auto &b : behaviours) { m_playBehaviour.set(b.behaviour, m_dwLastSavedWithVersion >= b.version); } } if(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) { // The following behaviours were added in/after OpenMPT 1.26, so are not affected by the upgrade mechanism above. static constexpr PlayBehaviourVersion behaviours[] = { { kITInstrWithNoteOff, MAKE_VERSION_NUMERIC(1, 26, 00, 01) }, { kITMultiSampleInstrumentNumber, MAKE_VERSION_NUMERIC(1, 27, 00, 27) }, }; for(const auto &b : behaviours) { if(m_dwLastSavedWithVersion < (b.version & 0xFFFF0000)) m_playBehaviour.reset(b.behaviour); // Full version information available, i.e. not compatibility-exported. else if(m_dwLastSavedWithVersion > (b.version & 0xFFFF0000) && m_dwLastSavedWithVersion < b.version) m_playBehaviour.reset(b.behaviour); } } else if(GetType() == MOD_TYPE_XM) { // The following behaviours were added after OpenMPT 1.26, so are not affected by the upgrade mechanism above. static constexpr PlayBehaviourVersion behaviours[] = { { kFT2NoteOffFlags, MAKE_VERSION_NUMERIC(1, 27, 00, 27) }, { kRowDelayWithNoteDelay, MAKE_VERSION_NUMERIC(1, 27, 00, 37) }, { kFT2TremoloRampWaveform, MAKE_VERSION_NUMERIC(1, 27, 00, 37) }, { kFT2PortaUpDownMemory, MAKE_VERSION_NUMERIC(1, 27, 00, 37) }, }; for(const auto &b : behaviours) { if(m_dwLastSavedWithVersion < b.version) m_playBehaviour.reset(b.behaviour); } } else if(GetType() == MOD_TYPE_S3M) { // We do not store any of these flags in S3M files. static constexpr PlayBehaviourVersion behaviours[] = { { kST3NoMutedChannels, MAKE_VERSION_NUMERIC(1, 18, 00, 00) }, { kST3EffectMemory, MAKE_VERSION_NUMERIC(1, 20, 00, 00) }, { kRowDelayWithNoteDelay, MAKE_VERSION_NUMERIC(1, 20, 00, 00) }, { kST3PortaSampleChange, MAKE_VERSION_NUMERIC(1, 22, 00, 00) }, { kST3VibratoMemory, MAKE_VERSION_NUMERIC(1, 26, 00, 00) }, { kITPanbrelloHold, MAKE_VERSION_NUMERIC(1, 26, 00, 00) }, { KST3PortaAfterArpeggio, MAKE_VERSION_NUMERIC(1, 27, 00, 00) }, }; for(const auto &b : behaviours) { if(m_dwLastSavedWithVersion < b.version) m_playBehaviour.reset(b.behaviour); } } if(m_dwLastSavedWithVersion >= MAKE_VERSION_NUMERIC(1, 27, 00, 27) && m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 27, 00, 49)) { // OpenMPT 1.27 inserted some IT/FT2 flags before the S3M flags that are never saved to files anyway, to keep the flag IDs a bit more compact. // However, it was overlooked that these flags would still be read by OpenMPT 1.26 and thus S3M-specific behaviour would be enabled in IT/XM files. // Hence, in OpenMPT 1.27.00.49 the flag IDs got remapped to no longer conflict with OpenMPT 1.26. // Files made with the affected pre-release versions of OpenMPT 1.27 are upgraded here to use the new IDs. for(int i = 0; i < 5; i++) { m_playBehaviour.set(kFT2NoteOffFlags + i, m_playBehaviour[kST3NoMutedChannels + i]); m_playBehaviour.reset(kST3NoMutedChannels + i); } } if(m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 17, 00, 00)) { // MPT 1.16 has a maximum tempo of 255. m_playBehaviour.set(kTempoClamp); } else if(m_dwLastSavedWithVersion >= MAKE_VERSION_NUMERIC(1, 17, 00, 00) && m_dwLastSavedWithVersion <= MAKE_VERSION_NUMERIC(1, 20, 01, 03) && m_dwLastSavedWithVersion != MAKE_VERSION_NUMERIC(1, 20, 00, 00)) { // OpenMPT introduced some "fixes" that execute regular portamentos also at speed 1. m_playBehaviour.set(kSlidesAtSpeed1); } if(m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 24, 00, 00)) { // No frequency slides in Hz before OpenMPT 1.24 m_playBehaviour.reset(kHertzInLinearMode); } else if(m_dwLastSavedWithVersion >= MAKE_VERSION_NUMERIC(1, 24, 00, 00) && m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 26, 00, 00) && (GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT))) { // Frequency slides were always in Hz rather than periods in this version range. m_playBehaviour.set(kHertzInLinearMode); } } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/SampleFormatOpus.cpp0000644000372100037210000001061513161656666022065 00000000000000/* * SampleFormatOpus.cpp * -------------------- * Purpose: Opus sample import. * Notes : * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Sndfile.h" #ifndef MODPLUG_NO_FILESAVE #include "../common/mptFileIO.h" #endif #include "../common/misc_util.h" #include "Tagging.h" #include "Loaders.h" #include "ChunkReader.h" #include "modsmp_ctrl.h" #include "../soundbase/SampleFormatConverters.h" #include "../soundbase/SampleFormatCopy.h" #include "../soundlib/ModSampleCopy.h" //#include "../common/mptCRC.h" #include "OggStream.h" #ifdef MPT_WITH_OGG #include #endif // MPT_WITH_OGG #if defined(MPT_WITH_OPUSFILE) #include #endif OPENMPT_NAMESPACE_BEGIN //////////////////////////////////////////////////////////////////////////////// // Opus #if defined(MPT_WITH_OPUSFILE) static mpt::ustring UStringFromOpus(const char *str) { return str ? mpt::ToUnicode(mpt::CharsetUTF8, str) : mpt::ustring(); } static FileTags GetOpusFileTags(OggOpusFile *of) { FileTags tags; const OpusTags *ot = op_tags(of, -1); if(!ot) { return tags; } tags.encoder = UStringFromOpus(opus_tags_query(ot, "ENCODER", 0)); tags.title = UStringFromOpus(opus_tags_query(ot, "TITLE", 0)); tags.comments = UStringFromOpus(opus_tags_query(ot, "DESCRIPTION", 0)); tags.bpm = UStringFromOpus(opus_tags_query(ot, "BPM", 0)); // non-standard tags.artist = UStringFromOpus(opus_tags_query(ot, "ARTIST", 0)); tags.album = UStringFromOpus(opus_tags_query(ot, "ALBUM", 0)); tags.trackno = UStringFromOpus(opus_tags_query(ot, "TRACKNUMBER", 0)); tags.year = UStringFromOpus(opus_tags_query(ot, "DATE", 0)); tags.url = UStringFromOpus(opus_tags_query(ot, "CONTACT", 0)); tags.genre = UStringFromOpus(opus_tags_query(ot, "GENRE", 0)); return tags; } #endif // MPT_WITH_OPUSFILE bool CSoundFile::ReadOpusSample(SAMPLEINDEX sample, FileReader &file) { file.Rewind(); #if defined(MPT_WITH_OPUSFILE) int rate = 0; int channels = 0; std::vector raw_sample_data; FileReader initial = file.GetChunk(65536); // 512 is recommended by libopusfile if(op_test(NULL, initial.GetRawData(), initial.GetLength()) != 0) { return false; } OggOpusFile *of = op_open_memory(file.GetRawData(), file.GetLength(), NULL); if(!of) { return false; } rate = 48000; channels = op_channel_count(of, -1); if(rate <= 0 || channels <= 0) { op_free(of); of = NULL; return false; } if(channels > 2 || op_link_count(of) != 1) { // We downmix multichannel to stereo as recommended by Opus specification in // case we are not able to handle > 2 channels. // We also decode chained files as stereo even if they start with a mono // stream, which simplifies handling of link boundaries for us. channels = 2; } std::vector decodeBuf(120 * 48000 / 1000); // 120ms (max Opus packet), 48kHz bool eof = false; while(!eof) { int framesRead = 0; if(channels == 2) { framesRead = op_read_stereo(of, &(decodeBuf[0]), static_cast(decodeBuf.size())); } else if(channels == 1) { framesRead = op_read(of, &(decodeBuf[0]), static_cast(decodeBuf.size()), NULL); } if(framesRead > 0) { raw_sample_data.insert(raw_sample_data.end(), decodeBuf.begin(), decodeBuf.begin() + (framesRead * channels)); } else if(framesRead == 0) { eof = true; } else if(framesRead == OP_HOLE) { // continue } else { // other errors are fatal, stop decoding eof = true; } } op_free(of); of = NULL; if(raw_sample_data.empty()) { return false; } if((raw_sample_data.size() / channels) > MAX_SAMPLE_LENGTH) { return false; } DestroySampleThreadsafe(sample); strcpy(m_szNames[sample], ""); Samples[sample].Initialize(); Samples[sample].nC5Speed = rate; Samples[sample].nLength = mpt::saturate_cast(raw_sample_data.size() / channels); Samples[sample].uFlags.set(CHN_16BIT); Samples[sample].uFlags.set(CHN_STEREO, channels == 2); if(!Samples[sample].AllocateSample()) { return false; } std::copy(raw_sample_data.begin(), raw_sample_data.end(), Samples[sample].pSample16); Samples[sample].Convert(MOD_TYPE_IT, GetType()); Samples[sample].PrecomputeLoops(*this, false); return true; #else // !MPT_WITH_OPUSFILE MPT_UNREFERENCED_PARAMETER(sample); MPT_UNREFERENCED_PARAMETER(file); return false; #endif // MPT_WITH_OPUSFILE } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Load_s3m.cpp0000644000372100037210000006757313161656666020304 00000000000000/* * Load_s3m.cpp * ------------ * Purpose: S3M (ScreamTracker 3) module loader / saver * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" #include "S3MTools.h" #ifndef MODPLUG_NO_FILESAVE #include "../common/mptFileIO.h" #ifdef MODPLUG_TRACKER #include "../mptrack/TrackerSettings.h" #endif // MODPLUG_TRACKER #endif // MODPLUG_NO_FILESAVE #include "../common/version.h" OPENMPT_NAMESPACE_BEGIN void CSoundFile::S3MConvert(ModCommand &m, bool fromIT) { switch(m.command | 0x40) { case 'A': m.command = CMD_SPEED; break; case 'B': m.command = CMD_POSITIONJUMP; break; case 'C': m.command = CMD_PATTERNBREAK; if (!fromIT) m.param = (m.param >> 4) * 10 + (m.param & 0x0F); break; case 'D': m.command = CMD_VOLUMESLIDE; break; case 'E': m.command = CMD_PORTAMENTODOWN; break; case 'F': m.command = CMD_PORTAMENTOUP; break; case 'G': m.command = CMD_TONEPORTAMENTO; break; case 'H': m.command = CMD_VIBRATO; break; case 'I': m.command = CMD_TREMOR; break; case 'J': m.command = CMD_ARPEGGIO; break; case 'K': m.command = CMD_VIBRATOVOL; break; case 'L': m.command = CMD_TONEPORTAVOL; break; case 'M': m.command = CMD_CHANNELVOLUME; break; case 'N': m.command = CMD_CHANNELVOLSLIDE; break; case 'O': m.command = CMD_OFFSET; break; case 'P': m.command = CMD_PANNINGSLIDE; break; case 'Q': m.command = CMD_RETRIG; break; case 'R': m.command = CMD_TREMOLO; break; case 'S': m.command = CMD_S3MCMDEX; break; case 'T': m.command = CMD_TEMPO; break; case 'U': m.command = CMD_FINEVIBRATO; break; case 'V': m.command = CMD_GLOBALVOLUME; break; case 'W': m.command = CMD_GLOBALVOLSLIDE; break; case 'X': m.command = CMD_PANNING8; break; case 'Y': m.command = CMD_PANBRELLO; break; case 'Z': m.command = CMD_MIDI; break; case '\\': m.command = static_cast(fromIT ? CMD_SMOOTHMIDI : CMD_MIDI); break; // Chars under 0x40 don't save properly, so map : to ] and # to [. case ']': m.command = CMD_DELAYCUT; break; case '[': m.command = CMD_XPARAM; break; default: m.command = CMD_NONE; } } void CSoundFile::S3MSaveConvert(uint8 &command, uint8 ¶m, bool toIT, bool compatibilityExport) const { switch(command) { case CMD_SPEED: command = 'A'; break; case CMD_POSITIONJUMP: command = 'B'; break; case CMD_PATTERNBREAK: command = 'C'; if(!toIT) param = ((param / 10) << 4) + (param % 10); break; case CMD_VOLUMESLIDE: command = 'D'; break; case CMD_PORTAMENTODOWN: command = 'E'; if (param >= 0xE0 && (GetType() & (MOD_TYPE_MOD | MOD_TYPE_XM))) param = 0xDF; break; case CMD_PORTAMENTOUP: command = 'F'; if (param >= 0xE0 && (GetType() & (MOD_TYPE_MOD | MOD_TYPE_XM))) param = 0xDF; break; case CMD_TONEPORTAMENTO: command = 'G'; break; case CMD_VIBRATO: command = 'H'; break; case CMD_TREMOR: command = 'I'; break; case CMD_ARPEGGIO: command = 'J'; break; case CMD_VIBRATOVOL: command = 'K'; break; case CMD_TONEPORTAVOL: command = 'L'; break; case CMD_CHANNELVOLUME: command = 'M'; break; case CMD_CHANNELVOLSLIDE: command = 'N'; break; case CMD_OFFSET: command = 'O'; break; case CMD_PANNINGSLIDE: command = 'P'; break; case CMD_RETRIG: command = 'Q'; break; case CMD_TREMOLO: command = 'R'; break; case CMD_S3MCMDEX: command = 'S'; break; case CMD_TEMPO: command = 'T'; break; case CMD_FINEVIBRATO: command = 'U'; break; case CMD_GLOBALVOLUME: command = 'V'; break; case CMD_GLOBALVOLSLIDE: command = 'W'; break; case CMD_PANNING8: command = 'X'; if(toIT && !(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT | MOD_TYPE_XM | MOD_TYPE_MOD))) { if (param == 0xA4) { command = 'S'; param = 0x91; } else if (param == 0x80) { param = 0xFF; } else if (param < 0x80) { param <<= 1; } else command = 0; } else if (!toIT && (GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT | MOD_TYPE_XM | MOD_TYPE_MOD))) { param >>= 1; } break; case CMD_PANBRELLO: command = 'Y'; break; case CMD_MIDI: command = 'Z'; break; case CMD_SMOOTHMIDI: if(compatibilityExport || !toIT) command = 'Z'; else command = '\\'; break; case CMD_XFINEPORTAUPDOWN: switch(param & 0xF0) { case 0x10: command = 'F'; param = (param & 0x0F) | 0xE0; break; case 0x20: command = 'E'; param = (param & 0x0F) | 0xE0; break; case 0x90: command = 'S'; break; default: command = 0; } break; case CMD_MODCMDEX: { ModCommand m; m.command = CMD_MODCMDEX; m.param = param; m.ExtendedMODtoS3MEffect(); command = m.command; param = m.param; S3MSaveConvert(command, param, toIT, compatibilityExport); } return; // Chars under 0x40 don't save properly, so map : to ] and # to [. case CMD_DELAYCUT: if(compatibilityExport || !toIT) command = 0; else command = ']'; break; case CMD_XPARAM: if(compatibilityExport || !toIT) command = 0; else command = '['; break; default: command = 0; } if(command == 0) { param = 0; } command &= ~0x40; } // Pattern decoding flags enum S3MPattern { s3mEndOfRow = 0x00, s3mChannelMask = 0x1F, s3mNotePresent = 0x20, s3mVolumePresent = 0x40, s3mEffectPresent = 0x80, s3mAnyPresent = 0xE0, s3mNoteOff = 0xFE, s3mNoteNone = 0xFF, }; static bool ValidateHeader(const S3MFileHeader &fileHeader) { if(std::memcmp(fileHeader.magic, "SCRM", 4) || fileHeader.fileType != S3MFileHeader::idS3MType || (fileHeader.formatVersion != S3MFileHeader::oldVersion && fileHeader.formatVersion != S3MFileHeader::newVersion) ) { return false; } return true; } static uint64 GetHeaderMinimumAdditionalSize(const S3MFileHeader &fileHeader) { return fileHeader.ordNum + (fileHeader.smpNum + fileHeader.patNum) * 2; } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderS3M(MemoryFileReader file, const uint64 *pfilesize) { S3MFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return ProbeWantMoreData; } if(!ValidateHeader(fileHeader)) { return ProbeFailure; } return ProbeAdditionalSize(file, pfilesize, GetHeaderMinimumAdditionalSize(fileHeader)); } bool CSoundFile::ReadS3M(FileReader &file, ModLoadingFlags loadFlags) { file.Rewind(); // Is it a valid S3M file? S3MFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return false; } if(!ValidateHeader(fileHeader)) { return false; } if(!file.CanRead(mpt::saturate_cast(GetHeaderMinimumAdditionalSize(fileHeader)))) { return false; } if(loadFlags == onlyVerifyHeader) { return true; } InitializeGlobals(MOD_TYPE_S3M); m_nMinPeriod = 64; m_nMaxPeriod = 32767; // ST3 ignored Zxx commands, so if we find that a file was made with ST3, we should erase all MIDI macros. bool keepMidiMacros = false; mpt::ustring trackerStr; bool nonCompatTracker = false; bool isST3 = false; switch(fileHeader.cwtv & S3MFileHeader::trackerMask) { case S3MFileHeader::trkScreamTracker: if(fileHeader.cwtv == S3MFileHeader::trkST3_20 && fileHeader.special == 0 && (fileHeader.ordNum & 0x0F) == 0 && fileHeader.ultraClicks == 0 && (fileHeader.flags & ~0x50) == 0) { // MPT 1.16 and older versions of OpenMPT - Simply keep default (filter) MIDI macros m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 16, 00, 00); m_madeWithTracker = MPT_USTRING("ModPlug Tracker / OpenMPT"); keepMidiMacros = true; nonCompatTracker = true; m_playBehaviour.set(kST3LimitPeriod); } else if(fileHeader.cwtv == S3MFileHeader::trkST3_20 && fileHeader.special == 0 && fileHeader.ultraClicks == 0 && fileHeader.flags == 0 && fileHeader.usePanningTable == 0) { m_madeWithTracker = MPT_USTRING("Velvet Studio"); } else { trackerStr = MPT_USTRING("Scream Tracker"); isST3 = true; } break; case S3MFileHeader::trkImagoOrpheus: trackerStr = MPT_USTRING("Imago Orpheus"); nonCompatTracker = true; break; case S3MFileHeader::trkImpulseTracker: if(fileHeader.cwtv <= S3MFileHeader::trkIT2_14) trackerStr = MPT_USTRING("Impulse Tracker"); else m_madeWithTracker = mpt::format(MPT_USTRING("Impulse Tracker 2.14p%1"))(fileHeader.cwtv - S3MFileHeader::trkIT2_14); nonCompatTracker = true; m_nMinPeriod = 1; break; case S3MFileHeader::trkSchismTracker: if(fileHeader.cwtv == S3MFileHeader::trkBeRoTrackerOld) { m_madeWithTracker = MPT_USTRING("BeRoTracker"); m_playBehaviour.set(kST3LimitPeriod); } else { m_madeWithTracker = GetSchismTrackerVersion(fileHeader.cwtv); m_nMinPeriod = 1; } nonCompatTracker = true; break; case S3MFileHeader::trkOpenMPT: trackerStr = MPT_USTRING("OpenMPT"); m_dwLastSavedWithVersion = (fileHeader.cwtv & S3MFileHeader::versionMask) << 16; break; case S3MFileHeader::trkBeRoTracker: m_madeWithTracker = MPT_USTRING("BeRoTracker"); m_playBehaviour.set(kST3LimitPeriod); break; case S3MFileHeader::trkCreamTracker: m_madeWithTracker = MPT_USTRING("CreamTracker"); break; } if(!trackerStr.empty()) { m_madeWithTracker = mpt::format(MPT_USTRING("%1 %2.%3"))(trackerStr, (fileHeader.cwtv & 0xF00) >> 8, mpt::ufmt::hex0<2>(fileHeader.cwtv & 0xFF)); } if(nonCompatTracker) { m_playBehaviour.reset(kST3NoMutedChannels); m_playBehaviour.reset(kST3EffectMemory); m_playBehaviour.reset(kST3PortaSampleChange); m_playBehaviour.reset(kST3VibratoMemory); m_playBehaviour.reset(KST3PortaAfterArpeggio); } if((fileHeader.cwtv & S3MFileHeader::trackerMask) > S3MFileHeader::trkScreamTracker) { // 2xyy - Imago Orpheus, 3xyy - IT, 4xyy - Schism, 5xyy - OpenMPT, 6xyy - BeRoTracker if((fileHeader.cwtv & S3MFileHeader::trackerMask) != S3MFileHeader::trkImpulseTracker || fileHeader.cwtv >= S3MFileHeader::trkIT2_14) { // Keep MIDI macros if this is not an old IT version (BABYLON.S3M by Necros has Zxx commands and was saved with IT 2.05) keepMidiMacros = true; } } m_MidiCfg.Reset(); if(!keepMidiMacros) { // Remove macros so they don't interfere with tunes made in trackers that don't support Zxx m_MidiCfg.ClearZxxMacros(); } mpt::String::Read(m_songName, fileHeader.name); if(fileHeader.flags & S3MFileHeader::amigaLimits) m_SongFlags.set(SONG_AMIGALIMITS); if(fileHeader.flags & S3MFileHeader::st2Vibrato) m_SongFlags.set(SONG_S3MOLDVIBRATO); if(fileHeader.cwtv < S3MFileHeader::trkST3_20 || (fileHeader.flags & S3MFileHeader::fastVolumeSlides) != 0) { m_SongFlags.set(SONG_FASTVOLSLIDES); } // Speed m_nDefaultSpeed = fileHeader.speed; if(m_nDefaultSpeed == 0 || (m_nDefaultSpeed == 255 && isST3)) { // Even though ST3 accepts the command AFF as expected, it mysteriously fails to load a default speed of 255... m_nDefaultSpeed = 6; } // Tempo m_nDefaultTempo.Set(fileHeader.tempo); if(fileHeader.tempo < 33) { // ST3 also fails to load an otherwise valid default tempo of 32... m_nDefaultTempo.Set(isST3 ? 125 : 32); } // Global Volume m_nDefaultGlobalVolume = std::min(fileHeader.globalVol, 64) * 4u; // The following check is probably not very reliable, but it fixes a few tunes, e.g. // DARKNESS.S3M by Purple Motion (ST 3.00) and "Image of Variance" by C.C.Catch (ST 3.01): if(m_nDefaultGlobalVolume == 0 && fileHeader.cwtv < S3MFileHeader::trkST3_20) { m_nDefaultGlobalVolume = MAX_GLOBAL_VOLUME; } // Bit 8 = Stereo (we always use stereo) m_nSamplePreAmp = std::max(fileHeader.masterVolume & 0x7F, 0x10); // Channel setup m_nChannels = 4; for(CHANNELINDEX i = 0; i < 32; i++) { ChnSettings[i].Reset(); if(fileHeader.channels[i] != 0xFF) { m_nChannels = i + 1; ChnSettings[i].nPan = (fileHeader.channels[i] & 8) ? 0xCC : 0x33; // 200 : 56 } if(fileHeader.channels[i] & 0x80) { ChnSettings[i].dwFlags = CHN_MUTE; // Detect Adlib channels here (except for OpenMPT 1.19 and older, which would write wrong channel types for PCM channels 16-32): // c = channels[i] ^ 0x80; // if(c >= 16 && c < 32) adlibChannel = true; } } if(m_nChannels < 1) { m_nChannels = 1; } ReadOrderFromFile(Order(), file, fileHeader.ordNum, 0xFF, 0xFE); // Read sample header offsets std::vector sampleOffsets; file.ReadVector(sampleOffsets, fileHeader.smpNum); // Read pattern offsets std::vector patternOffsets; file.ReadVector(patternOffsets, fileHeader.patNum); // Read extended channel panning if(fileHeader.usePanningTable == S3MFileHeader::idPanning) { uint8 pan[32]; file.ReadArray(pan); for(CHANNELINDEX i = 0; i < 32; i++) { if((pan[i] & 0x20) != 0) { ChnSettings[i].nPan = (static_cast(pan[i] & 0x0F) * 256 + 8) / 15; } } } bool hasAdlibPatches = false; // Reading sample headers m_nSamples = std::min(fileHeader.smpNum, MAX_SAMPLES - 1); for(SAMPLEINDEX smp = 0; smp < m_nSamples; smp++) { S3MSampleHeader sampleHeader; if(!file.Seek(sampleOffsets[smp] * 16) || !file.ReadStruct(sampleHeader)) { continue; } sampleHeader.ConvertToMPT(Samples[smp + 1]); mpt::String::Read(m_szNames[smp + 1], sampleHeader.name); if(sampleHeader.sampleType >= S3MSampleHeader::typeAdMel) { hasAdlibPatches = true; } const uint32 sampleOffset = (sampleHeader.dataPointer[1] << 4) | (sampleHeader.dataPointer[2] << 12) | (sampleHeader.dataPointer[0] << 20); if((loadFlags & loadSampleData) && sampleHeader.length != 0 && file.Seek(sampleOffset)) { sampleHeader.GetSampleFormat((fileHeader.formatVersion == S3MFileHeader::oldVersion)).ReadSample(Samples[smp + 1], file); } } if(hasAdlibPatches) { AddToLog("This track uses Adlib instruments, which are not supported by OpenMPT."); } // Try to find out if Zxx commands are supposed to be panning commands (PixPlay). // Actually I am only aware of one module that uses this panning style, namely "Crawling Despair" by $volkraq // and I have no idea what PixPlay is, so this code is solely based on the sample text of that module. // We won't convert if there are not enough Zxx commands, too "high" Zxx commands // or there are only "left" or "right" pannings (we assume that stereo should be somewhat balanced), // and modules not made with an old version of ST3 were probably made in a tracker that supports panning anyway. bool pixPlayPanning = (fileHeader.cwtv < S3MFileHeader::trkST3_20); int zxxCountRight = 0, zxxCountLeft = 0; // Reading patterns if(!(loadFlags & loadPatternData)) { return true; } // Order list cannot contain pattern indices > 255, so do not even try to load higher patterns const PATTERNINDEX readPatterns = std::min(fileHeader.patNum, uint8_max); Patterns.ResizeArray(readPatterns); for(PATTERNINDEX pat = 0; pat < readPatterns; pat++) { // A zero parapointer indicates an empty pattern. if(!Patterns.Insert(pat, 64) || patternOffsets[pat] == 0 || !file.Seek(patternOffsets[pat] * 16)) { continue; } // Skip pattern length indication. // Some modules, for example http://aminet.net/mods/8voic/s3m_hunt.lha seem to have a wrong pattern length - // If you strictly adhere the pattern length, you won't read the patterns correctly in that module. file.Skip(2); // Read pattern data ROWINDEX row = 0; PatternRow rowBase = Patterns[pat].GetRow(0); while(row < 64) { uint8 info = file.ReadUint8(); if(info == s3mEndOfRow) { // End of row if(++row < 64) { rowBase = Patterns[pat].GetRow(row); } continue; } CHANNELINDEX channel = (info & s3mChannelMask); ModCommand dummy; ModCommand &m = (channel < GetNumChannels()) ? rowBase[channel] : dummy; if(info & s3mNotePresent) { uint8 note = file.ReadUint8(), instr = file.ReadUint8(); if(note < 0xF0) { // Note note = (note & 0x0F) + 12 * (note >> 4) + 12 + NOTE_MIN; } else if(note == s3mNoteOff) { // ^^ note = NOTE_NOTECUT; } else if(note == s3mNoteNone) { // .. note = NOTE_NONE; } m.note = note; m.instr = instr; } if(info & s3mVolumePresent) { uint8 volume = file.ReadUint8(); if(volume >= 128 && volume <= 192) { m.volcmd = VOLCMD_PANNING; m.vol = volume - 128; } else { m.volcmd = VOLCMD_VOLUME; m.vol = MIN(volume, 64); } } if(info & s3mEffectPresent) { uint8 command = file.ReadUint8(), param = file.ReadUint8(); if(command != 0) { m.command = command; m.param = param; S3MConvert(m, false); } if(m.command == CMD_S3MCMDEX && (m.param & 0xF0) == 0xA0 && fileHeader.cwtv < S3MFileHeader::trkST3_20) { // Convert old SAx panning to S8x (should only be found in PANIC.S3M by Purple Motion) m.param = 0x80 | ((m.param & 0x0F) ^ 8); } else if(m.command == CMD_MIDI) { // PixPlay panning test if(m.param > 0x0F) { // PixPlay has Z00 to Z0F panning, so we ignore this. pixPlayPanning = false; } else { if(m.param < 0x08) { zxxCountLeft++; } else if(m.param > 0x08) { zxxCountRight++; } } } } } } if(pixPlayPanning && zxxCountLeft + zxxCountRight >= m_nChannels && (-zxxCountLeft + zxxCountRight) < static_cast(m_nChannels)) { // There are enough Zxx commands, so let's assume this was made to be played with PixPlay Patterns.ForEachModCommand([](ModCommand &m) { if(m.command == CMD_MIDI) { m.command = CMD_S3MCMDEX; m.param |= 0x80; } }); } return true; } #ifndef MODPLUG_NO_FILESAVE bool CSoundFile::SaveS3M(const mpt::PathString &filename) const { static const uint8 filler[16] = { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, }; FILE *f; if(m_nChannels == 0 || filename.empty()) return false; if((f = mpt_fopen(filename, "wb")) == nullptr) return false; S3MFileHeader fileHeader; MemsetZero(fileHeader); mpt::String::Write(fileHeader.name, m_songName); fileHeader.dosEof = S3MFileHeader::idEOF; fileHeader.fileType = S3MFileHeader::idS3MType; // Orders ORDERINDEX writeOrders = Order().GetLengthTailTrimmed(); if(writeOrders < 2) { writeOrders = 2; } else if((writeOrders % 2u) != 0) { // Number of orders should be even writeOrders++; } LimitMax(writeOrders, static_cast(256)); fileHeader.ordNum = static_cast(writeOrders); // Samples SAMPLEINDEX writeSamples = static_cast(GetNumInstruments()); if(fileHeader.smpNum == 0) { writeSamples = GetNumSamples(); } writeSamples = Clamp(writeSamples, static_cast(1), static_cast(99)); fileHeader.smpNum = static_cast(writeSamples); // Patterns PATTERNINDEX writePatterns = MIN(Patterns.GetNumPatterns(), 100u); fileHeader.patNum = static_cast(writePatterns); // Flags if(m_SongFlags[SONG_FASTVOLSLIDES]) { fileHeader.flags |= S3MFileHeader::fastVolumeSlides; } if(m_nMaxPeriod < 20000 || m_SongFlags[SONG_AMIGALIMITS]) { fileHeader.flags |= S3MFileHeader::amigaLimits; } // Version info following: ST3.20 = 0x1320 // Most significant nibble = Tracker ID, see S3MFileHeader::S3MTrackerVersions // Following: One nibble = Major version, one byte = Minor version (hex) fileHeader.cwtv = S3MFileHeader::trkOpenMPT | static_cast((MptVersion::num >> 16) & S3MFileHeader::versionMask); fileHeader.formatVersion = S3MFileHeader::newVersion; memcpy(fileHeader.magic, "SCRM", 4); // Song Variables fileHeader.globalVol = static_cast(std::min(m_nDefaultGlobalVolume / 4u, 64u)); fileHeader.speed = static_cast(Clamp(m_nDefaultSpeed, 1u, 254u)); fileHeader.tempo = static_cast(Clamp(m_nDefaultTempo.GetInt(), 33u, 255u)); fileHeader.masterVolume = static_cast(Clamp(m_nSamplePreAmp, 16u, 127u) | 0x80); fileHeader.ultraClicks = 8; fileHeader.usePanningTable = S3MFileHeader::idPanning; // Channel Table const uint8 midCh = static_cast(std::min(GetNumChannels() / 2, 8)); for(CHANNELINDEX chn = 0; chn < 32; chn++) { if(chn < GetNumChannels()) { // ST3 only supports 16 PCM channels, so if channels 17-32 are used, // they must be mapped to the same "internal channels" as channels 1-16. // The channel indices determine in which order channels are evaluated in ST3. // First, the "left" channels (0...7) are evaluated, then the "right" channels (8...15). // Previously, an alternating LRLR scheme was written, which would lead to a different // effect processing in ST3 than LLL...RRR, but since OpenMPT doesn't care about the // channel order and always parses them left to right as they appear in the pattern, // we should just write in the LLL...RRR manner. uint8 ch = chn & 0x0F; if(ch >= midCh) { ch += 8 - midCh; } #ifdef MODPLUG_TRACKER if(TrackerSettings::Instance().MiscSaveChannelMuteStatus) #endif if(ChnSettings[chn].dwFlags[CHN_MUTE]) { ch |= 0x80; } fileHeader.channels[chn] = ch; } else { fileHeader.channels[chn] = 0xFF; } } fwrite(&fileHeader, sizeof(fileHeader), 1, f); Order().WriteAsByte(f, writeOrders); // Comment about parapointers stolen from Schism Tracker: // The sample data parapointers are 24+4 bits, whereas pattern data and sample headers are only 16+4 // bits -- so while the sample data can be written up to 268 MB within the file (starting at 0xffffff0), // the pattern data and sample headers are restricted to the first 1 MB (starting at 0xffff0). In effect, // this practically requires the sample data to be written last in the file, as it is entirely possible // (and quite easy, even) to write more than 1 MB of sample data in a file. // The "practical standard order" listed in TECH.DOC is sample headers, patterns, then sample data. // Calculate offset of first sample header... size_t sampleHeaderOffset = ftell(f) + (writeSamples + writePatterns) * 2 + 32; // ...which must be a multiple of 16, because parapointers omit the lowest 4 bits. sampleHeaderOffset = (sampleHeaderOffset + 15) & ~15; std::vector sampleOffsets(writeSamples); for(SAMPLEINDEX smp = 0; smp < writeSamples; smp++) { STATIC_ASSERT((sizeof(S3MSampleHeader) % 16) == 0); sampleOffsets[smp] = static_cast((sampleHeaderOffset + smp * sizeof(S3MSampleHeader)) / 16); } if(writeSamples != 0) { fwrite(sampleOffsets.data(), 2, writeSamples, f); } size_t patternPointerOffset = ftell(f); size_t firstPatternOffset = sampleHeaderOffset + writeSamples * sizeof(S3MSampleHeader); std::vector patternOffsets(writePatterns); // Need to calculate the real offsets later. if(writePatterns != 0) { fwrite(patternOffsets.data(), 2, writePatterns, f); } // Write channel panning uint8 chnPan[32]; for(CHANNELINDEX chn = 0; chn < 32; chn++) { if(chn < GetNumChannels()) chnPan[chn] = static_cast(((ChnSettings[chn].nPan * 15 + 128) / 256)) | 0x20; else chnPan[chn] = 0x08; } fwrite(chnPan, 32, 1, f); // Do we need to fill up the file with some padding bytes for 16-Byte alignment? size_t curPos = ftell(f); if(curPos < sampleHeaderOffset) { MPT_ASSERT(sampleHeaderOffset - curPos < 16); fwrite(filler, sampleHeaderOffset - curPos, 1, f); } // Don't write sample headers for now, we are lacking the sample offset data. fseek(f, firstPatternOffset, SEEK_SET); // Write patterns for(PATTERNINDEX pat = 0; pat < writePatterns; pat++) { if(Patterns.IsPatternEmpty(pat)) { patternOffsets[pat] = 0; continue; } long patOffset = ftell(f); if(patOffset > 0xFFFF0) { AddToLog(LogError, mpt::format(MPT_USTRING("Too much pattern data! Writing patterns failed starting from pattern %1."))(pat)); break; } MPT_ASSERT((patOffset % 16) == 0); patternOffsets[pat] = static_cast(patOffset / 16); std::vector buffer; buffer.reserve(5 * 1024); // Reserve space for length bytes buffer.resize(2, 0); if(Patterns.IsValidPat(pat)) { for(ROWINDEX row = 0; row < 64; row++) { if(row >= Patterns[pat].GetNumRows()) { // Invent empty row buffer.push_back(s3mEndOfRow); continue; } const PatternRow rowBase = Patterns[pat].GetRow(row); CHANNELINDEX writeChannels = MIN(32, GetNumChannels()); for(CHANNELINDEX chn = 0; chn < writeChannels; chn++) { const ModCommand &m = rowBase[chn]; uint8 info = static_cast(chn); uint8 note = m.note; ModCommand::VOLCMD volcmd = m.volcmd; uint8 vol = m.vol; uint8 command = m.command; uint8 param = m.param; if(note != NOTE_NONE || m.instr != 0) { info |= s3mNotePresent; if(note == NOTE_NONE) { // No Note, or note is too low note = s3mNoteNone; } else if(ModCommand::IsSpecialNote(note)) { // Note Cut note = s3mNoteOff; } else if(note < 12 + NOTE_MIN) { // Too low note = 0; } else if(note <= NOTE_MAX) { note -= (12 + NOTE_MIN); note = (note % 12) + ((note / 12) << 4); } } if(command == CMD_VOLUME) { command = CMD_NONE; volcmd = VOLCMD_VOLUME; vol = MIN(param, 64); } if(volcmd == VOLCMD_VOLUME) { info |= s3mVolumePresent; } else if(volcmd == VOLCMD_PANNING) { info |= s3mVolumePresent; vol |= 0x80; } if(command != CMD_NONE) { S3MSaveConvert(command, param, false, true); if(command) { info |= s3mEffectPresent; } } if(info & s3mAnyPresent) { buffer.push_back(info); if(info & s3mNotePresent) { buffer.push_back(note); buffer.push_back(m.instr); } if(info & s3mVolumePresent) { buffer.push_back(vol); } if(info & s3mEffectPresent) { buffer.push_back(command); buffer.push_back(param); } } } buffer.push_back(s3mEndOfRow); } } else { // Invent empty pattern buffer.insert(buffer.end(), 64, s3mEndOfRow); } uint16 length = mpt::saturate_cast(buffer.size()); buffer[0] = static_cast(length & 0xFF); buffer[1] = static_cast((length >> 8) & 0xFF); if((buffer.size() % 16u) != 0) { // Add padding bytes buffer.insert(buffer.end(), 16 - (buffer.size() % 16u), 0); } fwrite(buffer.data(), buffer.size(), 1, f); } size_t sampleDataOffset = ftell(f); // Write samples std::vector sampleHeader(writeSamples); for(SAMPLEINDEX smp = 0; smp < writeSamples; smp++) { SAMPLEINDEX realSmp = smp + 1; if(GetNumInstruments() != 0 && Instruments[smp] != nullptr) { // Find some valid sample associated with this instrument. for(size_t i = 0; i < CountOf(Instruments[smp]->Keyboard); i++) { if(Instruments[smp]->Keyboard[i] > 0 && Instruments[smp]->Keyboard[i] <= GetNumSamples()) { realSmp = Instruments[smp]->Keyboard[i]; break; } } } if(realSmp > GetNumSamples()) { continue; } SmpLength smpLength = sampleHeader[smp].ConvertToS3M(Samples[realSmp]); mpt::String::Write(sampleHeader[smp].name, m_szNames[realSmp]); if(Samples[realSmp].pSample) { // Write sample data if(sampleDataOffset > 0xFFFFFF0) { AddToLog(LogError, mpt::format(MPT_USTRING("Too much sample data! Writing samples failed starting from sample %1."))(realSmp)); break; } sampleHeader[smp].dataPointer[1] = static_cast((sampleDataOffset >> 4) & 0xFF); sampleHeader[smp].dataPointer[2] = static_cast((sampleDataOffset >> 12) & 0xFF); sampleHeader[smp].dataPointer[0] = static_cast((sampleDataOffset >> 20) & 0xFF); size_t writtenLength = sampleHeader[smp].GetSampleFormat(false).WriteSample(f, Samples[realSmp], smpLength); sampleDataOffset += writtenLength; if((writtenLength % 16u) != 0) { size_t fillSize = 16 - (writtenLength % 16u); fwrite(filler, fillSize, 1, f); sampleDataOffset += fillSize; } } } // Now we know where the patterns are. if(writePatterns != 0) { fseek(f, patternPointerOffset, SEEK_SET); fwrite(patternOffsets.data(), 2, writePatterns, f); } // And we can finally write the sample headers. if(writeSamples != 0) { fseek(f, sampleHeaderOffset, SEEK_SET); fwrite(sampleHeader.data(), sizeof(sampleHeader[0]), writeSamples, f); } fclose(f); return true; } #endif // MODPLUG_NO_FILESAVE OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/MIDIEvents.cpp0000644000372100037210000001303713161656666020534 00000000000000/* * MIDIEvents.cpp * -------------- * Purpose: MIDI event handling, event lists, ... * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "MIDIEvents.h" OPENMPT_NAMESPACE_BEGIN namespace MIDIEvents { // Build a generic MIDI event uint32 Event(EventType eventType, uint8 midiChannel, uint8 dataByte1, uint8 dataByte2) { return (eventType << 4) | (midiChannel & 0x0F) | (dataByte1 << 8) | (dataByte2 << 16); } // Build a MIDI CC event uint32 CC(MidiCC midiCC, uint8 midiChannel, uint8 param) { return Event(evControllerChange, midiChannel, static_cast(midiCC), param); } // Build a MIDI Pitchbend event uint32 PitchBend(uint8 midiChannel, uint16 bendAmount) { return Event(evPitchBend, midiChannel, static_cast(bendAmount & 0x7F), static_cast(bendAmount >> 7)); } // Build a MIDI Program Change event uint32 ProgramChange(uint8 midiChannel, uint8 program) { return Event(evProgramChange, midiChannel, program, 0); } // Build a MIDI Note Off event uint32 NoteOff(uint8 midiChannel, uint8 note, uint8 velocity) { return Event(evNoteOff, midiChannel, note, velocity); } // Build a MIDI Note On event uint32 NoteOn(uint8 midiChannel, uint8 note, uint8 velocity) { return Event(evNoteOn, midiChannel, note, velocity); } // Build a MIDI System Event uint8 System(SystemEvent eventType) { return static_cast((evSystem << 4) | eventType); } // Get MIDI channel from a MIDI event uint8 GetChannelFromEvent(uint32 midiMsg) { return static_cast((midiMsg & 0xF)); } // Get MIDI Event type from a MIDI event EventType GetTypeFromEvent(uint32 midiMsg) { return static_cast(((midiMsg >> 4) & 0xF)); } // Get first data byte from a MIDI event uint8 GetDataByte1FromEvent(uint32 midiMsg) { return static_cast(((midiMsg >> 8) & 0xFF)); } // Get second data byte from a MIDI event uint8 GetDataByte2FromEvent(uint32 midiMsg) { return static_cast(((midiMsg >> 16) & 0xFF)); } // Get the length of a MIDI event in bytes uint8 GetEventLength(uint8 firstByte) { uint8 msgSize = 3; switch(firstByte & 0xF0) { case 0xC0: case 0xD0: msgSize = 2; break; case 0xF0: switch(firstByte) { case 0xF1: case 0xF3: msgSize = 2; break; case 0xF2: msgSize = 3; break; default: msgSize = 1; break; } break; } return msgSize; } // MIDI CC Names const char* const MidiCCNames[MIDICC_end + 1] = { "BankSelect [Coarse]", //0 "ModulationWheel [Coarse]", //1 "Breathcontroller [Coarse]", //2 "", //3 "FootPedal [Coarse]", //4 "PortamentoTime [Coarse]", //5 "DataEntry [Coarse]", //6 "Volume [Coarse]", //7 "Balance [Coarse]", //8 "", //9 "Panposition [Coarse]", //10 "Expression [Coarse]", //11 "EffectControl1 [Coarse]", //12 "EffectControl2 [Coarse]", //13 "", //14 "", //15 "GeneralPurposeSlider1", //16 "GeneralPurposeSlider2", //17 "GeneralPurposeSlider3", //18 "GeneralPurposeSlider4", //19 "", //20 "", //21 "", //22 "", //23 "", //24 "", //25 "", //26 "", //27 "", //28 "", //29 "", //30 "", //31 "BankSelect [Fine]", //32 "ModulationWheel [Fine]", //33 "Breathcontroller [Fine]", //34 "", //35 "FootPedal [Fine]", //36 "PortamentoTime [Fine]", //37 "DataEntry [Fine]", //38 "Volume [Fine]", //39 "Balance [Fine]", //40 "", //41 "Panposition [Fine]", //42 "Expression [Fine]", //43 "EffectControl1 [Fine]", //44 "EffectControl2 [Fine]", //45 "", //46 "", //47 "", //48 "", //49 "", //50 "", //51 "", //52 "", //53 "", //54 "", //55 "", //56 "", //57 "", //58 "", //59 "", //60 "", //61 "", //62 "", //63 "HoldPedal [OnOff]", //64 "Portamento [OnOff]", //65 "SustenutoPedal [OnOff]", //66 "SoftPedal [OnOff]", //67 "LegatoPedal [OnOff]", //68 "Hold2Pedal [OnOff]", //69 "SoundVariation", //70 "SoundTimbre", //71 "SoundReleaseTime", //72 "SoundAttackTime", //73 "SoundBrightness", //74 "SoundControl6", //75 "SoundControl7", //76 "SoundControl8", //77 "SoundControl9", //78 "SoundControl10", //79 "GeneralPurposeButton1 [OnOff]",//80 "GeneralPurposeButton2 [OnOff]",//81 "GeneralPurposeButton3 [OnOff]",//82 "GeneralPurposeButton4 [OnOff]",//83 "", //84 "", //85 "", //86 "", //87 "", //88 "", //89 "", //90 "EffectsLevel", //91 "TremoloLevel", //92 "ChorusLevel", //93 "CelesteLevel", //94 "PhaserLevel", //95 "DataButtonIncrement", //96 "DataButtonDecrement", //97 "NonRegisteredParameter [Fine]",//98 "NonRegisteredParameter [Coarse]",//99 "RegisteredParameter [Fine]", //100 "RegisteredParameter [Coarse]", //101 "", //102 "", //103 "", //104 "", //105 "", //106 "", //107 "", //108 "", //109 "", //110 "", //111 "", //112 "", //113 "", //114 "", //115 "", //116 "", //117 "", //118 "", //119 "AllSoundOff", //120 "AllControllersOff", //121 "LocalKeyboard [OnOff]", //122 "AllNotesOff", //123 "OmniModeOff", //124 "OmniModeOn", //125 "MonoOperation", //126 "PolyOperation", //127 }; } // End namespace OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Sndfile.cpp0000644000372100037210000015221013174677763020213 00000000000000/* * Sndfile.cpp * ----------- * Purpose: Core class of the playback engine. Every song is represented by a CSoundFile object. * Notes : (currently none) * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #ifdef MODPLUG_TRACKER #include "../mptrack/Mptrack.h" // For CTrackApp::OpenURL #include "../mptrack/TrackerSettings.h" #include "../mptrack/Moddoc.h" #include "../mptrack/Reporting.h" #include "../mptrack/Mainfrm.h" #endif // MODPLUG_TRACKER #ifdef MPT_EXTERNAL_SAMPLES #include "../common/mptFileIO.h" #endif // MPT_EXTERNAL_SAMPLES #include "../common/version.h" #include "../soundlib/AudioCriticalSection.h" #include "../common/mptIO.h" #include "../common/serialization_utils.h" #include "Sndfile.h" #include "Tables.h" #include "mod_specifications.h" #include "tuningcollection.h" #include "plugins/PluginManager.h" #include "plugins/PlugInterface.h" #include "../common/StringFixer.h" #include "../common/FileReader.h" #include "Container.h" #include #include #ifndef NO_ARCHIVE_SUPPORT #include "../unarchiver/unarchiver.h" #endif // NO_ARCHIVE_SUPPORT OPENMPT_NAMESPACE_BEGIN mpt::ustring FileHistory::AsISO8601() const { tm date = loadDate; if(openTime > 0) { // Calculate the date when editing finished. double openSeconds = (double)openTime / (double)HISTORY_TIMER_PRECISION; tm tmpLoadDate = loadDate; int64 loadDateSinceEpoch = mpt::Date::Unix::FromUTC(tmpLoadDate); int64 saveDateSinceEpoch = loadDateSinceEpoch + Util::Round(openSeconds); date = mpt::Date::Unix(saveDateSinceEpoch).AsUTC(); } return mpt::Date::ToShortenedISO8601(date); } ////////////////////////////////////////////////////////// // CSoundFile #ifdef MODPLUG_TRACKER const NoteName *CSoundFile::m_NoteNames = NoteNamesFlat; #endif CSoundFile::CSoundFile() : #ifndef MODPLUG_TRACKER m_NoteNames(NoteNamesSharp), #endif m_pTuningsTuneSpecific(nullptr), m_pModSpecs(&ModSpecs::itEx), m_nType(MOD_TYPE_NONE), Patterns(*this), Order(*this), #ifdef MODPLUG_TRACKER m_MIDIMapper(*this), m_pModDoc(nullptr), #endif m_PRNG(mpt::make_prng(mpt::global_prng())), visitedSongRows(*this), m_pCustomLog(nullptr) { MemsetZero(MixSoundBuffer); MemsetZero(MixRearBuffer); MemsetZero(MixFloatBuffer); gnDryLOfsVol = 0; gnDryROfsVol = 0; m_nType = MOD_TYPE_NONE; m_ContainerType = MOD_CONTAINERTYPE_NONE; m_nMixChannels = 0; m_nSamples = 0; m_nInstruments = 0; #ifndef MODPLUG_TRACKER m_nFreqFactor = m_nTempoFactor = 65536; #endif m_nRepeatCount = 0; m_nTempoMode = tempoModeClassic; m_bIsRendering = false; #ifdef MODPLUG_TRACKER m_lockRowStart = m_lockRowEnd = ROWINDEX_INVALID; m_lockOrderStart = m_lockOrderEnd = ORDERINDEX_INVALID; m_bChannelMuteTogglePending.reset(); m_nDefaultRowsPerBeat = m_PlayState.m_nCurrentRowsPerBeat = (TrackerSettings::Instance().m_nRowHighlightBeats) ? TrackerSettings::Instance().m_nRowHighlightBeats : 4; m_nDefaultRowsPerMeasure = m_PlayState.m_nCurrentRowsPerMeasure = (TrackerSettings::Instance().m_nRowHighlightMeasures >= m_nDefaultRowsPerBeat) ? TrackerSettings::Instance().m_nRowHighlightMeasures : m_nDefaultRowsPerBeat * 4; #else m_nDefaultRowsPerBeat = m_PlayState.m_nCurrentRowsPerBeat = 4; m_nDefaultRowsPerMeasure = m_PlayState.m_nCurrentRowsPerMeasure = 16; #endif // MODPLUG_TRACKER MemsetZero(Instruments); MemsetZero(m_szNames); m_pTuningsTuneSpecific = new CTuningCollection(); } CSoundFile::~CSoundFile() { Destroy(); delete m_pTuningsTuneSpecific; m_pTuningsTuneSpecific = nullptr; } void CSoundFile::AddToLog(LogLevel level, const mpt::ustring &text) const { if(m_pCustomLog) { m_pCustomLog->AddToLog(level, text); } else { #ifdef MODPLUG_TRACKER if(GetpModDoc()) GetpModDoc()->AddToLog(level, text); #else MPT_LOG(level, "soundlib", text); #endif } } // Global variable initializer for loader functions void CSoundFile::InitializeGlobals(MODTYPE type) { // Do not add or change any of these values! And if you do, review each and every loader to check if they require these defaults! m_nType = type; MODTYPE bestType = GetBestSaveFormat(); m_playBehaviour = GetDefaultPlaybackBehaviour(bestType); SetModSpecsPointer(m_pModSpecs, bestType); // Delete instruments in case some previously called loader already created them. for(INSTRUMENTINDEX i = 1; i <= m_nInstruments; i++) { delete Instruments[i]; Instruments[i] = nullptr; } m_ContainerType = MOD_CONTAINERTYPE_NONE; m_nChannels = 0; m_nInstruments = 0; m_nSamples = 0; m_nSamplePreAmp = 48; m_nVSTiVolume = 48; m_nDefaultSpeed = 6; m_nDefaultTempo.Set(125); m_nDefaultGlobalVolume = MAX_GLOBAL_VOLUME; m_SongFlags.reset(); m_nMinPeriod = 16; m_nMaxPeriod = 32767; m_nResampling = SRCMODE_DEFAULT; m_dwLastSavedWithVersion = m_dwCreatedWithVersion = 0; SetMixLevels(mixLevelsCompatible); Patterns.ClearPatterns(); Order.Initialize(); m_songName.clear(); m_songArtist.clear(); m_songMessage.clear(); m_madeWithTracker.clear(); m_FileHistory.clear(); m_tempoSwing.clear(); // Note: we do not use the Amiga resampler for DBM as it's a multichannel format and can make use of higher-quality Amiga soundcards instead of Paula. if(GetType() & (/*MOD_TYPE_DBM | */MOD_TYPE_DIGI | MOD_TYPE_MED | MOD_TYPE_MOD | MOD_TYPE_OKT | MOD_TYPE_SFX | MOD_TYPE_STP)) { m_SongFlags.set(SONG_ISAMIGA); } } void CSoundFile::InitializeChannels() { for(CHANNELINDEX nChn = 0; nChn < MAX_BASECHANNELS; nChn++) { InitChannel(nChn); } } CSoundFile::ProbeResult CSoundFile::ProbeAdditionalSize(MemoryFileReader &file, const uint64 *pfilesize, uint64 minimumAdditionalSize) { const uint64 availableFileSize = file.GetLength(); const uint64 fileSize = (pfilesize ? *pfilesize : file.GetLength()); //const uint64 validFileSize = std::min(fileSize, ProbeRecommendedSize); const uint64 goalSize = file.GetPosition() + minimumAdditionalSize; //const uint64 goalMinimumSize = std::min(goalSize, ProbeRecommendedSize); if(pfilesize) { if(availableFileSize < std::min(fileSize, ProbeRecommendedSize)) { if(availableFileSize < goalSize) { return ProbeWantMoreData; } } else { if(fileSize < goalSize) { return ProbeFailure; } } return ProbeSuccess; } return ProbeSuccess; } const std::size_t CSoundFile::ProbeRecommendedSize = PROBE_RECOMMENDED_SIZE; #define MPT_DO_PROBE( storedResult , call ) \ MPT_DO { \ ProbeResult lastResult = call ; \ if(lastResult == ProbeSuccess) { \ return ProbeSuccess; \ } else if(lastResult == ProbeWantMoreData) { \ storedResult = ProbeWantMoreData; \ } \ } MPT_WHILE_0 \ /**/ CSoundFile::ProbeResult CSoundFile::Probe(ProbeFlags flags, mpt::span data, const uint64 *pfilesize) { ProbeResult result = ProbeFailure; if(pfilesize && (*pfilesize < data.size())) { throw std::out_of_range(""); } if(!data.data()) { throw std::invalid_argument(""); } MemoryFileReader file(data); if(flags & ProbeContainers) { MPT_DO_PROBE(result, ProbeFileHeaderMMCMP(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderPP20(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderUMX(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderXPK(file, pfilesize)); } if(flags & ProbeModules) { MPT_DO_PROBE(result, ProbeFileHeader669(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderAM(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderAMF_Asylum(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderAMF_DSMI(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderAMS(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderAMS2(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderDBM(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderDTM(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderDIGI(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderDMF(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderDSM(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderFAR(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderGDM(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderICE(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderIMF(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderIT(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderITP(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderJ2B(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderM15(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderMDL(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderMED(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderMO3(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderMOD(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderMT2(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderMTM(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderOKT(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderPLM(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderPSM(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderPSM16(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderPT36(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderPTM(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderS3M(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderSFX(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderSTM(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderSTP(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderULT(file, pfilesize)); MPT_DO_PROBE(result, ProbeFileHeaderXM(file, pfilesize)); } if(pfilesize) { if((result == ProbeWantMoreData) && (mpt::saturate_cast(*pfilesize) <= data.size())) { // If the prober wants more data but we already reached EOF, // probing must fail. result = ProbeFailure; } } else { if((result == ProbeWantMoreData) && (data.size() >= ProbeRecommendedSize)) { // If the prober wants more daat but we already provided the recommended required maximum, // just return success as this is th ebest we can do for the suggestesd probing size. result = ProbeSuccess; } } return result; } #ifdef MODPLUG_TRACKER bool CSoundFile::Create(FileReader file, ModLoadingFlags loadFlags, CModDoc *pModDoc) { m_pModDoc = pModDoc; #else bool CSoundFile::Create(FileReader file, ModLoadingFlags loadFlags) { #endif // MODPLUG_TRACKER m_nMixChannels = 0; #ifndef MODPLUG_TRACKER m_nFreqFactor = m_nTempoFactor = 65536; #endif MemsetZero(Instruments); MemsetZero(m_szNames); #ifndef NO_PLUGINS std::fill(std::begin(m_MixPlugins), std::end(m_MixPlugins), SNDMIXPLUGIN()); #endif // NO_PLUGINS if(file.IsValid()) { try { #ifndef NO_ARCHIVE_SUPPORT CUnarchiver unarchiver(file); if(!(loadFlags & skipContainer)) { if (unarchiver.ExtractBestFile(GetSupportedExtensions(true))) { file = unarchiver.GetOutputFile(); } } #endif std::vector containerItems; MODCONTAINERTYPE packedContainerType = MOD_CONTAINERTYPE_NONE; if(!(loadFlags & skipContainer)) { ContainerLoadingFlags containerLoadFlags = (loadFlags == onlyVerifyHeader) ? ContainerOnlyVerifyHeader : ContainerUnwrapData; if(packedContainerType == MOD_CONTAINERTYPE_NONE && UnpackXPK(containerItems, file, containerLoadFlags)) packedContainerType = MOD_CONTAINERTYPE_XPK; if(packedContainerType == MOD_CONTAINERTYPE_NONE && UnpackPP20(containerItems, file, containerLoadFlags)) packedContainerType = MOD_CONTAINERTYPE_PP20; if(packedContainerType == MOD_CONTAINERTYPE_NONE && UnpackMMCMP(containerItems, file, containerLoadFlags)) packedContainerType = MOD_CONTAINERTYPE_MMCMP; if(packedContainerType == MOD_CONTAINERTYPE_NONE && UnpackUMX(containerItems, file, containerLoadFlags)) packedContainerType = MOD_CONTAINERTYPE_UMX; if(packedContainerType != MOD_CONTAINERTYPE_NONE) { if(loadFlags == onlyVerifyHeader) { return true; } if(!containerItems.empty()) { file = containerItems[0].file; } } } if(loadFlags & skipModules) { return false; } if(!ReadXM(file, loadFlags) && !ReadIT(file, loadFlags) && !ReadS3M(file, loadFlags) && !ReadSTM(file, loadFlags) && !ReadMed(file, loadFlags) && !ReadMTM(file, loadFlags) && !ReadMDL(file, loadFlags) && !ReadDBM(file, loadFlags) && !ReadFAR(file, loadFlags) && !ReadAMS(file, loadFlags) && !ReadAMS2(file, loadFlags) && !ReadOKT(file, loadFlags) && !ReadPTM(file, loadFlags) && !ReadUlt(file, loadFlags) && !ReadDMF(file, loadFlags) && !ReadDSM(file, loadFlags) #if defined(MODPLUG_TRACKER) || defined(MPT_FUZZ_TRACKER) && !ReadUAX(file, loadFlags) #endif // MODPLUG_TRACKER || MPT_FUZZ_TRACKER && !ReadAMF_Asylum(file, loadFlags) && !ReadAMF_DSMI(file, loadFlags) && !ReadPSM(file, loadFlags) && !ReadPSM16(file, loadFlags) && !ReadMT2(file, loadFlags) && !ReadITProject(file, loadFlags) #if defined(MODPLUG_TRACKER) || defined(MPT_FUZZ_TRACKER) // this makes little sense for a module player library && !ReadWav(file, loadFlags) && !ReadMID(file, loadFlags) #endif // MODPLUG_TRACKER || MPT_FUZZ_TRACKER && !ReadGDM(file, loadFlags) && !ReadIMF(file, loadFlags) && !ReadDIGI(file, loadFlags) && !ReadDTM(file, loadFlags) && !ReadPLM(file, loadFlags) && !ReadAM(file, loadFlags) && !ReadJ2B(file, loadFlags) && !ReadPT36(file, loadFlags) && !ReadSFX(file, loadFlags) && !ReadSTP(file, loadFlags) && !ReadMod(file, loadFlags) && !ReadICE(file, loadFlags) && !Read669(file, loadFlags) && !ReadMO3(file, loadFlags) && !ReadM15(file, loadFlags)) { m_nType = MOD_TYPE_NONE; m_ContainerType = MOD_CONTAINERTYPE_NONE; if(loadFlags == onlyVerifyHeader) { return false; } } else { if(loadFlags == onlyVerifyHeader) { return true; } } if(packedContainerType != MOD_CONTAINERTYPE_NONE && m_ContainerType == MOD_CONTAINERTYPE_NONE) { m_ContainerType = packedContainerType; } if(m_madeWithTracker.empty()) { m_madeWithTracker = ModTypeToTracker(GetType()); } #ifndef NO_ARCHIVE_SUPPORT // Read archive comment if there is no song comment if(m_songMessage.empty()) { m_songMessage.assign(mpt::ToCharset(mpt::CharsetLocale, unarchiver.GetComment())); } #endif } MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e) { MPT_EXCEPTION_DELETE_OUT_OF_MEMORY(e); #ifdef MODPLUG_TRACKER return false; #else // libopenmpt already handles this. throw; #endif // MODPLUG_TRACKER } } else { // New song InitializeGlobals(); m_dwCreatedWithVersion = MptVersion::num; } // Adjust channels for(CHANNELINDEX ich = 0; ich < MAX_BASECHANNELS; ich++) { LimitMax(ChnSettings[ich].nVolume, uint16(64)); if (ChnSettings[ich].nPan > 256) ChnSettings[ich].nPan = 128; m_PlayState.Chn[ich].Reset(ModChannel::resetTotal, *this, ich); } // Checking samples, load external samples for(SAMPLEINDEX nSmp = 1; nSmp <= m_nSamples; nSmp++) { // Sanitize sample names mpt::String::SetNullTerminator(m_szNames[nSmp]); ModSample &sample = Samples[nSmp]; #ifdef MPT_EXTERNAL_SAMPLES if(SampleHasPath(nSmp)) { mpt::PathString filename = GetSamplePath(nSmp); if(!file.GetFileName().empty()) { filename = filename.RelativePathToAbsolute(file.GetFileName().GetPath()); } else if(GetpModDoc() != nullptr) { filename = filename.RelativePathToAbsolute(GetpModDoc()->GetPathNameMpt().GetPath()); } if(!LoadExternalSample(nSmp, filename)) { #ifndef MODPLUG_TRACKER // OpenMPT has its own way of reporting this error in CModDoc. AddToLog(LogError, mpt::format(MPT_USTRING("Unable to load sample %1: %2"))(i, filename.ToUnicode())); #endif // MODPLUG_TRACKER } } else { sample.uFlags.reset(SMP_KEEPONDISK); } #endif // MPT_EXTERNAL_SAMPLES if(sample.pSample) { sample.PrecomputeLoops(*this, false); } else if(!sample.uFlags[SMP_KEEPONDISK]) { sample.nLength = 0; sample.nLoopStart = 0; sample.nLoopEnd = 0; sample.nSustainStart = 0; sample.nSustainEnd = 0; sample.uFlags.reset(CHN_LOOP | CHN_PINGPONGLOOP | CHN_SUSTAINLOOP | CHN_PINGPONGSUSTAIN); } if(sample.nGlobalVol > 64) sample.nGlobalVol = 64; } // Check invalid instruments INSTRUMENTINDEX maxInstr = 0; for(INSTRUMENTINDEX i = 0; i <= m_nInstruments; i++) { if(Instruments[i] != nullptr) { maxInstr = i; Instruments[i]->Sanitize(GetType()); } } m_nInstruments = maxInstr; // Set default play state values if (!m_nDefaultTempo.GetInt()) m_nDefaultTempo.Set(125); if (!m_nDefaultSpeed) m_nDefaultSpeed = 6; m_PlayState.m_nMusicSpeed = m_nDefaultSpeed; m_PlayState.m_nMusicTempo = m_nDefaultTempo; m_PlayState.m_nCurrentRowsPerBeat = m_nDefaultRowsPerBeat; m_PlayState.m_nCurrentRowsPerMeasure = m_nDefaultRowsPerMeasure; m_PlayState.m_nGlobalVolume = static_cast(m_nDefaultGlobalVolume); m_PlayState.m_lHighResRampingGlobalVolume = m_PlayState.m_nGlobalVolume<= order.size()) { order.SetRestartPos(0); } } #ifndef NO_PLUGINS // Load plugins #ifdef MODPLUG_TRACKER std::string notFoundText; #endif // MODPLUG_TRACKER std::vector notFoundIDs; if((loadFlags & (loadPluginData | loadPluginInstance)) == (loadPluginData | loadPluginInstance)) { for(PLUGINDEX plug = 0; plug < MAX_MIXPLUGINS; plug++) { auto &plugin = m_MixPlugins[plug]; if(plugin.IsValidPlugin()) { #ifdef MODPLUG_TRACKER // Provide some visual feedback { mpt::ustring s = mpt::format(MPT_USTRING("Loading Plugin FX%1: %2 (%3)"))( mpt::ufmt::dec0<2>(plug + 1), mpt::ToUnicode(mpt::CharsetUTF8, plugin.Info.szLibraryName), mpt::ToUnicode(mpt::CharsetLocale, plugin.Info.szName)); CMainFrame::GetMainFrame()->SetHelpText(mpt::ToCString(s)); } #endif // MODPLUG_TRACKER CreateMixPluginProc(plugin, *this); if(plugin.pMixPlugin) { // Plugin was found plugin.pMixPlugin->RestoreAllParameters(plugin.defaultProgram); } else { // Plugin not found - add to list bool found = std::find_if(notFoundIDs.cbegin(), notFoundIDs.cend(), [&plugin](const SNDMIXPLUGININFO *info) { return info->dwPluginId2 == plugin.Info.dwPluginId2 && info->dwPluginId1 == plugin.Info.dwPluginId1; }) != notFoundIDs.cend(); if(!found) { notFoundIDs.push_back(&plugin.Info); #ifdef MODPLUG_TRACKER notFoundText.append(plugin.GetLibraryName()); notFoundText.append("\n"); #else AddToLog(LogWarning, MPT_USTRING("Plugin not found: ") + mpt::ToUnicode(mpt::CharsetUTF8, plugin.GetLibraryName())); #endif // MODPLUG_TRACKER } } } } } #ifdef MODPLUG_TRACKER // Display a nice message so the user sees which plugins are missing // TODO: Use IDD_MODLOADING_WARNINGS dialog (NON-MODAL!) to display all warnings that are encountered when loading a module. if(!notFoundIDs.empty()) { if(notFoundIDs.size() == 1) { notFoundText = "The following plugin has not been found:\n\n" + notFoundText + "\nDo you want to search for it online?"; } else { notFoundText = "The following plugins have not been found:\n\n" + notFoundText + "\nDo you want to search for them online?"; } if (Reporting::Confirm(mpt::ToWide(mpt::CharsetUTF8, notFoundText.c_str()), L"OpenMPT - Plugins missing", false, true) == cnfYes) { std::string url = "https://resources.openmpt.org/plugins/search.php?p="; for(auto &id : notFoundIDs) { url += mpt::fmt::HEX0<8>(id->dwPluginId2.get()); url += id->szLibraryName; url += "%0a"; } CTrackApp::OpenURL(mpt::PathString::FromUTF8(url)); } } #endif // MODPLUG_TRACKER #endif // NO_PLUGINS // Set up mix levels SetMixLevels(m_nMixLevels); if(GetType() == MOD_TYPE_NONE) { return false; } SetModSpecsPointer(m_pModSpecs, GetBestSaveFormat()); // When reading a file made with an older version of MPT, it might be necessary to upgrade some settings automatically. if(m_dwLastSavedWithVersion) { UpgradeModule(); } return true; } bool CSoundFile::Destroy() { for(auto &chn : m_PlayState.Chn) { chn.pModInstrument = nullptr; chn.pModSample = nullptr; chn.pCurrentSample = nullptr; chn.nLength = 0; } Patterns.DestroyPatterns(); m_songName.clear(); m_songArtist.clear(); m_songMessage.clear(); m_madeWithTracker.clear(); m_FileHistory.clear(); for(auto &smp : Samples) { smp.FreeSample(); } for(auto &ins : Instruments) { delete ins; ins = nullptr; } #ifndef NO_PLUGINS for(auto &plug : m_MixPlugins) { plug.Destroy(); } #endif // NO_PLUGINS m_nType = MOD_TYPE_NONE; m_ContainerType = MOD_CONTAINERTYPE_NONE; m_nChannels = m_nSamples = m_nInstruments = 0; return true; } ////////////////////////////////////////////////////////////////////////// // Misc functions void CSoundFile::SetDspEffects(uint32 DSPMask) { #ifdef ENABLE_ASM #ifndef NO_REVERB if(!(GetProcSupport() & PROCSUPPORT_MMX)) DSPMask &= ~SNDDSP_REVERB; #endif #endif m_MixerSettings.DSPMask = DSPMask; InitPlayer(false); } void CSoundFile::SetPreAmp(uint32 nVol) { if (nVol < 1) nVol = 1; if (nVol > 0x200) nVol = 0x200; // x4 maximum #ifndef NO_AGC if ((nVol < m_MixerSettings.m_nPreAmp) && (nVol) && (m_MixerSettings.DSPMask & SNDDSP_AGC)) { m_AGC.Adjust(m_MixerSettings.m_nPreAmp, nVol); } #endif m_MixerSettings.m_nPreAmp = nVol; } double CSoundFile::GetCurrentBPM() const { double bpm; if (m_nTempoMode == tempoModeModern) { // With modern mode, we trust that true bpm is close enough to what user chose. // This avoids oscillation due to tick-to-tick corrections. bpm = m_PlayState.m_nMusicTempo.ToDouble(); } else { //with other modes, we calculate it: double ticksPerBeat = m_PlayState.m_nMusicSpeed * m_PlayState.m_nCurrentRowsPerBeat; //ticks/beat = ticks/row * rows/beat double samplesPerBeat = m_PlayState.m_nSamplesPerTick * ticksPerBeat; //samps/beat = samps/tick * ticks/beat bpm = m_MixerSettings.gdwMixingFreq / samplesPerBeat * 60; //beats/sec = samps/sec / samps/beat } //beats/min = beats/sec * 60 return bpm; } void CSoundFile::ResetPlayPos() { for(CHANNELINDEX i = 0; i < MAX_CHANNELS; i++) m_PlayState.Chn[i].Reset(ModChannel::resetSetPosFull, *this, i); visitedSongRows.Initialize(true); m_SongFlags.reset(SONG_FADINGSONG | SONG_ENDREACHED); m_PlayState.m_nGlobalVolume = m_nDefaultGlobalVolume; m_PlayState.m_nMusicSpeed = m_nDefaultSpeed; m_PlayState.m_nMusicTempo = m_nDefaultTempo; // do not ramp global volume when starting playback m_PlayState.m_lHighResRampingGlobalVolume = m_PlayState.m_nGlobalVolume<= Order().size()) || (Order()[nOrder] >= Patterns.Size())) return; for(auto &chn : m_PlayState.Chn) { chn.nPeriod = 0; chn.nNote = NOTE_NONE; chn.nPortamentoDest = 0; chn.nCommand = 0; chn.nPatternLoopCount = 0; chn.nPatternLoop = 0; chn.nVibratoPos = chn.nTremoloPos = chn.nPanbrelloPos = 0; //IT compatibility 15. Retrigger if(m_playBehaviour[kITRetrigger]) { chn.nRetrigCount = 0; chn.nRetrigParam = 1; } chn.nTremorCount = 0; } #ifndef NO_PLUGINS // Stop hanging notes from VST instruments as well StopAllVsti(); #endif // NO_PLUGINS if (!nOrder) { ResetPlayPos(); } else { m_PlayState.m_nNextOrder = nOrder; m_PlayState.m_nRow = m_PlayState.m_nNextRow = 0; m_PlayState.m_nPattern = 0; m_PlayState.m_nTickCount = m_PlayState.m_nMusicSpeed; m_PlayState.m_nBufferCount = 0; m_PlayState.m_nPatternDelay = 0; m_PlayState.m_nFrameDelay = 0; m_PlayState.m_nNextPatStartRow = 0; } m_SongFlags.reset(SONG_FADINGSONG | SONG_ENDREACHED); } void CSoundFile::SuspendPlugins() { #ifndef NO_PLUGINS for(auto &plug : m_MixPlugins) { IMixPlugin *pPlugin = plug.pMixPlugin; if(pPlugin != nullptr && pPlugin->IsResumed()) { pPlugin->NotifySongPlaying(false); pPlugin->HardAllNotesOff(); pPlugin->Suspend(); } } #endif // NO_PLUGINS } void CSoundFile::ResumePlugins() { #ifndef NO_PLUGINS for(auto &plugin : m_MixPlugins) { IMixPlugin *pPlugin = plugin.pMixPlugin; if(pPlugin != nullptr && !pPlugin->IsResumed()) { pPlugin->NotifySongPlaying(true); pPlugin->Resume(); } } #endif // NO_PLUGINS } void CSoundFile::StopAllVsti() { #ifndef NO_PLUGINS for(auto &plugin : m_MixPlugins) { IMixPlugin *pPlugin = plugin.pMixPlugin; if(pPlugin != nullptr && pPlugin->IsResumed()) { pPlugin->HardAllNotesOff(); } } #endif // NO_PLUGINS } void CSoundFile::SetMixLevels(MixLevels levels) { m_nMixLevels = levels; m_PlayConfig.SetMixLevels(m_nMixLevels); RecalculateGainForAllPlugs(); } void CSoundFile::RecalculateGainForAllPlugs() { #ifndef NO_PLUGINS for(auto &plugin : m_MixPlugins) { if(plugin.pMixPlugin != nullptr) plugin.pMixPlugin->RecalculateGain(); } #endif // NO_PLUGINS } void CSoundFile::ResetChannels() { m_SongFlags.reset(SONG_FADINGSONG | SONG_ENDREACHED); m_PlayState.m_nBufferCount = 0; for(auto &chn : m_PlayState.Chn) { chn.nROfs = chn.nLOfs = 0; chn.nLength = 0; } } #ifdef MODPLUG_TRACKER void CSoundFile::PatternTranstionChnSolo(const CHANNELINDEX chnIndex) { if(chnIndex >= m_nChannels) return; for(CHANNELINDEX i = 0; i < m_nChannels; i++) { m_bChannelMuteTogglePending[i] = !ChnSettings[i].dwFlags[CHN_MUTE]; } m_bChannelMuteTogglePending[chnIndex] = ChnSettings[chnIndex].dwFlags[CHN_MUTE]; } void CSoundFile::PatternTransitionChnUnmuteAll() { for(CHANNELINDEX i = 0; i < m_nChannels; i++) { m_bChannelMuteTogglePending[i] = ChnSettings[i].dwFlags[CHN_MUTE]; } } #endif // MODPLUG_TRACKER void CSoundFile::LoopPattern(PATTERNINDEX nPat, ROWINDEX nRow) { if(!Patterns.IsValidPat(nPat)) { m_SongFlags.reset(SONG_PATTERNLOOP); } else { if(nRow >= Patterns[nPat].GetNumRows()) nRow = 0; m_PlayState.m_nPattern = nPat; m_PlayState.m_nRow = m_PlayState.m_nNextRow = nRow; m_PlayState.m_nTickCount = m_PlayState.m_nMusicSpeed; m_PlayState.m_nPatternDelay = 0; m_PlayState.m_nFrameDelay = 0; m_PlayState.m_nBufferCount = 0; m_PlayState.m_nNextPatStartRow = 0; m_SongFlags.set(SONG_PATTERNLOOP); } } void CSoundFile::DontLoopPattern(PATTERNINDEX nPat, ROWINDEX nRow) { if(!Patterns.IsValidPat(nPat)) nPat = 0; if(nRow >= Patterns[nPat].GetNumRows()) nRow = 0; m_PlayState.m_nPattern = nPat; m_PlayState.m_nRow = m_PlayState.m_nNextRow = nRow; m_PlayState.m_nTickCount = m_PlayState.m_nMusicSpeed; m_PlayState.m_nPatternDelay = 0; m_PlayState.m_nFrameDelay = 0; m_PlayState.m_nBufferCount = 0; m_PlayState.m_nNextPatStartRow = 0; m_SongFlags.reset(SONG_PATTERNLOOP); } void CSoundFile::SetDefaultPlaybackBehaviour(MODTYPE type) { m_playBehaviour = GetDefaultPlaybackBehaviour(type); } PlayBehaviourSet CSoundFile::GetSupportedPlaybackBehaviour(MODTYPE type) { PlayBehaviourSet playBehaviour; switch(type) { case MOD_TYPE_MPT: case MOD_TYPE_IT: playBehaviour.set(MSF_COMPATIBLE_PLAY); playBehaviour.set(kHertzInLinearMode); playBehaviour.set(kTempoClamp); playBehaviour.set(kPerChannelGlobalVolSlide); playBehaviour.set(kPanOverride); playBehaviour.set(kITInstrWithoutNote); playBehaviour.set(kITVolColFinePortamento); playBehaviour.set(kITArpeggio); playBehaviour.set(kITOutOfRangeDelay); playBehaviour.set(kITPortaMemoryShare); playBehaviour.set(kITPatternLoopTargetReset); playBehaviour.set(kITFT2PatternLoop); playBehaviour.set(kITPingPongNoReset); playBehaviour.set(kITEnvelopeReset); playBehaviour.set(kITClearOldNoteAfterCut); playBehaviour.set(kITVibratoTremoloPanbrello); playBehaviour.set(kITTremor); playBehaviour.set(kITRetrigger); playBehaviour.set(kITMultiSampleBehaviour); playBehaviour.set(kITPortaTargetReached); playBehaviour.set(kITPatternLoopBreak); playBehaviour.set(kITOffset); playBehaviour.set(kITSwingBehaviour); playBehaviour.set(kITNNAReset); playBehaviour.set(kITSCxStopsSample); playBehaviour.set(kITEnvelopePositionHandling); playBehaviour.set(kITPortamentoInstrument); playBehaviour.set(kITPingPongMode); playBehaviour.set(kITRealNoteMapping); playBehaviour.set(kITHighOffsetNoRetrig); playBehaviour.set(kITFilterBehaviour); playBehaviour.set(kITNoSurroundPan); playBehaviour.set(kITShortSampleRetrig); playBehaviour.set(kITPortaNoNote); playBehaviour.set(kITDontResetNoteOffOnPorta); playBehaviour.set(kITVolColMemory); playBehaviour.set(kITPortamentoSwapResetsPos); playBehaviour.set(kITEmptyNoteMapSlot); playBehaviour.set(kITFirstTickHandling); playBehaviour.set(kITSampleAndHoldPanbrello); playBehaviour.set(kITClearPortaTarget); playBehaviour.set(kITPanbrelloHold); playBehaviour.set(kITPanningReset); playBehaviour.set(kITPatternLoopWithJumps); playBehaviour.set(kITInstrWithNoteOff); playBehaviour.set(kITMultiSampleInstrumentNumber); playBehaviour.set(kRowDelayWithNoteDelay); break; case MOD_TYPE_XM: playBehaviour.set(MSF_COMPATIBLE_PLAY); playBehaviour.set(kFT2VolumeRamping); playBehaviour.set(kTempoClamp); playBehaviour.set(kPerChannelGlobalVolSlide); playBehaviour.set(kPanOverride); playBehaviour.set(kITFT2PatternLoop); playBehaviour.set(kFT2Arpeggio); playBehaviour.set(kFT2Retrigger); playBehaviour.set(kFT2VolColVibrato); playBehaviour.set(kFT2PortaNoNote); playBehaviour.set(kFT2KeyOff); playBehaviour.set(kFT2PanSlide); playBehaviour.set(kFT2OffsetOutOfRange); playBehaviour.set(kFT2RestrictXCommand); playBehaviour.set(kFT2RetrigWithNoteDelay); playBehaviour.set(kFT2SetPanEnvPos); playBehaviour.set(kFT2PortaIgnoreInstr); playBehaviour.set(kFT2VolColMemory); playBehaviour.set(kFT2LoopE60Restart); playBehaviour.set(kFT2ProcessSilentChannels); playBehaviour.set(kFT2ReloadSampleSettings); playBehaviour.set(kFT2PortaDelay); playBehaviour.set(kFT2Transpose); playBehaviour.set(kFT2PatternLoopWithJumps); playBehaviour.set(kFT2PortaTargetNoReset); playBehaviour.set(kFT2EnvelopeEscape); playBehaviour.set(kFT2Tremor); playBehaviour.set(kFT2OutOfRangeDelay); playBehaviour.set(kFT2Periods); playBehaviour.set(kFT2PanWithDelayedNoteOff); playBehaviour.set(kFT2VolColDelay); playBehaviour.set(kFT2FinetunePrecision); playBehaviour.set(kFT2NoteOffFlags); playBehaviour.set(kRowDelayWithNoteDelay); playBehaviour.set(kFT2TremoloRampWaveform); playBehaviour.set(kFT2PortaUpDownMemory); break; case MOD_TYPE_S3M: playBehaviour.set(MSF_COMPATIBLE_PLAY); playBehaviour.set(kTempoClamp); playBehaviour.set(kPanOverride); playBehaviour.set(kITPanbrelloHold); playBehaviour.set(kST3NoMutedChannels); playBehaviour.set(kST3PortaSampleChange); playBehaviour.set(kST3EffectMemory); playBehaviour.set(kST3VibratoMemory); playBehaviour.set(KST3PortaAfterArpeggio); playBehaviour.set(kRowDelayWithNoteDelay); break; case MOD_TYPE_MOD: playBehaviour.set(kMODVBlankTiming); playBehaviour.set(kMODOneShotLoops); playBehaviour.set(kMODIgnorePanning); playBehaviour.set(kMODSampleSwap); playBehaviour.set(kMODOutOfRangeNoteDelay); playBehaviour.set(kMODTempoOnSecondTick); playBehaviour.set(kRowDelayWithNoteDelay); break; default: playBehaviour.set(MSF_COMPATIBLE_PLAY); playBehaviour.set(kHertzInLinearMode); playBehaviour.set(kTempoClamp); playBehaviour.set(kPanOverride); break; } return playBehaviour; } PlayBehaviourSet CSoundFile::GetDefaultPlaybackBehaviour(MODTYPE type) { PlayBehaviourSet playBehaviour; switch(type) { case MOD_TYPE_MPT: playBehaviour.set(kHertzInLinearMode); playBehaviour.set(kPerChannelGlobalVolSlide); playBehaviour.set(kPanOverride); playBehaviour.set(kITMultiSampleBehaviour); playBehaviour.set(kITSampleAndHoldPanbrello); playBehaviour.set(kITPanbrelloHold); break; case MOD_TYPE_XM: playBehaviour = GetSupportedPlaybackBehaviour(type); // Only set this explicitely for FT2-made XMs. playBehaviour.reset(kFT2VolumeRamping); break; case MOD_TYPE_MOD: playBehaviour.set(kMODSampleSwap); playBehaviour.set(kRowDelayWithNoteDelay); break; default: playBehaviour = GetSupportedPlaybackBehaviour(type); break; } return playBehaviour; } MODTYPE CSoundFile::GetBestSaveFormat() const { switch(GetType()) { case MOD_TYPE_MOD: case MOD_TYPE_S3M: case MOD_TYPE_XM: case MOD_TYPE_IT: case MOD_TYPE_MPT: return GetType(); case MOD_TYPE_AMF0: case MOD_TYPE_DIGI: case MOD_TYPE_SFX: case MOD_TYPE_STP: return MOD_TYPE_MOD; case MOD_TYPE_MED: if(m_nDefaultTempo == TEMPO(125, 0) && m_nDefaultSpeed == 6 && !m_nInstruments) { for(const auto &pat : Patterns) { if(pat.IsValid() && pat.GetNumRows() != 64) return MOD_TYPE_XM; } return MOD_TYPE_MOD; } return MOD_TYPE_XM; case MOD_TYPE_PSM: if(GetNumChannels() > 16) return MOD_TYPE_IT; for(CHANNELINDEX i = 0; i < GetNumChannels(); i++) { if(ChnSettings[i].dwFlags[CHN_SURROUND] || ChnSettings[i].nVolume != 64) { return MOD_TYPE_IT; break; } } return MOD_TYPE_S3M; case MOD_TYPE_669: case MOD_TYPE_FAR: case MOD_TYPE_STM: case MOD_TYPE_DSM: case MOD_TYPE_AMF: case MOD_TYPE_MTM: return MOD_TYPE_S3M; case MOD_TYPE_AMS: case MOD_TYPE_AMS2: case MOD_TYPE_DMF: case MOD_TYPE_DBM: case MOD_TYPE_IMF: case MOD_TYPE_J2B: case MOD_TYPE_ULT: case MOD_TYPE_OKT: case MOD_TYPE_MT2: case MOD_TYPE_MDL: case MOD_TYPE_PTM: case MOD_TYPE_DTM: default: return MOD_TYPE_IT; case MOD_TYPE_MID: return MOD_TYPE_MPT; } } const char *CSoundFile::GetSampleName(SAMPLEINDEX nSample) const { MPT_ASSERT(nSample <= GetNumSamples()); if (nSample < MAX_SAMPLES) { return m_szNames[nSample]; } else { return ""; } } const char *CSoundFile::GetInstrumentName(INSTRUMENTINDEX nInstr) const { if((nInstr >= MAX_INSTRUMENTS) || (!Instruments[nInstr])) return ""; MPT_ASSERT(nInstr <= GetNumInstruments()); return Instruments[nInstr]->name; } bool CSoundFile::InitChannel(CHANNELINDEX nChn) { if(nChn >= MAX_BASECHANNELS) return true; ChnSettings[nChn].Reset(); m_PlayState.Chn[nChn].Reset(ModChannel::resetTotal, *this, nChn); #ifdef MODPLUG_TRACKER if(GetpModDoc() != nullptr) { GetpModDoc()->Record1Channel(nChn, false); GetpModDoc()->Record2Channel(nChn, false); } #endif // MODPLUG_TRACKER #ifdef MODPLUG_TRACKER m_bChannelMuteTogglePending[nChn] = false; #endif // MODPLUG_TRACKER return false; } void CSoundFile::InitAmigaResampler() { if(m_SongFlags[SONG_ISAMIGA] && m_Resampler.m_Settings.emulateAmiga) { const Paula::State defaultState(GetSampleRate()); for(auto &chn : m_PlayState.Chn) { chn.paulaState = defaultState; } } } // Detect samples that are referenced by an instrument, but actually not used in a song. // Only works in instrument mode. Unused samples are marked as false in the vector. SAMPLEINDEX CSoundFile::DetectUnusedSamples(std::vector &sampleUsed) const { sampleUsed.assign(GetNumSamples() + 1, false); if(GetNumInstruments() == 0) { return 0; } SAMPLEINDEX unused = 0; std::vector lastIns; for(const auto &pat : Patterns) if(pat.IsValid()) { lastIns.assign(GetNumChannels(), 0); auto p = pat.cbegin(); for(ROWINDEX row = 0; row < pat.GetNumRows(); row++) { for(CHANNELINDEX c = 0; c < GetNumChannels(); c++, p++) { if(p->IsNote()) { ModCommand::INSTR instr = p->instr; if(!p->instr) instr = lastIns[c]; if (instr) { if(IsInRange(instr, (INSTRUMENTINDEX)0, MAX_INSTRUMENTS)) { ModInstrument *pIns = Instruments[p->instr]; if (pIns) { SAMPLEINDEX n = pIns->Keyboard[p->note - NOTE_MIN]; if (n <= GetNumSamples()) sampleUsed[n] = true; } } lastIns[c] = instr; } else { // No idea which instrument this note belongs to, so mark it used in any instruments. for (INSTRUMENTINDEX k = GetNumInstruments(); k >= 1; k--) { ModInstrument *pIns = Instruments[k]; if (pIns) { SAMPLEINDEX n = pIns->Keyboard[p->note - NOTE_MIN]; if (n <= GetNumSamples()) sampleUsed[n] = true; } } } } } } } for (SAMPLEINDEX ichk = GetNumSamples(); ichk >= 1; ichk--) { if ((!sampleUsed[ichk]) && (Samples[ichk].pSample)) unused++; } return unused; } // Destroy samples where keepSamples index is false. First sample is keepSamples[1]! SAMPLEINDEX CSoundFile::RemoveSelectedSamples(const std::vector &keepSamples) { if(keepSamples.empty()) { return 0; } SAMPLEINDEX nRemoved = 0; for(SAMPLEINDEX nSmp = std::min(GetNumSamples(), static_cast(keepSamples.size() - 1)); nSmp >= 1; nSmp--) { if(!keepSamples[nSmp]) { CriticalSection cs; #ifdef MODPLUG_TRACKER if(GetpModDoc()) { GetpModDoc()->GetSampleUndo().PrepareUndo(nSmp, sundo_replace, "Remove Sample"); } #endif // MODPLUG_TRACKER if(DestroySample(nSmp)) { strcpy(m_szNames[nSmp], ""); nRemoved++; } if((nSmp == GetNumSamples()) && (nSmp > 1)) m_nSamples--; } } return nRemoved; } bool CSoundFile::DestroySample(SAMPLEINDEX nSample) { if(!nSample || nSample >= MAX_SAMPLES) { return false; } if(Samples[nSample].pSample == nullptr) { return true; } ModSample &sample = Samples[nSample]; for(auto &chn : m_PlayState.Chn) { if(chn.pModSample == &sample) { chn.position.Set(0); chn.nLength = 0; chn.pCurrentSample = nullptr; } } sample.FreeSample(); sample.nLength = 0; sample.uFlags.reset(CHN_16BIT | CHN_STEREO); #ifdef MODPLUG_TRACKER ResetSamplePath(nSample); #endif return true; } bool CSoundFile::DestroySampleThreadsafe(SAMPLEINDEX nSample) { CriticalSection cs; return DestroySample(nSample); } CTuning* CSoundFile::CreateTuning12TET(const std::string &name) { CTuning* pT = CTuning::CreateGeometric(name, 12, 2, 15); for(ModCommand::NOTE note = 0; note < 12; ++note) { pT->SetNoteName(note, NoteNamesSharp[note]); } return pT; } std::string CSoundFile::GetNoteName(const ModCommand::NOTE note, const INSTRUMENTINDEX inst) const { // For MPTM instruments with custom tuning, find the appropriate note name. Else, use default note names. if(ModCommand::IsNote(note) && GetType() == MOD_TYPE_MPT && inst >= 1 && inst <= GetNumInstruments() && Instruments[inst] && Instruments[inst]->pTuning) { return Instruments[inst]->pTuning->GetNoteName(note - NOTE_MIDDLEC); } else { return GetNoteName(note); } } std::string CSoundFile::GetNoteName(const ModCommand::NOTE note) const { return GetNoteName(note, m_NoteNames); } std::string CSoundFile::GetNoteName(const ModCommand::NOTE note, const char (*noteNames)[4]) { if(ModCommand::IsSpecialNote(note)) { const char specialNoteNames[][4] = { "PCs", "PC ", "~~~", "^^^", "===" }; STATIC_ASSERT(CountOf(specialNoteNames) == NOTE_MAX_SPECIAL - NOTE_MIN_SPECIAL + 1); return specialNoteNames[note - NOTE_MIN_SPECIAL]; } else if(ModCommand::IsNote(note)) { return std::string() .append(noteNames[(note - NOTE_MIN) % 12]) .append(1, '0' + (note - NOTE_MIN) / 12) ; // e.g. "C#" + "5" } else if(note == NOTE_NONE) { return "..."; } return "???"; } #ifdef MODPLUG_TRACKER void CSoundFile::SetDefaultNoteNames() { m_NoteNames = TrackerSettings::Instance().accidentalFlats ? NoteNamesFlat : NoteNamesSharp; } const NoteName *CSoundFile::GetDefaultNoteNames() { return m_NoteNames; } #endif // MODPLUG_TRACKER void CSoundFile::SetModSpecsPointer(const CModSpecifications*& pModSpecs, const MODTYPE type) { switch(type) { case MOD_TYPE_MPT: pModSpecs = &ModSpecs::mptm; break; case MOD_TYPE_IT: pModSpecs = &ModSpecs::itEx; break; case MOD_TYPE_XM: pModSpecs = &ModSpecs::xmEx; break; case MOD_TYPE_S3M: pModSpecs = &ModSpecs::s3mEx; break; case MOD_TYPE_MOD: default: pModSpecs = &ModSpecs::mod; break; } } void CSoundFile::SetType(MODTYPE type) { m_nType = type; m_playBehaviour = GetDefaultPlaybackBehaviour(GetBestSaveFormat()); SetModSpecsPointer(m_pModSpecs, GetBestSaveFormat()); } #ifdef MODPLUG_TRACKER void CSoundFile::ChangeModTypeTo(const MODTYPE& newType) { const MODTYPE oldtype = GetType(); m_nType = newType; SetModSpecsPointer(m_pModSpecs, m_nType); if(oldtype == newType) return; SetupMODPanning(); // Setup LRRL panning scheme if needed // Only keep supported play behaviour flags PlayBehaviourSet oldAllowedFlags = GetSupportedPlaybackBehaviour(oldtype); PlayBehaviourSet newAllowedFlags = GetSupportedPlaybackBehaviour(newType); PlayBehaviourSet newDefaultFlags = GetDefaultPlaybackBehaviour(newType); for(size_t i = 0; i < m_playBehaviour.size(); i++) { // If a flag is supported in both formats, keep its status if(m_playBehaviour[i]) m_playBehaviour.set(i, newAllowedFlags[i]); // Set allowed flags to their defaults if they were not supported in the old format if(!oldAllowedFlags[i]) m_playBehaviour.set(i, newDefaultFlags[i]); } Order.OnModTypeChanged(oldtype); Patterns.OnModTypeChanged(oldtype); } #endif // MODPLUG_TRACKER bool CSoundFile::SetTitle(const std::string &newTitle) { if(m_songName != newTitle) { m_songName = newTitle; return true; } return false; } double CSoundFile::GetPlaybackTimeAt(ORDERINDEX ord, ROWINDEX row, bool updateVars, bool updateSamplePos) { const GetLengthType t = GetLength(updateVars ? (updateSamplePos ? eAdjustSamplePositions : eAdjust) : eNoAdjust, GetLengthTarget(ord, row)).back(); if(t.targetReached) return t.duration; else return -1; //Given position not found from play sequence. } // Calculate the length of a tick, depending on the tempo mode. // This differs from GetTickDuration() by not accumulating errors // because this is not called once per tick but in unrelated // circumstances. So this should not update error accumulation. void CSoundFile::RecalculateSamplesPerTick() { switch(m_nTempoMode) { case tempoModeClassic: default: m_PlayState.m_nSamplesPerTick = Util::muldiv(m_MixerSettings.gdwMixingFreq, 5 * TEMPO::fractFact, std::max(TEMPO::store_t(1), m_PlayState.m_nMusicTempo.GetRaw() << 1)); break; case tempoModeModern: m_PlayState.m_nSamplesPerTick = static_cast((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()))); break; case tempoModeAlternative: m_PlayState.m_nSamplesPerTick = Util::muldiv(m_MixerSettings.gdwMixingFreq, TEMPO::fractFact, std::max(TEMPO::store_t(1), m_PlayState.m_nMusicTempo.GetRaw())); break; } #ifndef MODPLUG_TRACKER m_PlayState.m_nSamplesPerTick = Util::muldivr(m_PlayState.m_nSamplesPerTick, m_nTempoFactor, 65536); #endif // !MODPLUG_TRACKER if(!m_PlayState.m_nSamplesPerTick) m_PlayState.m_nSamplesPerTick = 1; } // Get length of a tick in sample, with tick-to-tick tempo correction in modern tempo mode. // This has to be called exactly once per tick because otherwise the error accumulation // goes wrong. uint32 CSoundFile::GetTickDuration(PlayState &playState) const { uint32 retval = 0; switch(m_nTempoMode) { case tempoModeClassic: default: retval = Util::muldiv(m_MixerSettings.gdwMixingFreq, 5 * TEMPO::fractFact, std::max(TEMPO::store_t(1), playState.m_nMusicTempo.GetRaw() << 1)); break; case tempoModeAlternative: retval = Util::muldiv(m_MixerSettings.gdwMixingFreq, TEMPO::fractFact, std::max(TEMPO::store_t(1), playState.m_nMusicTempo.GetRaw())); break; case tempoModeModern: { double accurateBufferCount = static_cast(m_MixerSettings.gdwMixingFreq) * (60.0 / (playState.m_nMusicTempo.ToDouble() * Util::mul32to64_unsigned(playState.m_nMusicSpeed, playState.m_nCurrentRowsPerBeat))); const TempoSwing &swing = (Patterns.IsValidPat(playState.m_nPattern) && Patterns[playState.m_nPattern].HasTempoSwing()) ? Patterns[playState.m_nPattern].GetTempoSwing() : m_tempoSwing; if(!swing.empty()) { // Apply current row's tempo swing factor TempoSwing::value_type swingFactor = swing[playState.m_nRow % swing.size()]; accurateBufferCount = accurateBufferCount * swingFactor / double(TempoSwing::Unity); } uint32 bufferCount = static_cast(accurateBufferCount); playState.m_dBufferDiff += accurateBufferCount - bufferCount; //tick-to-tick tempo correction: if(playState.m_dBufferDiff >= 1) { bufferCount++; playState.m_dBufferDiff--; } else if(m_PlayState.m_dBufferDiff <= -1) { bufferCount--; playState.m_dBufferDiff++; } MPT_ASSERT(mpt::abs(playState.m_dBufferDiff) < 1.0); retval = bufferCount; } break; } #ifndef MODPLUG_TRACKER // when the user modifies the tempo, we do not really care about accurate tempo error accumulation retval = Util::muldivr_unsigned(retval, m_nTempoFactor, 65536); #endif // !MODPLUG_TRACKER if(!retval) retval = 1; return retval; } // Get the duration of a row in milliseconds, based on the current rows per beat and given speed and tempo settings. double CSoundFile::GetRowDuration(TEMPO tempo, uint32 speed) const { switch(m_nTempoMode) { case tempoModeClassic: default: return static_cast(2500 * speed) / tempo.ToDouble(); case tempoModeModern: { // If there are any row delay effects, the row length factor compensates for those. return 60000.0 / tempo.ToDouble() / static_cast(m_PlayState.m_nCurrentRowsPerBeat); } case tempoModeAlternative: return static_cast(1000 * speed) / tempo.ToDouble(); } } const CModSpecifications& CSoundFile::GetModSpecifications(const MODTYPE type) { const CModSpecifications* p = nullptr; SetModSpecsPointer(p, type); return *p; } // Find an unused sample slot. If it is going to be assigned to an instrument, targetInstrument should be specified. // SAMPLEINDEX_INVLAID is returned if no free sample slot could be found. SAMPLEINDEX CSoundFile::GetNextFreeSample(INSTRUMENTINDEX targetInstrument, SAMPLEINDEX start) const { // Find empty slot in two passes - in the first pass, we only search for samples with empty sample names, // in the second pass we check all samples with non-empty sample names. for(int passes = 0; passes < 2; passes++) { for(SAMPLEINDEX i = start; i <= GetModSpecifications().samplesMax; i++) { // When loading into an instrument, ignore non-empty sample names. Else, only use this slot if the sample name is empty or we're in second pass. if((i > GetNumSamples() && passes == 1) || (Samples[i].pSample == nullptr && (!m_szNames[i][0] || passes == 1 || targetInstrument != INSTRUMENTINDEX_INVALID)) || (targetInstrument != INSTRUMENTINDEX_INVALID && IsSampleReferencedByInstrument(i, targetInstrument))) // Not empty, but already used by this instrument. XXX this should only be done when replacing an instrument with a single sample! Otherwise it will use an inconsistent sample map! { // Empty slot, so it's a good candidate already. // In instrument mode, check whether any instrument references this sample slot. If that is the case, we won't use it as it could lead to unwanted conflicts. // If we are loading the sample *into* an instrument, we should also not consider that instrument's sample map, since it might be inconsistent at this time. bool isReferenced = false; for(INSTRUMENTINDEX ins = 1; ins <= GetNumInstruments(); ins++) { if(ins == targetInstrument) { continue; } if(IsSampleReferencedByInstrument(i, ins)) { isReferenced = true; break; } } if(!isReferenced) { return i; } } } } return SAMPLEINDEX_INVALID; } // Find an unused instrument slot. // INSTRUMENTINDEX_INVALID is returned if no free instrument slot could be found. INSTRUMENTINDEX CSoundFile::GetNextFreeInstrument(INSTRUMENTINDEX start) const { for(INSTRUMENTINDEX i = start; i <= GetModSpecifications().instrumentsMax; i++) { if(Instruments[i] == nullptr) { return i; } } return INSTRUMENTINDEX_INVALID; } // Check whether a given sample is used by a given instrument. bool CSoundFile::IsSampleReferencedByInstrument(SAMPLEINDEX sample, INSTRUMENTINDEX instr) const { ModInstrument *targetIns = nullptr; if(instr > 0 && instr <= GetNumInstruments()) { targetIns = Instruments[instr]; } if(targetIns != nullptr) { for(size_t note = 0; note < NOTE_MAX /*CountOf(targetIns->Keyboard)*/; note++) { if(targetIns->Keyboard[note] == sample) { return true; } } } return false; } ModInstrument *CSoundFile::AllocateInstrument(INSTRUMENTINDEX instr, SAMPLEINDEX assignedSample) { if(instr == 0 || instr >= MAX_INSTRUMENTS) { return nullptr; } ModInstrument *ins = Instruments[instr]; if(ins != nullptr) { // Re-initialize instrument *ins = ModInstrument(assignedSample); } else { // Create new instrument Instruments[instr] = ins = new (std::nothrow) ModInstrument(assignedSample); } if(ins != nullptr) { m_nInstruments = std::max(m_nInstruments, instr); } return ins; } void CSoundFile::PrecomputeSampleLoops(bool updateChannels) { for(SAMPLEINDEX i = 1; i <= GetNumSamples(); i++) { Samples[i].PrecomputeLoops(*this, updateChannels); } } #ifdef MPT_EXTERNAL_SAMPLES // Load external waveform, but keep sample properties like frequency, panning, etc... // Returns true if the file could be loaded. bool CSoundFile::LoadExternalSample(SAMPLEINDEX smp, const mpt::PathString &filename) { bool ok = false; InputFile f(filename); if(f.IsValid()) { const ModSample origSample = Samples[smp]; char origName[MAX_SAMPLENAME]; mpt::String::Copy(origName, m_szNames[smp]); FileReader file = GetFileReader(f); ok = ReadSampleFromFile(smp, file, false); if(ok) { // Copy over old attributes, but keep new sample data ModSample &sample = GetSample(smp); SmpLength newLength = sample.nLength; void *newData = sample.pSample; SampleFlags newFlags = sample.uFlags; sample = origSample; sample.nLength = newLength; sample.pSample = newData; sample.uFlags.set(CHN_16BIT, newFlags[CHN_16BIT]); sample.uFlags.set(CHN_STEREO, newFlags[CHN_STEREO]); sample.uFlags.reset(SMP_MODIFIED); sample.SanitizeLoops(); } mpt::String::Copy(m_szNames[smp], origName); } SetSamplePath(smp, filename); return ok; } #endif // MPT_EXTERNAL_SAMPLES // Set up channel panning and volume suitable for MOD + similar files. If the current mod type is not MOD, bForceSetup has to be set to true. void CSoundFile::SetupMODPanning(bool bForceSetup) { // Setup LRRL panning, max channel volume if(!(GetType() & MOD_TYPE_MOD) && bForceSetup == false) return; for(CHANNELINDEX nChn = 0; nChn < MAX_BASECHANNELS; nChn++) { ChnSettings[nChn].nVolume = 64; ChnSettings[nChn].dwFlags.reset(CHN_SURROUND); if(m_MixerSettings.MixerFlags & SNDMIX_MAXDEFAULTPAN) ChnSettings[nChn].nPan = (((nChn & 3) == 1) || ((nChn & 3) == 2)) ? 256 : 0; else ChnSettings[nChn].nPan = (((nChn & 3) == 1) || ((nChn & 3) == 2)) ? 0xC0 : 0x40; } } void CSoundFile::PropagateXMAutoVibrato(INSTRUMENTINDEX ins, uint8 type, uint8 sweep, uint8 depth, uint8 rate) { if(ins > m_nInstruments || Instruments[ins] == nullptr) return; const std::set referencedSamples = Instruments[ins]->GetSamples(); // Propagate changes to all samples that belong to this instrument. for(auto sample : referencedSamples) { if(sample <= m_nSamples) { Samples[sample].nVibDepth = depth; Samples[sample].nVibType = type; Samples[sample].nVibRate = rate; Samples[sample].nVibSweep = sweep; } } } // Normalize the tempo swing coefficients so that they add up to exactly the specified tempo again void TempoSwing::Normalize() { if(empty()) return; uint64 sum = 0; for(auto &i : *this) { Limit(i, Unity / 4u, Unity * 4u); sum += i; } sum /= size(); int64 remain = Unity * size(); for(auto &i : *this) { i = Util::muldivr_unsigned(i, Unity, static_cast(sum)); remain -= i; } //MPT_ASSERT(static_cast(mpt::abs(static_cast(remain))) <= size()); at(0) += static_cast(remain); } void TempoSwing::Serialize(std::ostream &oStrm, const TempoSwing &swing) { mpt::IO::WriteIntLE(oStrm, static_cast(swing.size())); for(std::size_t i = 0; i < swing.size(); i++) { mpt::IO::WriteIntLE(oStrm, swing[i]); } } void TempoSwing::Deserialize(std::istream &iStrm, TempoSwing &swing, const size_t) { uint16 numEntries; mpt::IO::ReadIntLE(iStrm, numEntries); swing.resize(numEntries); for(uint16 i = 0; i < numEntries; i++) { mpt::IO::ReadIntLE(iStrm, swing[i]); } swing.Normalize(); } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Fastmix.cpp0000644000372100037210000005275013161656666020245 00000000000000/* * Fastmix.cpp * ----------- * Purpose: Mixer core for rendering samples, mixing plugins, etc... * Notes : If this is Fastmix.cpp, where is Slowmix.cpp? :) * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ // FIXME: // - Playing samples backwards should reverse interpolation LUTs for interpolation modes // with more than two taps since they're not symmetric. We might need separate LUTs // because otherwise we will add tons of branches. // - Loop wraparound works pretty well in general, but not at the start of bidi samples. // - The loop lookahead stuff might still fail for samples with backward loops. #include "stdafx.h" #include "Sndfile.h" #include "MixerLoops.h" #include "MixFuncTable.h" #include // For FLT_EPSILON #include "plugins/PlugInterface.h" #include OPENMPT_NAMESPACE_BEGIN ///////////////////////////////////////////////////////////////////////// struct MixLoopState { const int8 * samplePointer; const int8 * lookaheadPointer; SmpLength lookaheadStart; uint32 maxSamples; MixLoopState(const ModChannel &chn) { UpdateLookaheadPointers(chn); // For platforms that have no fast 64-bit division, precompute this constant // as it won't change during the invocation of CreateStereoMix. SamplePosition increment = chn.increment; if(increment.IsNegative()) increment.Negate(); maxSamples = 16384u / (increment.GetUInt() + 1u); if(maxSamples < 2) maxSamples = 2; } // Calculate offset of loop wrap-around buffer for this sample. void UpdateLookaheadPointers(const ModChannel &chn) { samplePointer = static_cast(chn.pCurrentSample); lookaheadPointer = nullptr; if(chn.nLoopEnd < InterpolationMaxLookahead) lookaheadStart = chn.nLoopStart; else lookaheadStart = std::max(chn.nLoopStart, chn.nLoopEnd - InterpolationMaxLookahead); // We only need to apply the loop wrap-around logic if the sample is actually looping and if interpolation is applied. // If there is no interpolation happening, there is no lookahead happening the sample read-out is exact. if(chn.dwFlags[CHN_LOOP] && chn.resamplingMode != SRCMODE_NEAREST) { const bool inSustainLoop = chn.InSustainLoop(); // Do not enable wraparound magic if we're previewing a custom loop! if(inSustainLoop || chn.nLoopEnd == chn.pModSample->nLoopEnd) { SmpLength lookaheadOffset = 3 * InterpolationMaxLookahead + chn.pModSample->nLength - chn.nLoopEnd; if(inSustainLoop) { lookaheadOffset += 4 * InterpolationMaxLookahead; } lookaheadPointer = samplePointer + lookaheadOffset * chn.pModSample->GetBytesPerSample(); } } } // Returns the buffer length required to render a certain amount of samples, based on the channel's playback speed. static MPT_FORCEINLINE uint32 DistanceToBufferLength(SamplePosition from, SamplePosition to, SamplePosition inc) { return static_cast((to - from - SamplePosition(1)) / inc) + 1; } // Check how many samples can be rendered without encountering loop or sample end, and also update loop position / direction MPT_FORCEINLINE uint32 GetSampleCount(ModChannel &chn, uint32 nSamples, bool ITPingPongMode) const { int32 nLoopStart = chn.dwFlags[CHN_LOOP] ? chn.nLoopStart : 0; SamplePosition nInc = chn.increment; if ((nSamples <= 0) || nInc.IsZero() || (!chn.nLength)) return 0; // Part 1: Making sure the play position is valid, and if necessary, invert the play direction in case we reached a loop boundary of a ping-pong loop. chn.pCurrentSample = samplePointer; // Under zero ? if (chn.position.GetInt() < nLoopStart) { if (nInc.IsNegative()) { // Invert loop for bidi loops chn.position = SamplePosition(nLoopStart + nLoopStart, 0) - chn.position; if ((chn.position.GetInt() < nLoopStart) || (chn.position.GetUInt() >= (nLoopStart + chn.nLength) / 2)) { chn.position.Set(nLoopStart, 0); } nInc.Negate(); chn.increment = nInc; if(chn.dwFlags[CHN_PINGPONGLOOP]) { chn.dwFlags.reset(CHN_PINGPONGFLAG); // go forward } else { chn.dwFlags.set(CHN_PINGPONGFLAG); chn.position.SetInt(chn.nLength - 1); chn.increment.Negate(); } if(!chn.dwFlags[CHN_LOOP] || chn.position.GetUInt() >= chn.nLength) { chn.position.Set(chn.nLength); return 0; } } else { // We probably didn't hit the loop end yet (first loop), so we do nothing if (chn.position.GetInt() < 0) chn.position.SetInt(0); } } else if (chn.position.GetUInt() >= chn.nLength) { // Past the end if(!chn.dwFlags[CHN_LOOP]) return 0; // not looping -> stop this channel if(chn.dwFlags[CHN_PINGPONGLOOP]) { // Invert loop if (nInc.IsPositive()) { nInc.Negate(); chn.increment = nInc; } chn.dwFlags.set(CHN_PINGPONGFLAG); // adjust loop position SamplePosition invFract = chn.position.GetInvertedFract(); chn.position = SamplePosition(chn.nLength - (chn.position.GetInt() - chn.nLength) - invFract.GetInt(), invFract.GetFract()); if ((chn.position.GetUInt() <= chn.nLoopStart) || (chn.position.GetUInt() >= chn.nLength)) { // Impulse Tracker's software mixer would put a -2 (instead of -1) in the following line (doesn't happen on a GUS) chn.position.SetInt(chn.nLength - std::min(chn.nLength, ITPingPongMode ? 2 : 1)); } } else { if (nInc.IsNegative()) // This is a bug { nInc.Negate(); chn.increment = nInc; } // Restart at loop start chn.position += SamplePosition(nLoopStart - chn.nLength, 0); MPT_ASSERT(chn.position.GetInt() >= nLoopStart); // Interpolate correctly after wrapping around chn.dwFlags.set(CHN_WRAPPED_LOOP); } } // Part 2: Compute how many samples we can render until we reach the end of sample / loop boundary / etc. SamplePosition nPos = chn.position; // too big increment, and/or too small loop length if (nPos.GetInt() < nLoopStart) { if (nPos.IsNegative() || nInc.IsNegative()) return 0; } if (nPos.IsNegative() || nPos.GetUInt() >= chn.nLength) return 0; uint32 nSmpCount = nSamples; SamplePosition nInv = nInc; if (nInc.IsNegative()) { nInv.Negate(); } LimitMax(nSamples, maxSamples); SamplePosition incSamples = nInc * (nSamples - 1); int32 nPosDest = (nPos + incSamples).GetInt(); const SmpLength nPosInt = nPos.GetUInt(); const bool isAtLoopStart = (nPosInt >= chn.nLoopStart && nPosInt < chn.nLoopStart + InterpolationMaxLookahead); if(!isAtLoopStart) { chn.dwFlags.reset(CHN_WRAPPED_LOOP); } // Loop wrap-around magic. bool checkDest = true; if(lookaheadPointer != nullptr) { if(nPos.GetUInt() >= lookaheadStart) { #if 0 const uint32 oldCount = nSmpCount; // When going backwards - we can only go back up to lookaheadStart. // When going forwards - read through the whole pre-computed wrap-around buffer if possible. // TODO: ProTracker sample swapping needs hard cut at sample end. int32 samplesToRead = nInc.IsNegative() ? (nPosInt - lookaheadStart) //: 2 * InterpolationMaxLookahead - (nPosInt - mixLoopState.lookaheadStart); : (chn.nLoopEnd - nPosInt); //LimitMax(samplesToRead, chn.nLoopEnd - chn.nLoopStart); nSmpCount = SamplesToBufferLength(samplesToRead, chn); Limit(nSmpCount, 1u, oldCount); #else if (nInc.IsNegative()) { nSmpCount = DistanceToBufferLength(SamplePosition(lookaheadStart, 0), nPos, nInv); } else { nSmpCount = DistanceToBufferLength(nPos, SamplePosition(chn.nLoopEnd, 0), nInv); } #endif chn.pCurrentSample = lookaheadPointer; checkDest = false; } else if(chn.dwFlags[CHN_WRAPPED_LOOP] && isAtLoopStart) { // We just restarted the loop, so interpolate correctly after wrapping around nSmpCount = DistanceToBufferLength(nPos, SamplePosition(nLoopStart + InterpolationMaxLookahead, 0), nInv); chn.pCurrentSample = lookaheadPointer + (chn.nLoopEnd - nLoopStart) * chn.pModSample->GetBytesPerSample(); checkDest = false; } else if(nInc.IsPositive() && static_cast(nPosDest) >= lookaheadStart && nSmpCount > 1) { // We shouldn't read that far if we're not using the pre-computed wrap-around buffer. nSmpCount = DistanceToBufferLength(nPos, SamplePosition(lookaheadStart, 0), nInv); checkDest = false; } } if(checkDest) { // Fix up sample count if target position is invalid if (nInc.IsNegative()) { if (nPosDest < nLoopStart) { nSmpCount = DistanceToBufferLength(SamplePosition(chn.nLoopStart, 0), nPos, nInv); } } else { if (nPosDest >= (int32)chn.nLength) { nSmpCount = DistanceToBufferLength(nPos, SamplePosition(chn.nLength, 0), nInv); } } } Limit(nSmpCount, 1u, nSamples); #ifdef _DEBUG { SmpLength posDest = (nPos + nInc * (nSmpCount - 1)).GetUInt(); if (posDest < 0 || posDest > chn.nLength) { // We computed an invalid delta! MPT_ASSERT_NOTREACHED(); return 0; } } #endif return nSmpCount; } }; // Render count * number of channels samples void CSoundFile::CreateStereoMix(int count) { mixsample_t *pOfsL, *pOfsR; if (!count) return; // Resetting sound buffer StereoFill(MixSoundBuffer, count, gnDryROfsVol, gnDryLOfsVol); if(m_MixerSettings.gnChannels > 2) InitMixBuffer(MixRearBuffer, count*2); CHANNELINDEX nchmixed = 0; const bool ITPingPongMode = m_playBehaviour[kITPingPongMode]; for(uint32 nChn = 0; nChn < m_nMixChannels; nChn++) { ModChannel &chn = m_PlayState.Chn[m_PlayState.ChnMix[nChn]]; if(!chn.pCurrentSample) continue; pOfsR = &gnDryROfsVol; pOfsL = &gnDryLOfsVol; uint32 functionNdx = MixFuncTable::ResamplingModeToMixFlags(static_cast(chn.resamplingMode)); if(chn.dwFlags[CHN_16BIT]) functionNdx |= MixFuncTable::ndx16Bit; if(chn.dwFlags[CHN_STEREO]) functionNdx |= MixFuncTable::ndxStereo; #ifndef NO_FILTER if(chn.dwFlags[CHN_FILTER]) functionNdx |= MixFuncTable::ndxFilter; #endif mixsample_t *pbuffer = MixSoundBuffer; #ifndef NO_REVERB if(((m_MixerSettings.DSPMask & SNDDSP_REVERB) && !chn.dwFlags[CHN_NOREVERB]) || chn.dwFlags[CHN_REVERB]) { pbuffer = m_Reverb.GetReverbSendBuffer(count); pOfsR = &m_Reverb.gnRvbROfsVol; pOfsL = &m_Reverb.gnRvbLOfsVol; } #endif if(chn.dwFlags[CHN_SURROUND] && m_MixerSettings.gnChannels > 2) pbuffer = MixRearBuffer; //Look for plugins associated with this implicit tracker channel. #ifndef NO_PLUGINS PLUGINDEX nMixPlugin = GetBestPlugin(m_PlayState.ChnMix[nChn], PrioritiseInstrument, RespectMutes); if ((nMixPlugin > 0) && (nMixPlugin <= MAX_MIXPLUGINS) && m_MixPlugins[nMixPlugin - 1].pMixPlugin != nullptr) { // Render into plugin buffer instead of global buffer SNDMIXPLUGINSTATE &mixState = m_MixPlugins[nMixPlugin - 1].pMixPlugin->m_MixState; if (mixState.pMixBuffer) { pbuffer = mixState.pMixBuffer; pOfsR = &mixState.nVolDecayR; pOfsL = &mixState.nVolDecayL; if (!(mixState.dwFlags & SNDMIXPLUGINSTATE::psfMixReady)) { StereoFill(pbuffer, count, *pOfsR, *pOfsL); mixState.dwFlags |= SNDMIXPLUGINSTATE::psfMixReady; } } } #endif // NO_PLUGINS MixLoopState mixLoopState(chn); //////////////////////////////////////////////////// CHANNELINDEX naddmix = 0; int nsamples = count; // Keep mixing this sample until the buffer is filled. do { uint32 nrampsamples = nsamples; int32 nSmpCount; if(chn.nRampLength > 0) { if (nrampsamples > chn.nRampLength) nrampsamples = chn.nRampLength; } if((nSmpCount = mixLoopState.GetSampleCount(chn, nrampsamples, ITPingPongMode)) <= 0) { // Stopping the channel chn.pCurrentSample = nullptr; chn.nLength = 0; chn.position.Set(0); chn.nRampLength = 0; EndChannelOfs(chn, pbuffer, nsamples); *pOfsR += chn.nROfs; *pOfsL += chn.nLOfs; chn.nROfs = chn.nLOfs = 0; chn.dwFlags.reset(CHN_PINGPONGFLAG); break; } // Should we mix this channel ? if((nchmixed >= m_MixerSettings.m_nMaxMixChannels) // Too many channels || (!chn.nRampLength && !(chn.leftVol | chn.rightVol))) // Channel is completely silent { chn.position += chn.increment * nSmpCount; chn.nROfs = chn.nLOfs = 0; pbuffer += nSmpCount * 2; naddmix = 0; } else { // Do mixing mixsample_t *pbufmax = pbuffer + (nSmpCount * 2); chn.nROfs = - *(pbufmax-2); chn.nLOfs = - *(pbufmax-1); #ifdef _DEBUG SamplePosition targetpos = chn.position + chn.increment * nSmpCount; #endif MixFuncTable::Functions[functionNdx | (chn.nRampLength ? MixFuncTable::ndxRamp : 0)](chn, m_Resampler, pbuffer, nSmpCount); #ifdef _DEBUG MPT_ASSERT(chn.position.GetUInt() == targetpos.GetUInt()); #endif chn.nROfs += *(pbufmax-2); chn.nLOfs += *(pbufmax-1); pbuffer = pbufmax; naddmix = 1; } nsamples -= nSmpCount; if (chn.nRampLength) { if (chn.nRampLength <= static_cast(nSmpCount)) { // Ramping is done chn.nRampLength = 0; chn.leftVol = chn.newLeftVol; chn.rightVol = chn.newRightVol; chn.rightRamp = chn.leftRamp = 0; if(chn.dwFlags[CHN_NOTEFADE] && !chn.nFadeOutVol) { chn.nLength = 0; chn.pCurrentSample = nullptr; } } else { chn.nRampLength -= nSmpCount; } } if(chn.position.GetUInt() >= chn.nLoopEnd && chn.dwFlags[CHN_LOOP]) { if(m_playBehaviour[kMODSampleSwap] && chn.nNewIns && chn.nNewIns <= GetNumSamples() && chn.pModSample != &Samples[chn.nNewIns]) { // ProTracker compatibility: Instrument changes without a note do not happen instantly, but rather when the sample loop has finished playing. // Test case: PTInstrSwap.mod const ModSample &smp = Samples[chn.nNewIns]; chn.pModSample = &smp; chn.pCurrentSample = smp.pSample; chn.dwFlags = (chn.dwFlags & CHN_CHANNELFLAGS) | smp.uFlags; chn.nLength = smp.uFlags[CHN_LOOP] ? smp.nLoopEnd : smp.nLength; chn.nLoopStart = smp.nLoopStart; chn.nLoopEnd = smp.nLoopEnd; chn.position.SetInt(chn.nLoopStart); mixLoopState.UpdateLookaheadPointers(chn); if(!chn.pCurrentSample) { break; } } else if(m_playBehaviour[kMODOneShotLoops] && chn.nLoopStart == 0) { // ProTracker "oneshot" loops (if loop start is 0, play the whole sample once and then repeat until loop end) chn.position.SetInt(0); chn.nLoopEnd = chn.nLength = chn.pModSample->nLoopEnd; } } } while(nsamples > 0); // Restore sample pointer in case it got changed through loop wrap-around chn.pCurrentSample = mixLoopState.samplePointer; nchmixed += naddmix; #ifndef NO_PLUGINS if(naddmix && nMixPlugin > 0 && nMixPlugin <= MAX_MIXPLUGINS && m_MixPlugins[nMixPlugin - 1].pMixPlugin) { m_MixPlugins[nMixPlugin - 1].pMixPlugin->ResetSilence(); } #endif // NO_PLUGINS } m_nMixStat = std::max(m_nMixStat, nchmixed); } void CSoundFile::ProcessPlugins(uint32 nCount) { #ifndef NO_PLUGINS // If any sample channels are active or any plugin has some input, possibly suspended master plugins need to be woken up. bool masterHasInput = (m_nMixStat > 0); #ifdef MPT_INTMIXER const float IntToFloat = m_PlayConfig.getIntToFloat(); const float FloatToInt = m_PlayConfig.getFloatToInt(); #endif // MPT_INTMIXER // Setup float inputs from samples for(PLUGINDEX plug = 0; plug < MAX_MIXPLUGINS; plug++) { SNDMIXPLUGIN &plugin = m_MixPlugins[plug]; if(plugin.pMixPlugin != nullptr && plugin.pMixPlugin->m_MixState.pMixBuffer != nullptr && plugin.pMixPlugin->m_mixBuffer.Ok()) { IMixPlugin *mixPlug = plugin.pMixPlugin; SNDMIXPLUGINSTATE &state = mixPlug->m_MixState; //We should only ever reach this point if the song is playing. if (!mixPlug->IsSongPlaying()) { //Plugin doesn't know it is in a song that is playing; //we must have added it during playback. Initialise it! mixPlug->NotifySongPlaying(true); mixPlug->Resume(); } // Setup float input float *plugInputL = mixPlug->m_mixBuffer.GetInputBuffer(0); float *plugInputR = mixPlug->m_mixBuffer.GetInputBuffer(1); if (state.dwFlags & SNDMIXPLUGINSTATE::psfMixReady) { #ifdef MPT_INTMIXER StereoMixToFloat(state.pMixBuffer, plugInputL, plugInputR, nCount, IntToFloat); #else DeinterleaveStereo(pState->pMixBuffer, plugInputL, plugInputR, nCount); #endif // MPT_INTMIXER } else if (state.nVolDecayR || state.nVolDecayL) { StereoFill(state.pMixBuffer, nCount, state.nVolDecayR, state.nVolDecayL); #ifdef MPT_INTMIXER StereoMixToFloat(state.pMixBuffer, plugInputL, plugInputR, nCount, IntToFloat); #else DeinterleaveStereo(pState->pMixBuffer, plugInputL, plugInputR, nCount); #endif // MPT_INTMIXER } else { memset(plugInputL, 0, nCount * sizeof(plugInputL[0])); memset(plugInputR, 0, nCount * sizeof(plugInputR[0])); } state.dwFlags &= ~SNDMIXPLUGINSTATE::psfMixReady; if(!plugin.IsMasterEffect() && !(state.dwFlags & SNDMIXPLUGINSTATE::psfSilenceBypass)) { masterHasInput = true; } } } // Convert mix buffer #ifdef MPT_INTMIXER StereoMixToFloat(MixSoundBuffer, MixFloatBuffer[0], MixFloatBuffer[1], nCount, IntToFloat); #else DeinterleaveStereo(MixSoundBuffer, MixFloatBuffer[0], MixFloatBuffer[1], nCount); #endif // MPT_INTMIXER float *pMixL = MixFloatBuffer[0]; float *pMixR = MixFloatBuffer[1]; const bool positionChanged = HasPositionChanged(); // Process Plugins for(PLUGINDEX plug = 0; plug < MAX_MIXPLUGINS; plug++) { SNDMIXPLUGIN &plugin = m_MixPlugins[plug]; if (plugin.pMixPlugin != nullptr && plugin.pMixPlugin->m_MixState.pMixBuffer != nullptr && plugin.pMixPlugin->m_mixBuffer.Ok()) { IMixPlugin *pObject = plugin.pMixPlugin; if(!plugin.IsMasterEffect() && !plugin.pMixPlugin->ShouldProcessSilence() && !(plugin.pMixPlugin->m_MixState.dwFlags & SNDMIXPLUGINSTATE::psfHasInput)) { // If plugin has no inputs and isn't a master plugin, we shouldn't let it process silence if possible. // I have yet to encounter a plugin which actually sets this flag. bool hasInput = false; for(PLUGINDEX inPlug = 0; inPlug < plug; inPlug++) { if(m_MixPlugins[inPlug].GetOutputPlugin() == plug) { hasInput = true; break; } } if(!hasInput) { continue; } } bool isMasterMix = false; float *plugInputL = pObject->m_mixBuffer.GetInputBuffer(0); float *plugInputR = pObject->m_mixBuffer.GetInputBuffer(1); if (pMixL == plugInputL) { isMasterMix = true; pMixL = MixFloatBuffer[0]; pMixR = MixFloatBuffer[1]; } SNDMIXPLUGINSTATE &state = plugin.pMixPlugin->m_MixState; float *pOutL = pMixL; float *pOutR = pMixR; if (!plugin.IsOutputToMaster()) { PLUGINDEX nOutput = plugin.GetOutputPlugin(); if(nOutput > plug && nOutput != PLUGINDEX_INVALID && m_MixPlugins[nOutput].pMixPlugin != nullptr) { IMixPlugin *outPlugin = m_MixPlugins[nOutput].pMixPlugin; if(!(state.dwFlags & SNDMIXPLUGINSTATE::psfSilenceBypass)) outPlugin->ResetSilence(); if(outPlugin->m_mixBuffer.Ok()) { pOutL = outPlugin->m_mixBuffer.GetInputBuffer(0); pOutR = outPlugin->m_mixBuffer.GetInputBuffer(1); } } } /* if (plugin.multiRouting) { int nOutput=0; for (int nOutput=0; nOutput < plugin.nOutputs / 2; nOutput++) { destinationPlug = plugin.multiRoutingDestinations[nOutput]; pOutState = m_MixPlugins[destinationPlug].pMixState; pOutputs[2 * nOutput] = plugInputL; pOutputs[2 * (nOutput + 1)] = plugInputR; } }*/ if (plugin.IsMasterEffect()) { if (!isMasterMix) { float *pInL = plugInputL; float *pInR = plugInputR; for (uint32 i=0; iResetSilence(); SNDMIXPLUGIN *chain = &plugin; PLUGINDEX out = chain->GetOutputPlugin(), prevOut = plug; while(out > prevOut && out < MAX_MIXPLUGINS) { chain = &m_MixPlugins[out]; prevOut = out; out = chain->GetOutputPlugin(); if(chain->pMixPlugin) { chain->pMixPlugin->ResetSilence(); } } } } if(plugin.IsBypassed() || (plugin.IsAutoSuspendable() && (state.dwFlags & SNDMIXPLUGINSTATE::psfSilenceBypass))) { const float * const pInL = plugInputL; const float * const pInR = plugInputR; for (uint32 i=0; iPositionChanged(); pObject->Process(pOutL, pOutR, nCount); state.inputSilenceCount += nCount; if(plugin.IsAutoSuspendable() && pObject->GetNumOutputChannels() > 0 && state.inputSilenceCount >= m_MixerSettings.gdwMixingFreq * 4) { bool isSilent = true; for(uint32 i = 0; i < nCount; i++) { if(pOutL[i] >= FLT_EPSILON || pOutL[i] <= -FLT_EPSILON || pOutR[i] >= FLT_EPSILON || pOutR[i] <= -FLT_EPSILON) { isSilent = false; break; } } if(isSilent) { state.dwFlags |= SNDMIXPLUGINSTATE::psfSilenceBypass; } else { state.inputSilenceCount = 0; } } } state.dwFlags &= ~SNDMIXPLUGINSTATE::psfHasInput; } } #ifdef MPT_INTMIXER FloatToStereoMix(pMixL, pMixR, MixSoundBuffer, nCount, FloatToInt); #else InterleaveStereo(pMixL, pMixR, MixSoundBuffer, nCount); #endif // MPT_INTMIXER #else MPT_UNREFERENCED_PARAMETER(nCount); #endif // NO_PLUGINS } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/mod_specifications.h0000644000372100037210000001132113161656666022126 00000000000000/* * mod_specifications.h * -------------------- * Purpose: Mod specifications characterise the features of every editable module format in OpenMPT, such as the number of supported channels, samples, effects, etc... * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "Snd_defs.h" #include "modcommand.h" // ModCommand:: #include "../soundlib/SoundFilePlayConfig.h" // mixlevel constants. OPENMPT_NAMESPACE_BEGIN struct CModSpecifications { /// Returns modtype corresponding to given file extension. The extension string /// may begin with or without dot, e.g. both ".it" and "it" will be handled correctly. static MODTYPE ExtensionToType(std::string ext); // Return true if format supports given note. bool HasNote(ModCommand::NOTE note) const; bool HasVolCommand(ModCommand::VOLCMD volcmd) const; bool HasCommand(ModCommand::COMMAND cmd) const; // Return corresponding effect letter for this format char GetEffectLetter(ModCommand::COMMAND cmd) const; char GetVolEffectLetter(ModCommand::VOLCMD cmd) const; // NOTE: If changing order, update all initializations in .cpp file. MODTYPE internalType; // Internal MODTYPE value const char *fileExtension; // File extension without dot. ModCommand::NOTE noteMin; // Minimum note index (index starts from 1) ModCommand::NOTE noteMax; // Maximum note index (index starts from 1) PATTERNINDEX patternsMax; ORDERINDEX ordersMax; SEQUENCEINDEX sequencesMax; CHANNELINDEX channelsMin; // Minimum number of editable channels in pattern. CHANNELINDEX channelsMax; // Maximum number of editable channels in pattern. uint32 tempoMinInt; uint32 tempoMaxInt; uint32 speedMin; // Minimum ticks per frame uint32 speedMax; // Maximum ticks per frame ROWINDEX patternRowsMin; ROWINDEX patternRowsMax; uint16 modNameLengthMax; // Meaning 'usable letters', possible null character is not included. uint16 sampleNameLengthMax; // Ditto uint16 sampleFilenameLengthMax; // Ditto uint16 instrNameLengthMax; // Ditto uint16 instrFilenameLengthMax; // Ditto uint16 commentLineLengthMax; // not including line break, 0 for unlimited SAMPLEINDEX samplesMax; // Max number of samples == Highest possible sample index INSTRUMENTINDEX instrumentsMax; // Max number of instruments == Highest possible instrument index MixLevels defaultMixLevels; // Default mix levels that are used when creating a new file in this format FlagSet::store_type songFlags; // Supported song flags NOTE: Do not use the overloaded operator | to set these flags because this results in dynamic initialization uint8 MIDIMappingDirectivesMax; // Number of MIDI Mapping directives that the format can store (0 = none) uint8 envelopePointsMax; // Maximum number of points of each envelope // Work around a possible code generation bug in MSVC10 with boolean bitfields by using uint8 bool hasNoteCut; // True if format has note cut (^^). bool hasNoteOff; // True if format has note off (==). bool hasNoteFade; // True if format has note fade (~~). bool hasReleaseNode; // Envelope release node bool hasComments; // True if format has a comments field bool hasIgnoreIndex; // Does "+++" pattern exist? bool hasStopIndex; // Does "---" pattern exist? bool hasRestartPos; // Format has an automatic restart order position bool supportsPlugins; // Format can store plugins bool hasPatternSignatures; // Can patterns have a custom time signature? bool hasPatternNames; // Can patterns have a name? bool hasArtistName; // Can artist name be stored in file? bool hasDefaultResampling; // Can default resampling be saved? (if not, it can still be modified in the GUI but won't set the module as modified) bool hasFractionalTempo; // Are fractional tempos allowed? const char *commands; // An array holding all commands this format supports; commands that are not supported are marked with "?" const char *volcommands; // Ditto, but for volume column MPT_CONSTEXPR11_FUN TEMPO GetTempoMin() const { return TEMPO(tempoMinInt, 0); } MPT_CONSTEXPR11_FUN TEMPO GetTempoMax() const { return TEMPO(tempoMaxInt, 0); } MPT_CONSTEXPR11_FUN FlagSet GetSongFlags() const { return FlagSet(songFlags); } }; namespace ModSpecs { extern const CModSpecifications & mptm; extern const CModSpecifications & mod; extern const CModSpecifications & s3m; extern const CModSpecifications & s3mEx; extern const CModSpecifications & xm; extern const CModSpecifications & xmEx; extern const CModSpecifications & it; extern const CModSpecifications & itEx; extern const CModSpecifications *Collection[8]; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Load_imf.cpp0000644000372100037210000004102313161656666020333 00000000000000/* * Load_imf.cpp * ------------ * Purpose: IMF (Imago Orpheus) module loader * Notes : Reverb and Chorus are not supported. * Authors: Storlek (Original author - http://schismtracker.org/ - code ported with permission) * Johannes Schultz (OpenMPT Port, tweaks) * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" OPENMPT_NAMESPACE_BEGIN struct IMFChannel { char name[12]; // Channel name (ASCIIZ-String, max 11 chars) uint8 chorus; // Default chorus uint8 reverb; // Default reverb uint8 panning; // Pan positions 00-FF uint8 status; // Channel status: 0 = enabled, 1 = mute, 2 = disabled (ignore effects!) }; MPT_BINARY_STRUCT(IMFChannel, 16) struct IMFFileHeader { enum SongFlags { linearSlides = 0x01, }; char title[32]; // Songname (ASCIIZ-String, max. 31 chars) uint16le ordNum; // Number of orders saved uint16le patNum; // Number of patterns saved uint16le insNum; // Number of instruments saved uint16le flags; // See SongFlags uint8le unused1[8]; uint8le tempo; // Default tempo (Axx, 1...255) uint8le bpm; // Default beats per minute (BPM) (Txx, 32...255) uint8le master; // Default master volume (Vxx, 0...64) uint8le amp; // Amplification factor (mixing volume, 4...127) uint8le unused2[8]; char im10[4]; // 'IM10' IMFChannel channels[32]; // Channel settings }; MPT_BINARY_STRUCT(IMFFileHeader, 576) struct IMFEnvelope { enum EnvFlags { envEnabled = 0x01, envSustain = 0x02, envLoop = 0x04, }; uint8 points; // Number of envelope points uint8 sustain; // Envelope sustain point uint8 loopStart; // Envelope loop start point uint8 loopEnd; // Envelope loop end point uint8 flags; // See EnvFlags uint8 unused[3]; }; MPT_BINARY_STRUCT(IMFEnvelope, 8) struct IMFEnvNode { uint16le tick; uint16le value; }; MPT_BINARY_STRUCT(IMFEnvNode, 4) struct IMFInstrument { enum EnvTypes { volEnv = 0, panEnv = 1, filterEnv = 2, }; char name[32]; // Inst. name (ASCIIZ-String, max. 31 chars) uint8le map[120]; // Multisample settings uint8le unused[8]; IMFEnvNode nodes[3][16]; IMFEnvelope env[3]; uint16le fadeout; // Fadeout rate (0...0FFFH) uint16le smpNum; // Number of samples in instrument char ii10[4]; // 'II10' void ConvertEnvelope(InstrumentEnvelope &mptEnv, EnvTypes e) const { const int shift = (e == volEnv) ? 0 : 2; mptEnv.dwFlags.set(ENV_ENABLED, (env[e].flags & 1) != 0); mptEnv.dwFlags.set(ENV_SUSTAIN, (env[e].flags & 2) != 0); mptEnv.dwFlags.set(ENV_LOOP, (env[e].flags & 4) != 0); mptEnv.resize(Clamp(env[e].points, uint8(2), uint8(16))); mptEnv.nLoopStart = env[e].loopStart; mptEnv.nLoopEnd = env[e].loopEnd; mptEnv.nSustainStart = mptEnv.nSustainEnd = env[e].sustain; uint16 minTick = 0; // minimum tick value for next node for(uint32 n = 0; n < mptEnv.size(); n++) { minTick = mptEnv[n].tick = std::max(minTick, nodes[e][n].tick); minTick++; mptEnv[n].value = static_cast(std::min(nodes[e][n].value >> shift, ENVELOPE_MAX)); } } // Convert an IMFInstrument to OpenMPT's internal instrument representation. void ConvertToMPT(ModInstrument &mptIns, SAMPLEINDEX firstSample) const { mpt::String::Read(mptIns.name, name); if(smpNum) { STATIC_ASSERT(CountOf(mptIns.Keyboard) >= CountOf(map)); for(size_t note = 0; note < CountOf(map); note++) { mptIns.Keyboard[note] = firstSample + map[note]; } } mptIns.nFadeOut = fadeout; ConvertEnvelope(mptIns.VolEnv, volEnv); ConvertEnvelope(mptIns.PanEnv, panEnv); ConvertEnvelope(mptIns.PitchEnv, filterEnv); if(mptIns.PitchEnv.dwFlags[ENV_ENABLED]) mptIns.PitchEnv.dwFlags.set(ENV_FILTER); // hack to get === to stop notes (from modplug's xm loader) if(!mptIns.VolEnv.dwFlags[ENV_ENABLED] && !mptIns.nFadeOut) mptIns.nFadeOut = 8192; } }; MPT_BINARY_STRUCT(IMFInstrument, 384) struct IMFSample { enum SampleFlags { smpLoop = 0x01, smpPingPongLoop = 0x02, smp16Bit = 0x04, smpPanning = 0x08, }; char filename[13]; // Sample filename (12345678.ABC) */ uint8le unused1[3]; uint32le length; // Length (in bytes) uint32le loopStart; // Loop start (in bytes) uint32le loopEnd; // Loop end (in bytes) uint32le c5Speed; // Samplerate uint8le volume; // Default volume (0...64) uint8le panning; // Default pan (0...255) uint8le unused2[14]; uint8le flags; // Sample flags uint8le unused3[5]; uint16le ems; // Reserved for internal usage uint32le dram; // Reserved for internal usage char is10[4]; // 'IS10' // Convert an IMFSample to OpenMPT's internal sample representation. void ConvertToMPT(ModSample &mptSmp) const { mptSmp.Initialize(); mpt::String::Read(mptSmp.filename, filename); mptSmp.nLength = length; mptSmp.nLoopStart = loopStart; mptSmp.nLoopEnd = loopEnd; mptSmp.nC5Speed = c5Speed; mptSmp.nVolume = volume * 4; mptSmp.nPan = panning; if(flags & smpLoop) mptSmp.uFlags.set(CHN_LOOP); if(flags & smpPingPongLoop) mptSmp.uFlags.set(CHN_PINGPONGLOOP); if(flags & smp16Bit) { mptSmp.uFlags.set(CHN_16BIT); mptSmp.nLength /= 2; mptSmp.nLoopStart /= 2; mptSmp.nLoopEnd /= 2; } if(flags & smpPanning) mptSmp.uFlags.set(CHN_PANNING); } }; MPT_BINARY_STRUCT(IMFSample, 64) static const EffectCommand imfEffects[] = { CMD_NONE, CMD_SPEED, // 0x01 1xx Set Tempo CMD_TEMPO, // 0x02 2xx Set BPM CMD_TONEPORTAMENTO, // 0x03 3xx Tone Portamento CMD_TONEPORTAVOL, // 0x04 4xy Tone Portamento + Volume Slide CMD_VIBRATO, // 0x05 5xy Vibrato CMD_VIBRATOVOL, // 0x06 6xy Vibrato + Volume Slide CMD_FINEVIBRATO, // 0x07 7xy Fine Vibrato CMD_TREMOLO, // 0x08 8xy Tremolo CMD_ARPEGGIO, // 0x09 9xy Arpeggio CMD_PANNING8, // 0x0A Axx Set Pan Position CMD_PANNINGSLIDE, // 0x0B Bxy Pan Slide CMD_VOLUME, // 0x0C Cxx Set Volume CMD_VOLUMESLIDE, // 0x0D Dxy Volume Slide CMD_VOLUMESLIDE, // 0x0E Exy Fine Volume Slide CMD_S3MCMDEX, // 0x0F Fxx Set Finetune CMD_NOTESLIDEUP, // 0x10 Gxy Note Slide Up CMD_NOTESLIDEDOWN, // 0x11 Hxy Note Slide Down CMD_PORTAMENTOUP, // 0x12 Ixx Slide Up CMD_PORTAMENTODOWN, // 0x13 Jxx Slide Down CMD_PORTAMENTOUP, // 0x14 Kxx Fine Slide Up CMD_PORTAMENTODOWN, // 0x15 Lxx Fine Slide Down CMD_MIDI, // 0x16 Mxx Set Filter Cutoff - XXX CMD_NONE, // 0x17 Nxy Filter Slide + Resonance - XXX CMD_OFFSET, // 0x18 Oxx Set Sample Offset CMD_NONE, // 0x19 Pxx Set Fine Sample Offset - XXX CMD_KEYOFF, // 0x1A Qxx Key Off CMD_RETRIG, // 0x1B Rxy Retrig CMD_TREMOR, // 0x1C Sxy Tremor CMD_POSITIONJUMP, // 0x1D Txx Position Jump CMD_PATTERNBREAK, // 0x1E Uxx Pattern Break CMD_GLOBALVOLUME, // 0x1F Vxx Set Mastervolume CMD_GLOBALVOLSLIDE, // 0x20 Wxy Mastervolume Slide CMD_S3MCMDEX, // 0x21 Xxx Extended Effect // X1x Set Filter // X3x Glissando // X5x Vibrato Waveform // X8x Tremolo Waveform // XAx Pattern Loop // XBx Pattern Delay // XCx Note Cut // XDx Note Delay // XEx Ignore Envelope // XFx Invert Loop CMD_NONE, // 0x22 Yxx Chorus - XXX CMD_NONE, // 0x23 Zxx Reverb - XXX }; static void ImportIMFEffect(ModCommand &m) { uint8 n; // fix some of them switch (m.command) { case 0xE: // fine volslide // hackaround to get almost-right behavior for fine slides (i think!) if(m.param == 0) /* nothing */; else if(m.param == 0xF0) m.param = 0xEF; else if(m.param == 0x0F) m.param = 0xFE; else if(m.param & 0xF0) m.param |= 0x0F; else m.param |= 0xF0; break; case 0xF: // set finetune // we don't implement this, but let's at least import the value m.param = 0x20 | MIN(m.param >> 4, 0x0F); break; case 0x14: // fine slide up case 0x15: // fine slide down // this is about as close as we can do... if(m.param >> 4) m.param = 0xF0 | MIN(m.param >> 4, 0x0F); else m.param |= 0xE0; break; case 0x16: // cutoff m.param >>= 1; break; case 0x1F: // set global volume m.param = MIN(m.param << 1, 0xFF); break; case 0x21: n = 0; switch (m.param >> 4) { case 0: /* undefined, but since S0x does nothing in IT anyway, we won't care. this is here to allow S00 to pick up the previous value (assuming IMF even does that -- I haven't actually tried it) */ break; default: // undefined case 0x1: // set filter case 0xF: // invert loop m.command = CMD_NONE; break; case 0x3: // glissando n = 0x20; break; case 0x5: // vibrato waveform n = 0x30; break; case 0x8: // tremolo waveform n = 0x40; break; case 0xA: // pattern loop n = 0xB0; break; case 0xB: // pattern delay n = 0xE0; break; case 0xC: // note cut case 0xD: // note delay // Apparently, Imago Orpheus doesn't cut samples on tick 0. if(!m.param) m.command = CMD_NONE; break; case 0xE: // ignore envelope /* predicament: we can only disable one envelope at a time. volume is probably most noticeable, so let's go with that. (... actually, orpheus doesn't even seem to implement this at all) */ m.param = 0x77; break; case 0x18: // sample offset // O00 doesn't pick up the previous value if(!m.param) m.command = CMD_NONE; break; } if(n) m.param = n | (m.param & 0x0F); break; } m.command = (m.command < CountOf(imfEffects)) ? imfEffects[m.command] : CMD_NONE; if(m.command == CMD_VOLUME && m.volcmd == VOLCMD_NONE) { m.volcmd = VOLCMD_VOLUME; m.vol = m.param; m.command = CMD_NONE; m.param = 0; } } static bool ValidateHeader(const IMFFileHeader &fileHeader) { if(std::memcmp(fileHeader.im10, "IM10", 4) || fileHeader.ordNum > 256 || fileHeader.insNum >= MAX_INSTRUMENTS ) { return false; } bool channelFound = false; for(uint8 chn = 0; chn < 32; chn++) { switch(fileHeader.channels[chn].status) { case 0: // enabled; don't worry about it channelFound = true; break; case 1: // mute channelFound = true; break; case 2: // disabled // nothing break; default: // uhhhh.... freak out return false; } } if(!channelFound) { return false; } return true; } static uint64 GetHeaderMinimumAdditionalSize(const IMFFileHeader &fileHeader) { MPT_UNREFERENCED_PARAMETER(fileHeader); return 256; } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderIMF(MemoryFileReader file, const uint64 *pfilesize) { IMFFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return ProbeWantMoreData; } if(!ValidateHeader(fileHeader)) { return ProbeFailure; } return ProbeAdditionalSize(file, pfilesize, GetHeaderMinimumAdditionalSize(fileHeader)); } bool CSoundFile::ReadIMF(FileReader &file, ModLoadingFlags loadFlags) { IMFFileHeader fileHeader; file.Rewind(); if(!file.ReadStruct(fileHeader)) { return false; } if(!ValidateHeader(fileHeader)) { return false; } if(!file.CanRead(mpt::saturate_cast(GetHeaderMinimumAdditionalSize(fileHeader)))) { return false; } // Read channel configuration std::bitset<32> ignoreChannels; // bit set for each channel that's completely disabled uint8 detectedChannels = 0; for(uint8 chn = 0; chn < 32; chn++) { ChnSettings[chn].Reset(); ChnSettings[chn].nPan = fileHeader.channels[chn].panning * 256 / 255; mpt::String::Read(ChnSettings[chn].szName, fileHeader.channels[chn].name); // TODO: reverb/chorus? switch(fileHeader.channels[chn].status) { case 0: // enabled; don't worry about it detectedChannels = chn + 1; break; case 1: // mute ChnSettings[chn].dwFlags = CHN_MUTE; detectedChannels = chn + 1; break; case 2: // disabled ChnSettings[chn].dwFlags = CHN_MUTE; ignoreChannels[chn] = true; break; default: // uhhhh.... freak out //fprintf(stderr, "imf: channel %d has unknown status %d\n", n, hdr.channels[n].status); return false; } } if(!detectedChannels) { return false; } if(loadFlags == onlyVerifyHeader) { return true; } InitializeGlobals(MOD_TYPE_IMF); m_nChannels = detectedChannels; //From mikmod: work around an Orpheus bug if(fileHeader.channels[0].status == 0) { CHANNELINDEX chn; for(chn = 1; chn < 16; chn++) if(fileHeader.channels[chn].status != 1) break; if(chn == 16) for(chn = 1; chn < 16; chn++) ChnSettings[chn].dwFlags.reset(CHN_MUTE); } // Song Name mpt::String::Read(m_songName, fileHeader.title); m_SongFlags = (fileHeader.flags & IMFFileHeader::linearSlides) ? SONG_LINEARSLIDES : SongFlags(0); m_nDefaultSpeed = fileHeader.tempo; m_nDefaultTempo.Set(fileHeader.bpm); m_nDefaultGlobalVolume = Clamp(fileHeader.master, 0, 64) * 4; m_nSamplePreAmp = Clamp(fileHeader.amp, 4, 127); m_nInstruments = fileHeader.insNum; m_nSamples = 0; // Will be incremented later uint8 orders[256]; file.ReadArray(orders); ReadOrderFromArray(Order(), orders, fileHeader.ordNum, uint16_max, 0xFF); // Read patterns if(loadFlags & loadPatternData) Patterns.ResizeArray(fileHeader.patNum); for(PATTERNINDEX pat = 0; pat < fileHeader.patNum; pat++) { const uint16 length = file.ReadUint16LE(), numRows = file.ReadUint16LE(); FileReader patternChunk = file.ReadChunk(length - 4); if(!(loadFlags & loadPatternData) || !Patterns.Insert(pat, numRows)) { continue; } ModCommand junkNote; ROWINDEX row = 0; while(row < numRows) { uint8 mask = patternChunk.ReadUint8(); if(mask == 0) { row++; continue; } uint8 channel = mask & 0x1F; ModCommand &m = ignoreChannels[channel] ? junkNote : *Patterns[pat].GetpModCommand(row, channel); if(mask & 0x20) { // Read note/instrument m.note = patternChunk.ReadUint8(); m.instr = patternChunk.ReadUint8(); if(m.note == 160) { m.note = NOTE_KEYOFF; } else if(m.note == 255) { m.note = NOTE_NONE; } else { m.note = (m.note >> 4) * 12 + (m.note & 0x0F) + 12 + 1; if(!m.IsNoteOrEmpty()) { m.note = NOTE_NONE; } } } if((mask & 0xC0) == 0xC0) { // Read both effects and figure out what to do with them uint8 e1c = patternChunk.ReadUint8(); // Command 1 uint8 e1d = patternChunk.ReadUint8(); // Data 1 uint8 e2c = patternChunk.ReadUint8(); // Command 2 uint8 e2d = patternChunk.ReadUint8(); // Data 2 if(e1c == 0x0C) { m.vol = MIN(e1d, 0x40); m.volcmd = VOLCMD_VOLUME; m.command = e2c; m.param = e2d; } else if(e2c == 0x0C) { m.vol = MIN(e2d, 0x40); m.volcmd = VOLCMD_VOLUME; m.command = e1c; m.param = e1d; } else if(e1c == 0x0A) { m.vol = e1d * 64 / 255; m.volcmd = VOLCMD_PANNING; m.command = e2c; m.param = e2d; } else if(e2c == 0x0A) { m.vol = e2d * 64 / 255; m.volcmd = VOLCMD_PANNING; m.command = e1c; m.param = e1d; } else { /* check if one of the effects is a 'global' effect -- if so, put it in some unused channel instead. otherwise pick the most important effect. */ m.command = e2c; m.param = e2d; } } else if(mask & 0xC0) { // There's one effect, just stick it in the effect column m.command = patternChunk.ReadUint8(); m.param = patternChunk.ReadUint8(); } if(m.command) ImportIMFEffect(m); } } SAMPLEINDEX firstSample = 1; // first sample index of the current instrument // read instruments for(INSTRUMENTINDEX ins = 0; ins < GetNumInstruments(); ins++) { ModInstrument *instr = AllocateInstrument(ins + 1); IMFInstrument instrumentHeader; if(!file.ReadStruct(instrumentHeader) || instr == nullptr) { continue; } // Orpheus does not check this! //if(memcmp(instrumentHeader.ii10, "II10", 4) != 0) // return false; instrumentHeader.ConvertToMPT(*instr, firstSample); // Read this instrument's samples for(SAMPLEINDEX smp = 0; smp < instrumentHeader.smpNum; smp++) { IMFSample sampleHeader; file.ReadStruct(sampleHeader); const SAMPLEINDEX smpID = firstSample + smp; if(memcmp(sampleHeader.is10, "IS10", 4) || smpID >= MAX_SAMPLES) { continue; } m_nSamples = smpID; ModSample &sample = Samples[smpID]; sampleHeader.ConvertToMPT(sample); mpt::String::Copy(m_szNames[smpID], sample.filename); if(sampleHeader.length) { FileReader sampleChunk = file.ReadChunk(sampleHeader.length); if(loadFlags & loadSampleData) { SampleIO( sample.uFlags[CHN_16BIT] ? SampleIO::_16bit : SampleIO::_8bit, SampleIO::mono, SampleIO::littleEndian, SampleIO::signedPCM) .ReadSample(sample, sampleChunk); } } } firstSample += instrumentHeader.smpNum; } return true; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/tuning.cpp0000644000372100037210000005637713224426375020137 00000000000000/* * tuning.cpp * ---------- * Purpose: Alternative sample tuning. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "tuning.h" #include "../common/mptIO.h" #include "../common/serialization_utils.h" #include "../common/misc_util.h" #include #include OPENMPT_NAMESPACE_BEGIN namespace Tuning { namespace CTuningS11n { void ReadStr(std::istream& iStrm, std::string& str, const size_t); void ReadNoteMap(std::istream& iStrm, std::map& m, const size_t); void ReadRatioTable(std::istream& iStrm, std::vector& v, const size_t); void WriteNoteMap(std::ostream& oStrm, const std::map& m); void WriteStr(std::ostream& oStrm, const std::string& str); struct RatioWriter { RatioWriter(uint16 nWriteCount = s_nDefaultWriteCount) : m_nWriteCount(nWriteCount) {} void operator()(std::ostream& oStrm, const std::vector& v); uint16 m_nWriteCount; static const uint16 s_nDefaultWriteCount = (uint16_max >> 2); }; } using namespace CTuningS11n; /* Version changes: 3->4: Finetune related internal structure and serialization revamp. 2->3: The type for the size_type in the serialisation changed from default(size_t, uint32) to unsigned STEPTYPE. (March 2007) */ CTuningRTI::CTuningRTI() : m_TuningType(TT_GENERAL) , m_FineStepCount(0) { { m_RatioTable.clear(); m_StepMin = s_StepMinDefault; m_RatioTable.resize(s_RatioTableSizeDefault, 1); m_GroupSize = 0; m_GroupRatio = 0; m_RatioTableFine.clear(); } } bool CTuningRTI::ProCreateGroupGeometric(const std::vector& v, const RATIOTYPE& r, const VRPAIR& vr, const NOTEINDEXTYPE& ratiostartpos) { if(v.size() == 0 || r <= 0 || vr.second < vr.first || ratiostartpos < vr.first) { return true; } m_StepMin = vr.first; m_GroupSize = mpt::saturate_cast(v.size()); m_GroupRatio = std::fabs(r); m_RatioTable.resize(vr.second-vr.first+1); std::copy(v.begin(), v.end(), m_RatioTable.begin() + (ratiostartpos - vr.first)); for(int32 i = ratiostartpos-1; i>=m_StepMin && ratiostartpos > NOTEINDEXTYPE_MIN; i--) { m_RatioTable[i-m_StepMin] = m_RatioTable[i - m_StepMin + m_GroupSize] / m_GroupRatio; } for(int32 i = ratiostartpos+m_GroupSize; i<=vr.second && ratiostartpos <= (NOTEINDEXTYPE_MAX - m_GroupSize); i++) { m_RatioTable[i-m_StepMin] = m_GroupRatio * m_RatioTable[i - m_StepMin - m_GroupSize]; } return false; } bool CTuningRTI::ProCreateGeometric(const UNOTEINDEXTYPE& s, const RATIOTYPE& r, const VRPAIR& vr) { if(vr.second - vr.first + 1 > NOTEINDEXTYPE_MAX) return true; //Note: Setting finestep is handled by base class when CreateGeometric is called. { m_RatioTable.clear(); m_StepMin = s_StepMinDefault; m_RatioTable.resize(s_RatioTableSizeDefault, static_cast(1.0)); m_GroupSize = 0; m_GroupRatio = 0; m_RatioTableFine.clear(); } m_StepMin = vr.first; m_GroupSize = mpt::saturate_cast(s); m_GroupRatio = std::fabs(r); const RATIOTYPE stepRatio = std::pow(m_GroupRatio, static_cast(1.0)/ static_cast(m_GroupSize)); m_RatioTable.resize(vr.second - vr.first + 1); for(int32 i = vr.first; i<=vr.second; i++) { m_RatioTable[i-m_StepMin] = std::pow(stepRatio, static_cast(i)); } return false; } std::string CTuningRTI::GetNoteName(const NOTEINDEXTYPE& x, bool addOctave) const { if(!IsValidNote(x)) { return std::string(); } if(GetGroupSize() < 1) { const auto i = m_NoteNameMap.find(x); if(i != m_NoteNameMap.end()) return i->second; else return mpt::fmt::val(x); } else { const NOTEINDEXTYPE pos = static_cast(mpt::wrapping_modulo(x, m_GroupSize)); const NOTEINDEXTYPE middlePeriodNumber = 5; std::string rValue; const auto nmi = m_NoteNameMap.find(pos); if(nmi != m_NoteNameMap.end()) { rValue = nmi->second; if(addOctave) { rValue += mpt::fmt::val(middlePeriodNumber + mpt::wrapping_divide(x, m_GroupSize)); } } else { //By default, using notation nnP for notes; nn <-> note character starting //from 'A' with char ':' as fill char, and P is period integer. For example: //C:5, D:3, R:7 if(m_GroupSize <= 26) { rValue = std::string(1, static_cast(pos + 'A')); rValue += ":"; } else { rValue = mpt::fmt::HEX0<1>(pos % 16) + mpt::fmt::HEX0<1>((pos / 16) % 16); if(pos > 0xff) { rValue = mpt::ToLowerCaseAscii(rValue); } } if(addOctave) { rValue += mpt::fmt::val(middlePeriodNumber + mpt::wrapping_divide(x, m_GroupSize)); } } return rValue; } } const RATIOTYPE CTuningRTI::s_DefaultFallbackRatio = 1.0f; //Without finetune RATIOTYPE CTuningRTI::GetRatio(const NOTEINDEXTYPE& stepsFromCentre) const { if(stepsFromCentre < m_StepMin) return s_DefaultFallbackRatio; if(stepsFromCentre >= m_StepMin + static_cast(m_RatioTable.size())) return s_DefaultFallbackRatio; return m_RatioTable[stepsFromCentre - m_StepMin]; } //With finetune RATIOTYPE CTuningRTI::GetRatio(const NOTEINDEXTYPE& baseNote, const STEPINDEXTYPE& baseStepDiff) const { const STEPINDEXTYPE fsCount = static_cast(GetFineStepCount()); if(fsCount == 0 || baseStepDiff == 0) { return GetRatio(static_cast(baseNote + baseStepDiff)); } //If baseStepDiff is more than the number of finesteps between notes, //note is increased. So first figuring out what step and fineStep values to //actually use. Interpreting finestep -1 on note x so that it is the same as //finestep GetFineStepCount() on note x-1. //Note: If finestepcount is n, n+1 steps are needed to get to //next note. NOTEINDEXTYPE note; STEPINDEXTYPE fineStep; note = static_cast(baseNote + mpt::wrapping_divide(baseStepDiff, (fsCount+1))); fineStep = mpt::wrapping_modulo(baseStepDiff, (fsCount+1)); if(note < m_StepMin) return s_DefaultFallbackRatio; if(note >= m_StepMin + static_cast(m_RatioTable.size())) return s_DefaultFallbackRatio; if(fineStep) return m_RatioTable[note - m_StepMin] * GetRatioFine(note, fineStep); else return m_RatioTable[note - m_StepMin]; } RATIOTYPE CTuningRTI::GetRatioFine(const NOTEINDEXTYPE& note, USTEPINDEXTYPE sd) const { if(GetFineStepCount() <= 0) return 1; //Neither of these should happen. if(sd <= 0) sd = 1; if(sd > GetFineStepCount()) sd = GetFineStepCount(); if(GetType() != TT_GENERAL && m_RatioTableFine.size() > 0) //Taking fineratio from table { if(GetType() == TT_GEOMETRIC) { return m_RatioTableFine[sd-1]; } if(GetType() == TT_GROUPGEOMETRIC) return m_RatioTableFine[GetRefNote(note) * GetFineStepCount() + sd - 1]; MPT_ASSERT_NOTREACHED(); return m_RatioTableFine[0]; //Shouldn't happen. } else //Calculating ratio 'on the fly'. { //'Geometric finestepping'. return pow(GetRatio(note+1) / GetRatio(note), static_cast(sd)/(GetFineStepCount()+1)); } } bool CTuningRTI::SetRatio(const NOTEINDEXTYPE& s, const RATIOTYPE& r) { if(GetType() != TT_GROUPGEOMETRIC && GetType() != TT_GENERAL) { return false; } //Creating ratio table if doesn't exist. if(m_RatioTable.empty()) { m_RatioTable.assign(s_RatioTableSizeDefault, 1); m_StepMin = s_StepMinDefault; } if(!IsNoteInTable(s)) { return false; } m_RatioTable[s - m_StepMin] = std::fabs(r); if(GetType() == TT_GROUPGEOMETRIC) { // update other groups for(NOTEINDEXTYPE n = m_StepMin; n < m_StepMin + static_cast(m_RatioTable.size()); ++n) { if(n == s) { // nothing } else if(mpt::abs(n - s) % m_GroupSize == 0) { m_RatioTable[n - m_StepMin] = std::pow(m_GroupRatio, static_cast(n - s) / static_cast(m_GroupSize)) * m_RatioTable[s - m_StepMin]; } } UpdateFineStepTable(); } return true; } void CTuningRTI::SetFineStepCount(const USTEPINDEXTYPE& fs) { m_FineStepCount = mpt::clamp(mpt::saturate_cast(fs), 0, FINESTEPCOUNT_MAX); UpdateFineStepTable(); } void CTuningRTI::UpdateFineStepTable() { if(m_FineStepCount <= 0) { m_RatioTableFine.clear(); return; } if(GetType() == TT_GEOMETRIC) { if(m_FineStepCount > s_RatioTableFineSizeMaxDefault) { m_RatioTableFine.clear(); return; } m_RatioTableFine.resize(m_FineStepCount); const RATIOTYPE q = GetRatio(GetValidityRange().first + 1) / GetRatio(GetValidityRange().first); const RATIOTYPE rFineStep = pow(q, static_cast(1)/(m_FineStepCount+1)); for(USTEPINDEXTYPE i = 1; i<=m_FineStepCount; i++) m_RatioTableFine[i-1] = std::pow(rFineStep, static_cast(i)); return; } if(GetType() == TT_GROUPGEOMETRIC) { const UNOTEINDEXTYPE p = GetGroupSize(); if(p > s_RatioTableFineSizeMaxDefault / m_FineStepCount) { //In case fineratiotable would become too large, not using //table for it. m_RatioTableFine.clear(); return; } else { //Creating 'geometric' finestepping between notes. m_RatioTableFine.resize(p * m_FineStepCount); const NOTEINDEXTYPE startnote = GetRefNote(GetValidityRange().first); for(UNOTEINDEXTYPE i = 0; i(1)/(m_FineStepCount+1)); for(UNOTEINDEXTYPE j = 1; j<=m_FineStepCount; j++) { m_RatioTableFine[m_FineStepCount * refnote + (j-1)] = pow(rFineStep, static_cast(j)); } } return; } } if(GetType() == TT_GENERAL) { //Not using table with tuning of type general. m_RatioTableFine.clear(); return; } //Should not reach here. m_RatioTableFine.clear(); m_FineStepCount = 0; } NOTEINDEXTYPE CTuningRTI::GetRefNote(const NOTEINDEXTYPE note) const { if((GetType() != TT_GROUPGEOMETRIC) && (GetType() != TT_GEOMETRIC)) return 0; return static_cast(mpt::wrapping_modulo(note, GetGroupSize())); } SerializationResult CTuningRTI::InitDeserialize(std::istream& iStrm) { // Note: OpenMPT since at least r323 writes version number (4<<24)+4 while it // reads version number (5<<24)+4 or earlier. // We keep this behaviour. if(iStrm.fail()) return SerializationResult::Failure; srlztn::SsbRead ssb(iStrm); ssb.BeginRead("CTB244RTI", (5 << 24) + 4); // version ssb.ReadItem(m_TuningName, "0", ReadStr); uint16 dummyEditMask = 0xffff; ssb.ReadItem(dummyEditMask, "1"); ssb.ReadItem(m_TuningType, "2"); ssb.ReadItem(m_NoteNameMap, "3", ReadNoteMap); ssb.ReadItem(m_FineStepCount, "4"); // RTI entries. ssb.ReadItem(m_RatioTable, "RTI0", ReadRatioTable); ssb.ReadItem(m_StepMin, "RTI1"); ssb.ReadItem(m_GroupSize, "RTI2"); ssb.ReadItem(m_GroupRatio, "RTI3"); UNOTEINDEXTYPE ratiotableSize = 0; ssb.ReadItem(ratiotableSize, "RTI4"); // If reader status is ok and m_StepMin is somewhat reasonable, process data. if(!((ssb.GetStatus() & srlztn::SNT_FAILURE) == 0 && m_StepMin >= -300 && m_StepMin <= 300)) { return SerializationResult::Failure; } // reject unknown types if(m_TuningType != TT_GENERAL && m_TuningType != TT_GROUPGEOMETRIC && m_TuningType != TT_GEOMETRIC) { return SerializationResult::Failure; } if(m_GroupSize < 0) { return SerializationResult::Failure; } if(m_RatioTable.size() > static_cast(NOTEINDEXTYPE_MAX)) { return SerializationResult::Failure; } if((GetType() == TT_GROUPGEOMETRIC) || (GetType() == TT_GEOMETRIC)) { if(ratiotableSize < 1 || ratiotableSize > NOTEINDEXTYPE_MAX) { return SerializationResult::Failure; } if(GetType() == TT_GEOMETRIC) { if(CreateGeometric(GetGroupSize(), GetGroupRatio(), VRPAIR(m_StepMin, static_cast(m_StepMin + ratiotableSize - 1))) != false) { return SerializationResult::Failure; } } else { if(CreateGroupGeometric(m_RatioTable, GetGroupRatio(), VRPAIR(m_StepMin, static_cast(m_StepMin+ratiotableSize-1)), m_StepMin) != false) { return SerializationResult::Failure; } } } else { UpdateFineStepTable(); } return SerializationResult::Success; } template static bool VectorFromBinaryStream(std::istream& inStrm, std::vector& v, const SIZETYPE maxSize = (std::numeric_limits::max)()) { if(!inStrm.good()) return true; SIZETYPE size = 0; mpt::IO::ReadIntLE(inStrm, size); if(size > maxSize) return true; v.resize(size); for(std::size_t i = 0; i(inStrm, version); if(version != 2 && version != 3) return SerializationResult::Failure; char begin2[8]; MemsetZero(begin2); inStrm.read(begin2, sizeof(begin2)); if(std::memcmp(begin2, "CTB", 8)) { return SerializationResult::Failure; } int16 version2 = 0; mpt::IO::ReadIntLE(inStrm, version2); if(version2 != 3 && version2 != 4) { return SerializationResult::Failure; } //Tuning name if(version2 <= 3) { if(!mpt::IO::ReadSizedStringLE(inStrm, m_TuningName, 0xffff)) { return SerializationResult::Failure; } } else { if(!mpt::IO::ReadSizedStringLE(inStrm, m_TuningName)) { return SerializationResult::Failure; } } //Const mask int16 em = 0; mpt::IO::ReadIntLE(inStrm, em); //Tuning type int16 tt = 0; mpt::IO::ReadIntLE(inStrm, tt); m_TuningType = tt; //Notemap uint16 size = 0; if(version2 <= 3) { uint32 tempsize = 0; mpt::IO::ReadIntLE(inStrm, tempsize); if(tempsize > 0xffff) { return SerializationResult::Failure; } size = mpt::saturate_cast(tempsize); } else { mpt::IO::ReadIntLE(inStrm, size); } for(UNOTEINDEXTYPE i = 0; i(inStrm, n); if(version2 <= 3) { if(!mpt::IO::ReadSizedStringLE(inStrm, str, 0xffff)) { return SerializationResult::Failure; } } else { if(!mpt::IO::ReadSizedStringLE(inStrm, str)) { return SerializationResult::Failure; } } m_NoteNameMap[n] = str; } //End marker char end2[8]; MemsetZero(end2); inStrm.read(end2, sizeof(end2)); if(std::memcmp(end2, "CTE", 8)) { return SerializationResult::Failure; } // reject unknown types if(m_TuningType != TT_GENERAL && m_TuningType != TT_GROUPGEOMETRIC && m_TuningType != TT_GEOMETRIC) { return SerializationResult::Failure; } //Ratiotable if(version <= 2) { if(VectorFromBinaryStream(inStrm, m_RatioTable, 0xffff)) { return SerializationResult::Failure; } } else { if(VectorFromBinaryStream(inStrm, m_RatioTable)) { return SerializationResult::Failure; } } //Fineratios if(version <= 2) { if(VectorFromBinaryStream(inStrm, m_RatioTableFine, 0xffff)) { return SerializationResult::Failure; } } else { if(VectorFromBinaryStream(inStrm, m_RatioTableFine)) { return SerializationResult::Failure; } } m_FineStepCount = mpt::saturate_cast(m_RatioTableFine.size()); //m_StepMin int16 stepmin = 0; mpt::IO::ReadIntLE(inStrm, stepmin); m_StepMin = stepmin; if(m_StepMin < -200 || m_StepMin > 200) { return SerializationResult::Failure; } //m_GroupSize int16 groupsize = 0; mpt::IO::ReadIntLE(inStrm, groupsize); m_GroupSize = groupsize; if(m_GroupSize < 0) { return SerializationResult::Failure; } //m_GroupRatio IEEE754binary32LE groupratio = IEEE754binary32LE(0.0f); mpt::IO::Read(inStrm, groupratio); m_GroupRatio = groupratio; if(m_GroupRatio < 0) { return SerializationResult::Failure; } char end[8]; MemsetZero(end); inStrm.read(reinterpret_cast(&end), sizeof(end)); if(std::memcmp(end, "CTRTI_E.", 8)) { return SerializationResult::Failure; } // reject corrupt tunings if(m_RatioTable.size() > static_cast(NOTEINDEXTYPE_MAX)) { return SerializationResult::Failure; } if((m_GroupSize <= 0 || m_GroupRatio <= 0) && m_TuningType != TT_GENERAL) { return SerializationResult::Failure; } if(m_TuningType == TT_GROUPGEOMETRIC || m_TuningType == TT_GEOMETRIC) { if(m_RatioTable.size() < static_cast(m_GroupSize)) { return SerializationResult::Failure; } } // convert old finestepcount if(m_FineStepCount > 0) { m_FineStepCount -= 1; } UpdateFineStepTable(); if(m_TuningType == TT_GEOMETRIC) { // Convert old geometric to new groupgeometric because old geometric tunings // can have ratio(0) != 1.0, which would get lost when saving nowadays. if(mpt::saturate_cast(m_RatioTable.size()) >= m_GroupSize - m_StepMin) { std::vector ratios; for(NOTEINDEXTYPE n = 0; n < m_GroupSize; ++n) { ratios.push_back(m_RatioTable[n - m_StepMin]); } CreateGroupGeometric(ratios, m_GroupRatio, GetValidityRange(), 0); } } return SerializationResult::Success; } Tuning::SerializationResult CTuningRTI::Serialize(std::ostream& outStrm) const { // Note: OpenMPT since at least r323 writes version number (4<<24)+4 while it // reads version number (5<<24)+4. // We keep this behaviour. srlztn::SsbWrite ssb(outStrm); ssb.BeginWrite("CTB244RTI", (4 << 24) + 4); // version if (m_TuningName.length() > 0) ssb.WriteItem(m_TuningName, "0", WriteStr); uint16 dummyEditMask = 0xffff; ssb.WriteItem(dummyEditMask, "1"); ssb.WriteItem(m_TuningType, "2"); if (m_NoteNameMap.size() > 0) ssb.WriteItem(m_NoteNameMap, "3", WriteNoteMap); if (GetFineStepCount() > 0) ssb.WriteItem(m_FineStepCount, "4"); const TUNINGTYPE tt = GetType(); if (GetGroupRatio() > 0) ssb.WriteItem(m_GroupRatio, "RTI3"); if (tt == TT_GROUPGEOMETRIC) ssb.WriteItem(m_RatioTable, "RTI0", RatioWriter(GetGroupSize())); if (tt == TT_GENERAL) ssb.WriteItem(m_RatioTable, "RTI0", RatioWriter()); if (tt == TT_GEOMETRIC) ssb.WriteItem(m_GroupSize, "RTI2"); if(tt == TT_GEOMETRIC || tt == TT_GROUPGEOMETRIC) { //For Groupgeometric this data is the number of ratios in ratiotable. UNOTEINDEXTYPE ratiotableSize = static_cast(m_RatioTable.size()); ssb.WriteItem(ratiotableSize, "RTI4"); } //m_StepMin ssb.WriteItem(m_StepMin, "RTI1"); ssb.FinishWrite(); return ((ssb.GetStatus() & srlztn::SNT_FAILURE) != 0) ? Tuning::SerializationResult::Failure : Tuning::SerializationResult::Success; } #ifdef MODPLUG_TRACKER bool CTuningRTI::WriteSCL(std::ostream &f, const mpt::PathString &filename) const { mpt::IO::WriteTextCRLF(f, mpt::format("! %1")(mpt::ToCharset(mpt::CharsetISO8859_1, (filename.GetFileName() + filename.GetFileExt()).ToUnicode()))); mpt::IO::WriteTextCRLF(f, "!"); std::string name = mpt::ToCharset(mpt::CharsetISO8859_1, mpt::CharsetLocale, GetName()); for(auto & c : name) { if(static_cast(c) < 32) c = ' '; } // remove control characters if(name.length() >= 1 && name[0] == '!') name[0] = '?'; // do not confuse description with comment mpt::IO::WriteTextCRLF(f, name); if(GetType() == TT_GEOMETRIC) { mpt::IO::WriteTextCRLF(f, mpt::format(" %1")(m_GroupSize)); mpt::IO::WriteTextCRLF(f, "!"); for(NOTEINDEXTYPE n = 0; n < m_GroupSize; ++n) { double ratio = std::pow(static_cast(m_GroupRatio), static_cast(n + 1) / static_cast(m_GroupSize)); double cents = std::log2(ratio) * 1200.0; mpt::IO::WriteTextCRLF(f, mpt::format(" %1 ! %2")( mpt::fmt::fix(cents), mpt::ToCharset(mpt::CharsetISO8859_1, mpt::CharsetLocale, GetNoteName((n + 1) % m_GroupSize, false)) )); } } else if(GetType() == TT_GROUPGEOMETRIC) { mpt::IO::WriteTextCRLF(f, mpt::format(" %1")(m_GroupSize)); mpt::IO::WriteTextCRLF(f, "!"); for(NOTEINDEXTYPE n = 0; n < m_GroupSize; ++n) { bool last = (n == (m_GroupSize - 1)); double baseratio = static_cast(GetRatio(0)); double ratio = static_cast(last ? m_GroupRatio : GetRatio(n + 1)) / baseratio; double cents = std::log2(ratio) * 1200.0; mpt::IO::WriteTextCRLF(f, mpt::format(" %1 ! %2")( mpt::fmt::fix(cents), mpt::ToCharset(mpt::CharsetISO8859_1, mpt::CharsetLocale, GetNoteName((n + 1) % m_GroupSize, false)) )); } } else if(GetType() == TT_GENERAL) { mpt::IO::WriteTextCRLF(f, mpt::format(" %1")(m_RatioTable.size() + 1)); mpt::IO::WriteTextCRLF(f, "!"); double baseratio = 1.0; for(NOTEINDEXTYPE n = 0; n < mpt::saturate_cast(m_RatioTable.size()); ++n) { baseratio = std::min(baseratio, static_cast(m_RatioTable[n])); } for(NOTEINDEXTYPE n = 0; n < mpt::saturate_cast(m_RatioTable.size()); ++n) { double ratio = static_cast(m_RatioTable[n]) / baseratio; double cents = std::log2(ratio) * 1200.0; mpt::IO::WriteTextCRLF(f, mpt::format(" %1 ! %2")( mpt::fmt::fix(cents), mpt::ToCharset(mpt::CharsetISO8859_1, mpt::CharsetLocale, GetNoteName(n + m_StepMin, false)) )); } mpt::IO::WriteTextCRLF(f, mpt::format(" %1 ! %2")( mpt::fmt::val(1), std::string() )); } else { return false; } return true; } #endif namespace CTuningS11n { void RatioWriter::operator()(std::ostream& oStrm, const std::vector& v) { const size_t nWriteCount = MIN(v.size(), m_nWriteCount); mpt::IO::WriteAdaptiveInt64LE(oStrm, nWriteCount); for(size_t i = 0; i < nWriteCount; i++) mpt::IO::Write(oStrm, IEEE754binary32LE(v[i])); } void ReadNoteMap(std::istream& iStrm, std::map& m, const size_t) { uint64 val; mpt::IO::ReadAdaptiveInt64LE(iStrm, val); LimitMax(val, 256u); // Read 256 at max. for(size_t i = 0; i < val; i++) { int16 key; mpt::IO::ReadIntLE(iStrm, key); std::string str; mpt::IO::ReadSizedStringLE(iStrm, str); m[key] = str; } } void ReadRatioTable(std::istream& iStrm, std::vector& v, const size_t) { uint64 val; mpt::IO::ReadAdaptiveInt64LE(iStrm, val); v.resize( static_cast(MIN(val, 256u))); // Read 256 vals at max. for(size_t i = 0; i < v.size(); i++) { IEEE754binary32LE tmp(0.0f); mpt::IO::Read(iStrm, tmp); v[i] = tmp; } } void ReadStr(std::istream& iStrm, std::string& str, const size_t) { uint64 val; mpt::IO::ReadAdaptiveInt64LE(iStrm, val); size_t nSize = (val > 255) ? 255 : static_cast(val); // Read 255 characters at max. str.clear(); str.resize(nSize); for(size_t i = 0; i < nSize; i++) mpt::IO::ReadIntLE(iStrm, str[i]); if(str.find_first_of('\0') != std::string::npos) { // trim \0 at the end str.resize(str.find_first_of('\0')); } } void WriteNoteMap(std::ostream& oStrm, const std::map& m) { mpt::IO::WriteAdaptiveInt64LE(oStrm, m.size()); for(auto &mi : m) { mpt::IO::WriteIntLE(oStrm, mi.first); mpt::IO::WriteSizedStringLE(oStrm, mi.second); } } void WriteStr(std::ostream& oStrm, const std::string& str) { mpt::IO::WriteAdaptiveInt64LE(oStrm, str.size()); oStrm.write(str.c_str(), str.size()); } } // namespace CTuningS11n. } // namespace Tuning OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Sndmix.cpp0000644000372100037210000025177513233626144020070 00000000000000/* * Sndmix.cpp * ----------- * Purpose: Pattern playback, effect processing * Notes : (currently none) * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Sndfile.h" #include "MixerLoops.h" #include "MIDIEvents.h" #include "tuning.h" #include "Tables.h" #ifdef MODPLUG_TRACKER #include "../mptrack/TrackerSettings.h" #endif // MODPLUG_TRACKER #ifndef NO_PLUGINS #include "plugins/PlugInterface.h" #endif // NO_PLUGINS OPENMPT_NAMESPACE_BEGIN // VU-Meter #define VUMETER_DECAY 4 // Log tables for pre-amp // Pre-amp (or more precisely: Pre-attenuation) depends on the number of channels, // Which this table takes care of. static const uint8 PreAmpTable[16] = { 0x60, 0x60, 0x60, 0x70, // 0-7 0x80, 0x88, 0x90, 0x98, // 8-15 0xA0, 0xA4, 0xA8, 0xAC, // 16-23 0xB0, 0xB4, 0xB8, 0xBC, // 24-31 }; #ifndef NO_AGC static const uint8 PreAmpAGCTable[16] = { 0x60, 0x60, 0x60, 0x64, 0x68, 0x70, 0x78, 0x80, 0x84, 0x88, 0x8C, 0x90, 0x92, 0x94, 0x96, 0x98, }; #endif // Compensate frequency slide LUTs depending on whether we are handling periods or frequency - "up" and "down" in function name are seen from frequency perspective. static uint32 GetLinearSlideDownTable (const CSoundFile *sndFile, uint32 i) { MPT_ASSERT(i < CountOf(LinearSlideDownTable)); return sndFile->m_playBehaviour[kHertzInLinearMode] ? LinearSlideDownTable[i] : LinearSlideUpTable[i]; } static uint32 GetLinearSlideUpTable (const CSoundFile *sndFile, uint32 i) { MPT_ASSERT(i < CountOf(LinearSlideDownTable)); return sndFile->m_playBehaviour[kHertzInLinearMode] ? LinearSlideUpTable[i] : LinearSlideDownTable[i]; } static uint32 GetFineLinearSlideDownTable(const CSoundFile *sndFile, uint32 i) { MPT_ASSERT(i < CountOf(FineLinearSlideDownTable)); return sndFile->m_playBehaviour[kHertzInLinearMode] ? FineLinearSlideDownTable[i] : FineLinearSlideUpTable[i]; } static uint32 GetFineLinearSlideUpTable (const CSoundFile *sndFile, uint32 i) { MPT_ASSERT(i < CountOf(FineLinearSlideDownTable)); return sndFile->m_playBehaviour[kHertzInLinearMode] ? FineLinearSlideUpTable[i] : FineLinearSlideDownTable[i]; } void CSoundFile::SetMixerSettings(const MixerSettings &mixersettings) { SetPreAmp(mixersettings.m_nPreAmp); // adjust agc bool reset = false; if( (mixersettings.gdwMixingFreq != m_MixerSettings.gdwMixingFreq) || (mixersettings.gnChannels != m_MixerSettings.gnChannels) || (mixersettings.MixerFlags != m_MixerSettings.MixerFlags)) reset = true; m_MixerSettings = mixersettings; InitPlayer(reset); } void CSoundFile::SetResamplerSettings(const CResamplerSettings &resamplersettings) { m_Resampler.m_Settings = resamplersettings; m_Resampler.UpdateTables(); InitAmigaResampler(); } void CSoundFile::InitPlayer(bool bReset) { if(bReset) { ResetMixStat(); gnDryLOfsVol = 0; gnDryROfsVol = 0; InitAmigaResampler(); } m_Resampler.UpdateTables(); #ifndef NO_REVERB m_Reverb.Initialize(bReset, m_MixerSettings.gdwMixingFreq); #endif #ifndef NO_DSP m_Surround.Initialize(bReset, m_MixerSettings.gdwMixingFreq); #endif #ifndef NO_DSP m_MegaBass.Initialize(bReset, m_MixerSettings.gdwMixingFreq); #endif #ifndef NO_EQ m_EQ.Initialize(bReset, m_MixerSettings.gdwMixingFreq); #endif #ifndef NO_AGC m_AGC.Initialize(bReset, m_MixerSettings.gdwMixingFreq); #endif } bool CSoundFile::FadeSong(uint32 msec) { samplecount_t nsamples = Util::muldiv(msec, m_MixerSettings.gdwMixingFreq, 1000); if (nsamples <= 0) return false; if (nsamples > 0x100000) nsamples = 0x100000; m_PlayState.m_nBufferCount = nsamples; int32 nRampLength = static_cast(m_PlayState.m_nBufferCount); // Ramp everything down for (uint32 noff=0; noff < m_nMixChannels; noff++) { ModChannel &pramp = m_PlayState.Chn[m_PlayState.ChnMix[noff]]; pramp.newRightVol = pramp.newLeftVol = 0; pramp.leftRamp = (-pramp.leftVol << VOLUMERAMPPRECISION) / nRampLength; pramp.rightRamp = (-pramp.rightVol << VOLUMERAMPPRECISION) / nRampLength; pramp.rampLeftVol = pramp.leftVol << VOLUMERAMPPRECISION; pramp.rampRightVol = pramp.rightVol << VOLUMERAMPPRECISION; pramp.nRampLength = nRampLength; pramp.dwFlags.set(CHN_VOLUMERAMP); } return true; } // Apply stereo separation factor on an interleaved stereo/quad stream. // count = Number of stereo sample pairs to process // separation = -256...256 (negative values = swap L/R, 0 = mono, 128 = normal) static void ApplyStereoSeparation(mixsample_t *mixBuf, std::size_t count, int32 separation) { #ifdef MPT_INTMIXER const mixsample_t factor_num = separation; // 128 =^= 1.0f const mixsample_t factor_den = MixerSettings::StereoSeparationScale; // 128 const mixsample_t normalize_den = 2; // mid/side pre/post normalization const mixsample_t mid_den = normalize_den; const mixsample_t side_num = factor_num; const mixsample_t side_den = factor_den * normalize_den; #else const float normalize_factor = 0.5f; // cumulative mid/side normalization factor (1/sqrt(2))*(1/sqrt(2)) const float factor = static_cast(separation) / static_cast(MixerSettings::StereoSeparationScale); // sep / 128 const float mid_factor = normalize_factor; const float side_factor = factor * normalize_factor; #endif for(std::size_t i = 0; i < count; i++) { mixsample_t l = mixBuf[0]; mixsample_t r = mixBuf[1]; mixsample_t m = l + r; mixsample_t s = l - r; #ifdef MPT_INTMIXER m /= mid_den; s = Util::muldiv(s, side_num, side_den); #else m *= mid_factor; s *= side_factor; #endif l = m + s; r = m - s; mixBuf[0] = l; mixBuf[1] = r; mixBuf += 2; } } static void ApplyStereoSeparation(mixsample_t *SoundFrontBuffer, mixsample_t *SoundRearBuffer, std::size_t channels, std::size_t countChunk, int32 separation) { if(separation == MixerSettings::StereoSeparationScale) { // identity return; } if(channels >= 2) ApplyStereoSeparation(SoundFrontBuffer, countChunk, separation); if(channels >= 4) ApplyStereoSeparation(SoundRearBuffer , countChunk, separation); } CSoundFile::samplecount_t CSoundFile::Read(samplecount_t count, IAudioReadTarget &target) { MPT_ASSERT_ALWAYS(m_MixerSettings.IsValid()); bool mixPlugins = false; #ifndef NO_PLUGINS for(const auto &plug : m_MixPlugins) { if(plug.pMixPlugin) { mixPlugins = true; break; } } #endif // NO_PLUGINS samplecount_t countRendered = 0; samplecount_t countToRender = count; while(!m_SongFlags[SONG_ENDREACHED] && countToRender > 0) { // Update Channel Data if(!m_PlayState.m_nBufferCount) { // last tick or fade completely processed, find out what to do next if(m_SongFlags[SONG_FADINGSONG]) { // song was faded out m_SongFlags.set(SONG_ENDREACHED); } else if(ReadNote()) { // render next tick (normal progress) MPT_ASSERT(m_PlayState.m_nBufferCount > 0); #ifdef MODPLUG_TRACKER // Save pattern cue points for WAV rendering here (if we reached a new pattern, that is.) if(IsRenderingToDisc() && (m_PatternCuePoints.empty() || m_PlayState.m_nCurrentOrder != m_PatternCuePoints.back().order)) { PatternCuePoint cue; cue.offset = countRendered; cue.order = m_PlayState.m_nCurrentOrder; cue.processed = false; // We don't know the base offset in the file here. It has to be added in the main conversion loop. m_PatternCuePoints.push_back(cue); } #endif } else { // no new pattern data #ifdef MODPLUG_TRACKER if((m_nMaxOrderPosition) && (m_PlayState.m_nCurrentOrder >= m_nMaxOrderPosition)) { m_SongFlags.set(SONG_ENDREACHED); } #endif // MODPLUG_TRACKER if(IsRenderingToDisc()) { // rewbs: disable song fade when rendering. m_SongFlags.set(SONG_ENDREACHED); } else { // end of song reached, fade it out if(FadeSong(FADESONGDELAY)) // sets m_nBufferCount xor returns false { // FadeSong sets m_nBufferCount here MPT_ASSERT(m_PlayState.m_nBufferCount > 0); m_SongFlags.set(SONG_FADINGSONG); } else { m_SongFlags.set(SONG_ENDREACHED); } } } } if(m_SongFlags[SONG_ENDREACHED]) { break; // mix done } MPT_ASSERT(m_PlayState.m_nBufferCount > 0); // assert that we have actually something to do const samplecount_t countChunk = std::min(MIXBUFFERSIZE, std::min(m_PlayState.m_nBufferCount, countToRender)); CreateStereoMix(countChunk); #ifndef NO_REVERB m_Reverb.Process(MixSoundBuffer, countChunk); #endif // NO_REVERB if(mixPlugins) { ProcessPlugins(countChunk); } if(m_MixerSettings.gnChannels == 1) { MonoFromStereo(MixSoundBuffer, countChunk); } if(m_PlayConfig.getGlobalVolumeAppliesToMaster()) { ProcessGlobalVolume(countChunk); } if(m_MixerSettings.m_nStereoSeparation != MixerSettings::StereoSeparationScale) { ProcessStereoSeparation(countChunk); } if(m_MixerSettings.DSPMask) { ProcessDSP(countChunk); } if(m_MixerSettings.gnChannels == 4) { InterleaveFrontRear(MixSoundBuffer, MixRearBuffer, countChunk); } target.DataCallback(MixSoundBuffer, m_MixerSettings.gnChannels, countChunk); // Buffer ready countRendered += countChunk; countToRender -= countChunk; m_PlayState.m_nBufferCount -= countChunk; m_PlayState.m_lTotalSampleCount += countChunk; // increase sample count for VSTTimeInfo. #ifdef MODPLUG_TRACKER if(IsRenderingToDisc()) { // Stop playback on F00 if no more voices are active. // F00 sets the tick count to 65536 in FT2, so it just generates a reaaaally long row. // Usually this command can be found at the end of a song to effectively stop playback. // Since we don't want to render hours of silence, we are going to check if there are // still any channels playing, and if that is no longer the case, we stop playback at // the end of the next tick. if(m_PlayState.m_nMusicSpeed == uint16_max && (m_nMixStat == 0 || m_PlayState.m_nGlobalVolume == 0) && GetType() == MOD_TYPE_XM && !m_PlayState.m_nBufferCount) { m_SongFlags.set(SONG_ENDREACHED); } } #endif // MODPLUG_TRACKER } // mix done return countRendered; } void CSoundFile::ProcessDSP(std::size_t countChunk) { #ifndef NO_DSP if(m_MixerSettings.DSPMask & SNDDSP_SURROUND) { m_Surround.Process(MixSoundBuffer, MixRearBuffer, countChunk, m_MixerSettings.gnChannels); } #endif // NO_DSP #ifndef NO_DSP if(m_MixerSettings.DSPMask & SNDDSP_MEGABASS) { m_MegaBass.Process(MixSoundBuffer, MixRearBuffer, countChunk, m_MixerSettings.gnChannels); } #endif // NO_DSP #ifndef NO_EQ if(m_MixerSettings.DSPMask & SNDDSP_EQ) { m_EQ.Process(MixSoundBuffer, MixRearBuffer, countChunk, m_MixerSettings.gnChannels); } #endif // NO_EQ #ifndef NO_AGC if(m_MixerSettings.DSPMask & SNDDSP_AGC) { m_AGC.Process(MixSoundBuffer, MixRearBuffer, countChunk, m_MixerSettings.gnChannels); } #endif // NO_AGC #if defined(NO_DSP) && defined(NO_EQ) && defined(NO_AGC) MPT_UNREFERENCED_PARAMETER(countChunk); #endif } ///////////////////////////////////////////////////////////////////////////// // Handles navigation/effects bool CSoundFile::ProcessRow() { while(++m_PlayState.m_nTickCount >= GetNumTicksOnCurrentRow()) { // When having an EEx effect on the same row as a Dxx jump, the target row is not played in ProTracker. // Test case: DelayBreak.mod (based on condom_corruption by Travolta) const bool ignoreRow = m_PlayState.m_nPatternDelay != 0 && m_SongFlags[SONG_BREAKTOROW] && GetType() == MOD_TYPE_MOD; // Done with the last row of the pattern or jumping somewhere else const bool patternTransition = m_PlayState.m_nNextRow == 0 || m_SongFlags[SONG_BREAKTOROW]; if(patternTransition) { if(GetType() == MOD_TYPE_S3M) { // Reset pattern loop start // Test case: LoopReset.s3m for(CHANNELINDEX i = 0; i < GetNumChannels(); i++) { m_PlayState.Chn[i].nPatternLoop = 0; } } } m_PlayState.m_nPatternDelay = 0; m_PlayState.m_nFrameDelay = 0; m_PlayState.m_nTickCount = 0; m_PlayState.m_nRow = m_PlayState.m_nNextRow; // Reset Pattern Loop Effect m_PlayState.m_nCurrentOrder = m_PlayState.m_nNextOrder; #ifdef MODPLUG_TRACKER if(patternTransition) { HandlePatternTransitionEvents(); } // "Lock row" editing feature if(m_lockRowStart != ROWINDEX_INVALID && (m_PlayState.m_nRow < m_lockRowStart || m_PlayState.m_nRow > m_lockRowEnd) && !IsRenderingToDisc()) { m_PlayState.m_nRow = m_lockRowStart; } // "Lock order" editing feature if(Order().IsPositionLocked(m_PlayState.m_nCurrentOrder) && !IsRenderingToDisc()) { m_PlayState.m_nCurrentOrder = m_lockOrderStart; } #endif // MODPLUG_TRACKER // Check if pattern is valid if(!m_SongFlags[SONG_PATTERNLOOP]) { m_PlayState.m_nPattern = (m_PlayState.m_nCurrentOrder < Order().size()) ? Order()[m_PlayState.m_nCurrentOrder] : Order.GetInvalidPatIndex(); if (m_PlayState.m_nPattern < Patterns.Size() && !Patterns[m_PlayState.m_nPattern].IsValid()) m_PlayState.m_nPattern = Order.GetIgnoreIndex(); while (m_PlayState.m_nPattern >= Patterns.Size()) { // End of song? if ((m_PlayState.m_nPattern == Order.GetInvalidPatIndex()) || (m_PlayState.m_nCurrentOrder >= Order().size())) { //if (!m_nRepeatCount) return false; ORDERINDEX restartPosOverride = Order().GetRestartPos(); if(restartPosOverride == 0 && m_PlayState.m_nCurrentOrder <= Order().size() && m_PlayState.m_nCurrentOrder > 0) { // Subtune detection. Subtunes are separated by "---" order items, so if we're in a // subtune and there's no restart position, we go to the first order of the subtune // (i.e. the first order after the previous "---" item) for(ORDERINDEX ord = m_PlayState.m_nCurrentOrder - 1; ord > 0; ord--) { if(Order()[ord] == Order.GetInvalidPatIndex()) { // Jump back to first order of this subtune restartPosOverride = ord + 1; break; } } } // If channel resetting is disabled in MPT, we will emulate a pattern break (and we always do it if we're not in MPT) #ifdef MODPLUG_TRACKER if(!(TrackerSettings::Instance().m_dwPatternSetup & PATTERN_RESETCHANNELS)) #endif // MODPLUG_TRACKER { m_SongFlags.set(SONG_BREAKTOROW); } if (restartPosOverride == 0 && !m_SongFlags[SONG_BREAKTOROW]) { //rewbs.instroVSTi: stop all VSTi at end of song, if looping. StopAllVsti(); m_PlayState.m_nMusicSpeed = m_nDefaultSpeed; m_PlayState.m_nMusicTempo = m_nDefaultTempo; m_PlayState.m_nGlobalVolume = m_nDefaultGlobalVolume; for(CHANNELINDEX i = 0; i < MAX_CHANNELS; i++) { m_PlayState.Chn[i].dwFlags.set(CHN_NOTEFADE | CHN_KEYOFF); m_PlayState.Chn[i].nFadeOutVol = 0; if (i < m_nChannels) { m_PlayState.Chn[i].nGlobalVol = ChnSettings[i].nVolume; m_PlayState.Chn[i].nVolume = ChnSettings[i].nVolume; m_PlayState.Chn[i].nPan = ChnSettings[i].nPan; m_PlayState.Chn[i].nPanSwing = m_PlayState.Chn[i].nVolSwing = 0; m_PlayState.Chn[i].nCutSwing = m_PlayState.Chn[i].nResSwing = 0; m_PlayState.Chn[i].nOldVolParam = 0; m_PlayState.Chn[i].oldOffset = 0; m_PlayState.Chn[i].nOldHiOffset = 0; m_PlayState.Chn[i].nPortamentoDest = 0; if (!m_PlayState.Chn[i].nLength) { m_PlayState.Chn[i].dwFlags = ChnSettings[i].dwFlags; m_PlayState.Chn[i].nLoopStart = 0; m_PlayState.Chn[i].nLoopEnd = 0; m_PlayState.Chn[i].pModInstrument = nullptr; m_PlayState.Chn[i].pModSample = nullptr; } } } } //Handle Repeat position //if (m_nRepeatCount > 0) m_nRepeatCount--; m_PlayState.m_nCurrentOrder = restartPosOverride; m_SongFlags.reset(SONG_BREAKTOROW); //If restart pos points to +++, move along while(m_PlayState.m_nCurrentOrder < Order().size() && Order()[m_PlayState.m_nCurrentOrder] == Order.GetIgnoreIndex()) { m_PlayState.m_nCurrentOrder++; } //Check for end of song or bad pattern if (m_PlayState.m_nCurrentOrder >= Order().size() || !Order().IsValidPat(m_PlayState.m_nCurrentOrder)) { visitedSongRows.Initialize(true); return false; } } else { m_PlayState.m_nCurrentOrder++; } if (m_PlayState.m_nCurrentOrder < Order().size()) m_PlayState.m_nPattern = Order()[m_PlayState.m_nCurrentOrder]; else m_PlayState.m_nPattern = Order.GetInvalidPatIndex(); if (m_PlayState.m_nPattern < Patterns.Size() && !Patterns[m_PlayState.m_nPattern].IsValid()) m_PlayState.m_nPattern = Order.GetIgnoreIndex(); } m_PlayState.m_nNextOrder = m_PlayState.m_nCurrentOrder; #ifdef MODPLUG_TRACKER if ((m_nMaxOrderPosition) && (m_PlayState.m_nCurrentOrder >= m_nMaxOrderPosition)) return false; #endif // MODPLUG_TRACKER } // Weird stuff? if (!Patterns.IsValidPat(m_PlayState.m_nPattern)) return false; // Did we jump to an invalid row? if (m_PlayState.m_nRow >= Patterns[m_PlayState.m_nPattern].GetNumRows()) m_PlayState.m_nRow = 0; // Has this row been visited before? We might want to stop playback now. // But: We will not mark the row as modified if the song is not in loop mode but // the pattern loop (editor flag, not to be confused with the pattern loop effect) // flag is set - because in that case, the module would stop after the first pattern loop... const bool overrideLoopCheck = (m_nRepeatCount != -1) && m_SongFlags[SONG_PATTERNLOOP]; if(!overrideLoopCheck && visitedSongRows.IsVisited(m_PlayState.m_nCurrentOrder, m_PlayState.m_nRow, true)) { if(m_nRepeatCount) { // repeat count == -1 means repeat infinitely. if(m_nRepeatCount > 0) { m_nRepeatCount--; } // Forget all but the current row. visitedSongRows.Initialize(true); visitedSongRows.Visit(m_PlayState.m_nCurrentOrder, m_PlayState.m_nRow); } else { #ifdef MODPLUG_TRACKER // Let's check again if this really is the end of the song. // The visited rows vector might have been screwed up while editing... // This is of course not possible during rendering to WAV, so we ignore that case. GetLengthType t = GetLength(eNoAdjust).back(); if(IsRenderingToDisc() || (t.lastOrder == m_PlayState.m_nCurrentOrder && t.lastRow == m_PlayState.m_nRow)) { // This is really the song's end! visitedSongRows.Initialize(true); return false; } else { // Ok, this is really dirty, but we have to update the visited rows vector... GetLength(eAdjustOnSuccess, GetLengthTarget(m_PlayState.m_nCurrentOrder, m_PlayState.m_nRow)); } #else if(m_SongFlags[SONG_PLAYALLSONGS]) { // When playing all subsongs consecutively, first search for any hidden subsongs... if(!visitedSongRows.GetFirstUnvisitedRow(m_PlayState.m_nCurrentOrder, m_PlayState.m_nRow, true)) { // ...and then try the next sequence. m_PlayState.m_nNextOrder = m_PlayState.m_nCurrentOrder = 0; m_PlayState.m_nNextRow = m_PlayState.m_nRow = 0; if(Order.GetCurrentSequenceIndex() >= Order.GetNumSequences() - 1) { Order.SetSequence(0); visitedSongRows.Initialize(true); return false; } Order.SetSequence(Order.GetCurrentSequenceIndex() + 1); visitedSongRows.Initialize(true); } // When jumping to the next subsong, stop all playing notes from the previous song... for(CHANNELINDEX i = 0; i < MAX_CHANNELS; i++) m_PlayState.Chn[i].Reset(ModChannel::resetSetPosFull, *this, i); StopAllVsti(); // ...and the global playback information. m_PlayState.m_nMusicSpeed = m_nDefaultSpeed; m_PlayState.m_nMusicTempo = m_nDefaultTempo; m_PlayState.m_nGlobalVolume = m_nDefaultGlobalVolume; m_PlayState.m_nNextOrder = m_PlayState.m_nCurrentOrder; m_PlayState.m_nNextRow = m_PlayState.m_nRow; if(Order().size() > m_PlayState.m_nCurrentOrder) m_PlayState.m_nPattern = Order()[m_PlayState.m_nCurrentOrder]; visitedSongRows.Visit(m_PlayState.m_nCurrentOrder, m_PlayState.m_nRow); if (!Patterns.IsValidPat(m_PlayState.m_nPattern)) return false; } else { visitedSongRows.Initialize(true); return false; } #endif // MODPLUG_TRACKER } } m_PlayState.m_nNextRow = m_PlayState.m_nRow + 1; if (m_PlayState.m_nNextRow >= Patterns[m_PlayState.m_nPattern].GetNumRows()) { if (!m_SongFlags[SONG_PATTERNLOOP]) m_PlayState.m_nNextOrder = m_PlayState.m_nCurrentOrder + 1; m_PlayState.m_nNextRow = 0; // FT2 idiosyncrasy: When E60 is used on a pattern row x, the following pattern also starts from row x // instead of the beginning of the pattern, unless there was a Bxx or Dxx effect. if(m_playBehaviour[kFT2LoopE60Restart]) { m_PlayState.m_nNextRow = m_PlayState.m_nNextPatStartRow; m_PlayState.m_nNextPatStartRow = 0; } } // Reset channel values ModCommand *m = Patterns[m_PlayState.m_nPattern].GetRow(m_PlayState.m_nRow); for (ModChannel *pChn = m_PlayState.Chn, *pEnd = pChn + m_nChannels; pChn != pEnd; pChn++, m++) { // First, handle some quirks that happen after the last tick of the previous row... if(m_playBehaviour[KST3PortaAfterArpeggio] && pChn->nCommand == CMD_ARPEGGIO // Previous row state! && (m->command == CMD_PORTAMENTOUP || m->command == CMD_PORTAMENTODOWN)) { // In ST3, a portamento immediately following an arpeggio continues where the arpeggio left off. // Test case: PortaAfterArp.s3m pChn->nPeriod = GetPeriodFromNote(pChn->nArpeggioLastNote, pChn->nFineTune, pChn->nC5Speed); } if(m_playBehaviour[kMODOutOfRangeNoteDelay] && !m->IsNote() && pChn->rowCommand.IsNote() && pChn->rowCommand.command == CMD_MODCMDEX && (pChn->rowCommand.param & 0xF0) == 0xD0 && (pChn->rowCommand.param & 0x0Fu) >= m_PlayState.m_nMusicSpeed) { // In ProTracker, a note triggered by an out-of-range note delay can be heard on the next row // if there is no new note on that row. // Test case: NoteDelay-NextRow.mod pChn->nPeriod = GetPeriodFromNote(pChn->rowCommand.note, pChn->nFineTune, 0); } if(m_playBehaviour[kMODTempoOnSecondTick] && !m_playBehaviour[kMODVBlankTiming] && m_PlayState.m_nMusicSpeed == 1 && pChn->rowCommand.command == CMD_TEMPO) { // ProTracker sets the tempo after the first tick. This block handles the case of one tick per row. // Test case: TempoChange.mod m_PlayState.m_nMusicTempo = TEMPO(pChn->rowCommand.param, 0); } pChn->rowCommand = *m; pChn->rightVol = pChn->newRightVol; pChn->leftVol = pChn->newLeftVol; pChn->dwFlags.reset(CHN_VIBRATO | CHN_TREMOLO); if(!m_playBehaviour[kITVibratoTremoloPanbrello]) pChn->nPanbrelloOffset = 0; pChn->nCommand = CMD_NONE; pChn->m_plugParamValueStep = 0; } // Now that we know which pattern we're on, we can update time signatures (global or pattern-specific) UpdateTimeSignature(); if(ignoreRow) { m_PlayState.m_nTickCount = m_PlayState.m_nMusicSpeed; continue; } break; } // Should we process tick0 effects? if (!m_PlayState.m_nMusicSpeed) m_PlayState.m_nMusicSpeed = 1; //End of row? stop pattern step (aka "play row"). #ifdef MODPLUG_TRACKER if (m_PlayState.m_nTickCount >= GetNumTicksOnCurrentRow() - 1) { if(m_SongFlags[SONG_STEP]) { m_SongFlags.reset(SONG_STEP); m_SongFlags.set(SONG_PAUSED); } } #endif // MODPLUG_TRACKER if (m_PlayState.m_nTickCount) { m_SongFlags.reset(SONG_FIRSTTICK); if(!(GetType() & (MOD_TYPE_XM | MOD_TYPE_MT2)) && m_PlayState.m_nTickCount < GetNumTicksOnCurrentRow()) { // Emulate first tick behaviour if Row Delay is set. // Test cases: PatternDelaysRetrig.it, PatternDelaysRetrig.s3m, PatternDelaysRetrig.xm, PatternDelaysRetrig.mod if(!(m_PlayState.m_nTickCount % (m_PlayState.m_nMusicSpeed + m_PlayState.m_nFrameDelay))) { m_SongFlags.set(SONG_FIRSTTICK); } } } else { m_SongFlags.set(SONG_FIRSTTICK); m_SongFlags.reset(SONG_BREAKTOROW); } // Update Effects return ProcessEffects(); } //////////////////////////////////////////////////////////////////////////////////////////// // Channel effect processing // Calculate delta for Vibrato / Tremolo / Panbrello effect int CSoundFile::GetVibratoDelta(int type, int position) const { // IT compatibility: IT has its own, more precise tables if(m_playBehaviour[kITVibratoTremoloPanbrello]) { position &= 0xFF; switch(type & 0x03) { case 0: // Sine default: return ITSinusTable[position]; case 1: // Ramp down return 64 - (position + 1) / 2; case 2: // Square return position < 128 ? 64 : 0; case 3: // Random return mpt::random(AccessPRNG()) - 0x40; } } else if(GetType() & (MOD_TYPE_DIGI | MOD_TYPE_DBM)) { // Other waveforms are not supported. static const int8 DBMSinus[] = { 33, 52, 69, 84, 96, 107, 116, 122, 125, 127, 125, 122, 116, 107, 96, 84, 69, 52, 33, 13, -8, -31, -54, -79, -104,-128, -104, -79, -54, -31, -8, 13, }; return DBMSinus[(position / 2u) & 0x1F]; } else { position &= 0x3F; switch(type & 0x03) { case 0: // Sine default: return ModSinusTable[position]; case 1: // Ramp down return (position < 32 ? 0 : 255) - position * 4; case 2: // Square return position < 32 ? 127 : -127; case 3: // Random return ModRandomTable[position]; } } } void CSoundFile::ProcessVolumeSwing(ModChannel *pChn, int &vol) const { if(m_playBehaviour[kITSwingBehaviour]) { vol += pChn->nVolSwing; Limit(vol, 0, 64); } else if(m_playBehaviour[kMPTOldSwingBehaviour]) { vol += pChn->nVolSwing; Limit(vol, 0, 256); } else { pChn->nVolume += pChn->nVolSwing; Limit(pChn->nVolume, 0, 256); vol = pChn->nVolume; pChn->nVolSwing = 0; } } void CSoundFile::ProcessPanningSwing(ModChannel *pChn) const { if(m_playBehaviour[kITSwingBehaviour] || m_playBehaviour[kMPTOldSwingBehaviour]) { pChn->nRealPan = pChn->nPan + pChn->nPanSwing; Limit(pChn->nRealPan, 0, 256); } else { pChn->nPan += pChn->nPanSwing; Limit(pChn->nPan, 0, 256); pChn->nPanSwing = 0; pChn->nRealPan = pChn->nPan; } } void CSoundFile::ProcessTremolo(ModChannel *pChn, int &vol) const { if (pChn->dwFlags[CHN_TREMOLO]) { if(m_SongFlags.test_all(SONG_FIRSTTICK | SONG_PT_MODE)) { // ProTracker doesn't apply tremolo nor advance on the first tick. // Test case: VibratoReset.mod return; } // IT compatibility: Why would you not want to execute tremolo at volume 0? if(vol > 0 || m_playBehaviour[kITVibratoTremoloPanbrello]) { // IT compatibility: We don't need a different attenuation here because of the different tables we're going to use const uint8 attenuation = ((GetType() & (MOD_TYPE_XM | MOD_TYPE_MOD)) || m_playBehaviour[kITVibratoTremoloPanbrello]) ? 5 : 6; int delta = GetVibratoDelta(pChn->nTremoloType, pChn->nTremoloPos); if((pChn->nTremoloType & 0x03) == 1 && m_playBehaviour[kFT2TremoloRampWaveform]) { // FT2 compatibility: Tremolo ramp down / triangle implementation is weird and affected by vibrato position (copypaste bug) // Test case: TremoloWaveforms.xm, TremoloVibrato.xm uint8 ramp = (pChn->nTremoloPos * 4u) & 0x7F; // Volume-colum vibrato gets executed first in FT2, so we may need to advance the vibrato position first uint32 vibPos = pChn->nVibratoPos; if(!m_SongFlags[SONG_FIRSTTICK] && pChn->dwFlags[CHN_VIBRATO]) vibPos += pChn->nVibratoSpeed; if((vibPos & 0x3F) >= 32) ramp ^= 0x7F; if((pChn->nTremoloPos & 0x3F) >= 32) delta = -ramp; else delta = ramp; } if(GetType() != MOD_TYPE_DMF) { vol += (delta * pChn->nTremoloDepth) / (1 << attenuation); } else { // Tremolo in DMF always attenuates by a percentage of the current note volume vol -= (vol * pChn->nTremoloDepth * (64 - delta)) / (128 * 64); } } if(!m_SongFlags[SONG_FIRSTTICK] || ((GetType() & (MOD_TYPE_IT|MOD_TYPE_MPT)) && !m_SongFlags[SONG_ITOLDEFFECTS])) { // IT compatibility: IT has its own, more precise tables if(m_playBehaviour[kITVibratoTremoloPanbrello]) pChn->nTremoloPos += 4 * pChn->nTremoloSpeed; else pChn->nTremoloPos += pChn->nTremoloSpeed; } } } void CSoundFile::ProcessTremor(CHANNELINDEX nChn, int &vol) { ModChannel &chn = m_PlayState.Chn[nChn]; if(m_playBehaviour[kFT2Tremor]) { // FT2 Compatibility: Weird XM tremor. // Test case: Tremor.xm if(chn.nTremorCount & 0x80) { if(!m_SongFlags[SONG_FIRSTTICK] && chn.nCommand == CMD_TREMOR) { chn.nTremorCount &= ~0x20; if(chn.nTremorCount == 0x80) { // Reached end of off-time chn.nTremorCount = (chn.nTremorParam >> 4) | 0xC0; } else if(chn.nTremorCount == 0xC0) { // Reached end of on-time chn.nTremorCount = (chn.nTremorParam & 0x0F) | 0x80; } else { chn.nTremorCount--; } chn.dwFlags.set(CHN_FASTVOLRAMP); } if((chn.nTremorCount & 0xE0) == 0x80) { vol = 0; } } } else if(chn.nCommand == CMD_TREMOR) { // IT compatibility 12. / 13.: Tremor if(m_playBehaviour[kITTremor]) { if((chn.nTremorCount & 0x80) && chn.nLength) { if (chn.nTremorCount == 0x80) chn.nTremorCount = (chn.nTremorParam >> 4) | 0xC0; else if (chn.nTremorCount == 0xC0) chn.nTremorCount = (chn.nTremorParam & 0x0F) | 0x80; else chn.nTremorCount--; } if((chn.nTremorCount & 0xC0) == 0x80) vol = 0; } else { uint8 ontime = chn.nTremorParam >> 4; uint8 n = ontime + (chn.nTremorParam & 0x0F); // Total tremor cycle time (On + Off) if ((!(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT))) || m_SongFlags[SONG_ITOLDEFFECTS]) { n += 2; ontime++; } uint8 tremcount = chn.nTremorCount; if(!(GetType() & MOD_TYPE_XM)) { if (tremcount >= n) tremcount = 0; if (tremcount >= ontime) vol = 0; chn.nTremorCount = tremcount + 1; } else { if(m_SongFlags[SONG_FIRSTTICK]) { // tremcount is only 0 on the first tremor tick after triggering a note. if(tremcount > 0) { tremcount--; } } else { chn.nTremorCount = tremcount + 1; } if (tremcount % n >= ontime) vol = 0; } } chn.dwFlags.set(CHN_FASTVOLRAMP); } #ifndef NO_PLUGINS // Plugin tremor if(chn.nCommand == CMD_TREMOR && chn.pModInstrument && chn.pModInstrument->nMixPlug && !chn.pModInstrument->dwFlags[INS_MUTE] && !chn.dwFlags[CHN_MUTE | CHN_SYNCMUTE] && ModCommand::IsNote(chn.nLastNote)) { const ModInstrument *pIns = chn.pModInstrument; IMixPlugin *pPlugin = m_MixPlugins[pIns->nMixPlug - 1].pMixPlugin; if(pPlugin) { uint8 midiChn = GetBestMidiChannel(nChn); bool isPlaying = pPlugin->IsNotePlaying(chn.nLastNote, midiChn, nChn); if(vol == 0 && isPlaying) pPlugin->MidiCommand(midiChn, pIns->nMidiProgram, pIns->wMidiBank, chn.nLastNote + NOTE_MAX_SPECIAL, 0, nChn); else if(vol != 0 && !isPlaying) pPlugin->MidiCommand(midiChn, pIns->nMidiProgram, pIns->wMidiBank, chn.nLastNote, static_cast(chn.nVolume), nChn); } } #endif // NO_PLUGINS } bool CSoundFile::IsEnvelopeProcessed(const ModChannel *pChn, EnvelopeType env) const { if(pChn->pModInstrument == nullptr) { return false; } const InstrumentEnvelope &insEnv = pChn->pModInstrument->GetEnvelope(env); // IT Compatibility: S77/S79/S7B do not disable the envelope, they just pause the counter // Test cases: s77.it, EnvLoops.xm return ((pChn->GetEnvelope(env).flags[ENV_ENABLED] || (insEnv.dwFlags[ENV_ENABLED] && m_playBehaviour[kITEnvelopePositionHandling])) && !insEnv.empty()); } void CSoundFile::ProcessVolumeEnvelope(ModChannel *pChn, int &vol) const { if(IsEnvelopeProcessed(pChn, ENV_VOLUME)) { const ModInstrument *pIns = pChn->pModInstrument; if(m_playBehaviour[kITEnvelopePositionHandling] && pChn->VolEnv.nEnvPosition == 0) { // If the envelope is disabled at the very same moment as it is triggered, we do not process anything. return; } const int envpos = pChn->VolEnv.nEnvPosition - (m_playBehaviour[kITEnvelopePositionHandling] ? 1 : 0); // Get values in [0, 256] int envval = pIns->VolEnv.GetValueFromPosition(envpos, 256); // if we are in the release portion of the envelope, // rescale envelope factor so that it is proportional to the release point // and release envelope beginning. if(pIns->VolEnv.nReleaseNode != ENV_RELEASE_NODE_UNSET && envpos >= pIns->VolEnv[pIns->VolEnv.nReleaseNode].tick && pChn->VolEnv.nEnvValueAtReleaseJump != NOT_YET_RELEASED) { int envValueAtReleaseJump = pChn->VolEnv.nEnvValueAtReleaseJump; int envValueAtReleaseNode = pIns->VolEnv[pIns->VolEnv.nReleaseNode].value * 4; //If we have just hit the release node, force the current env value //to be that of the release node. This works around the case where // we have another node at the same position as the release node. if(envpos == pIns->VolEnv[pIns->VolEnv.nReleaseNode].tick) envval = envValueAtReleaseNode; int relativeVolumeChange = (envval - envValueAtReleaseNode) * 2; envval = envValueAtReleaseJump + relativeVolumeChange; } vol = (vol * Clamp(envval, 0, 512)) / 256; } } void CSoundFile::ProcessPanningEnvelope(ModChannel *pChn) const { if(IsEnvelopeProcessed(pChn, ENV_PANNING)) { const ModInstrument *pIns = pChn->pModInstrument; if(m_playBehaviour[kITEnvelopePositionHandling] && pChn->PanEnv.nEnvPosition == 0) { // If the envelope is disabled at the very same moment as it is triggered, we do not process anything. return; } const int envpos = pChn->PanEnv.nEnvPosition - (m_playBehaviour[kITEnvelopePositionHandling] ? 1 : 0); // Get values in [-32, 32] const int envval = pIns->PanEnv.GetValueFromPosition(envpos, 64) - 32; int pan = pChn->nRealPan; if(pan >= 128) { pan += (envval * (256 - pan)) / 32; } else { pan += (envval * (pan)) / 32; } pChn->nRealPan = Clamp(pan, 0, 256); } } void CSoundFile::ProcessPitchFilterEnvelope(ModChannel *pChn, int &period) const { if(IsEnvelopeProcessed(pChn, ENV_PITCH)) { const ModInstrument *pIns = pChn->pModInstrument; if(m_playBehaviour[kITEnvelopePositionHandling] && pChn->PitchEnv.nEnvPosition == 0) { // If the envelope is disabled at the very same moment as it is triggered, we do not process anything. return; } const int envpos = pChn->PitchEnv.nEnvPosition - (m_playBehaviour[kITEnvelopePositionHandling] ? 1 : 0); // Get values in [-256, 256] #ifdef MODPLUG_TRACKER const int32 range = ENVELOPE_MAX; const int32 amp = 512; #else // TODO: AMS2 envelopes behave differently when linear slides are off - emulate with 15 * (-128...127) >> 6 // Copy over vibrato behaviour for that? const int32 range = GetType() == MOD_TYPE_AMS2 ? uint8_max : ENVELOPE_MAX; int32 amp; switch(GetType()) { case MOD_TYPE_AMS2: amp = 64; break; case MOD_TYPE_MDL: amp = 192; break; default: amp = 512; } #endif const int envval = pIns->PitchEnv.GetValueFromPosition(envpos, amp, range) - amp / 2; if(pChn->PitchEnv.flags[ENV_FILTER]) { // Filter Envelope: controls cutoff frequency SetupChannelFilter(pChn, !pChn->dwFlags[CHN_FILTER], envval); } else { // Pitch Envelope if(GetType() == MOD_TYPE_MPT && pChn->pModInstrument && pChn->pModInstrument->pTuning) { if(pChn->nFineTune != envval) { pChn->nFineTune = envval; pChn->m_CalculateFreq = true; //Preliminary tests indicated that this behavior //is very close to original(with 12TET) when finestep count //is 15. } } else //Original behavior { const bool useFreq = PeriodsAreFrequencies(); const uint32 (&upTable)[256] = useFreq ? LinearSlideUpTable : LinearSlideDownTable; const uint32 (&downTable)[256] = useFreq ? LinearSlideDownTable : LinearSlideUpTable; int l = envval; if(l < 0) { l = -l; LimitMax(l, 255); period = Util::muldiv(period, downTable[l], 65536); } else { LimitMax(l, 255); period = Util::muldiv(period, upTable[l], 65536); } } //End: Original behavior. } } } void CSoundFile::IncrementEnvelopePosition(ModChannel *pChn, EnvelopeType envType) const { ModChannel::EnvInfo &chnEnv = pChn->GetEnvelope(envType); if(pChn->pModInstrument == nullptr || !chnEnv.flags[ENV_ENABLED]) { return; } // Increase position uint32 position = chnEnv.nEnvPosition + (m_playBehaviour[kITEnvelopePositionHandling] ? 0 : 1); const InstrumentEnvelope &insEnv = pChn->pModInstrument->GetEnvelope(envType); if(insEnv.empty()) { return; } bool endReached = false; if(!m_playBehaviour[kITEnvelopePositionHandling]) { // FT2-style envelope processing. if(insEnv.dwFlags[ENV_LOOP]) { // Normal loop active uint32 end = insEnv[insEnv.nLoopEnd].tick; if(!(GetType() & (MOD_TYPE_XM | MOD_TYPE_MT2))) end++; // FT2 compatibility: If the sustain point is at the loop end and the sustain loop has been released, don't loop anymore. // Test case: EnvLoops.xm const bool escapeLoop = (insEnv.nLoopEnd == insEnv.nSustainEnd && insEnv.dwFlags[ENV_SUSTAIN] && pChn->dwFlags[CHN_KEYOFF] && m_playBehaviour[kFT2EnvelopeEscape]); if(position == end && !escapeLoop) { position = insEnv[insEnv.nLoopStart].tick; } } if(insEnv.dwFlags[ENV_SUSTAIN] && !pChn->dwFlags[CHN_KEYOFF]) { // Envelope sustained if(position == insEnv[insEnv.nSustainEnd].tick + 1u) { position = insEnv[insEnv.nSustainStart].tick; } } else { // Limit to last envelope point if(position > insEnv.back().tick) { // Env of envelope position = insEnv.back().tick; endReached = true; } } } else { // IT envelope processing. // Test case: EnvLoops.it uint32 start, end; // IT compatiblity: OpenMPT processes the key-off flag earlier than IT. Grab the flag from the previous tick instead. // Test case: EnvOffLength.it if(insEnv.dwFlags[ENV_SUSTAIN] && !pChn->dwOldFlags[CHN_KEYOFF]) { // Envelope sustained start = insEnv[insEnv.nSustainStart].tick; end = insEnv[insEnv.nSustainEnd].tick + 1; } else if(insEnv.dwFlags[ENV_LOOP]) { // Normal loop active start = insEnv[insEnv.nLoopStart].tick; end = insEnv[insEnv.nLoopEnd].tick + 1; } else { // Limit to last envelope point start = end = insEnv.back().tick; if(position > end) { // Env of envelope endReached = true; } } if(position >= end) { position = start; } } if(envType == ENV_VOLUME && endReached) { // Special handling for volume envelopes at end of envelope if((GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) || (pChn->dwFlags[CHN_KEYOFF] && GetType() != MOD_TYPE_MDL)) { pChn->dwFlags.set(CHN_NOTEFADE); } if(insEnv.back().value == 0 && (pChn->nMasterChn > 0 || (GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)))) { // Stop channel if the last envelope node is silent anyway. pChn->dwFlags.set(CHN_NOTEFADE); pChn->nFadeOutVol = 0; pChn->nRealVolume = 0; pChn->nCalcVolume = 0; } } chnEnv.nEnvPosition = position + (m_playBehaviour[kITEnvelopePositionHandling] ? 1 : 0); } void CSoundFile::IncrementEnvelopePositions(ModChannel *pChn) const { IncrementEnvelopePosition(pChn, ENV_VOLUME); IncrementEnvelopePosition(pChn, ENV_PANNING); IncrementEnvelopePosition(pChn, ENV_PITCH); } void CSoundFile::ProcessInstrumentFade(ModChannel *pChn, int &vol) const { // FadeOut volume if(pChn->dwFlags[CHN_NOTEFADE] && pChn->pModInstrument != nullptr) { const ModInstrument *pIns = pChn->pModInstrument; uint32 fadeout = pIns->nFadeOut; if (fadeout) { pChn->nFadeOutVol -= fadeout * 2; if (pChn->nFadeOutVol <= 0) pChn->nFadeOutVol = 0; vol = (vol * pChn->nFadeOutVol) / 65536; } else if (!pChn->nFadeOutVol) { vol = 0; } } } void CSoundFile::ProcessPitchPanSeparation(ModChannel *pChn) const { const ModInstrument *pIns = pChn->pModInstrument; if ((pIns->nPPS) && (pChn->nNote != NOTE_NONE)) { // with PPS = 16 / PPC = C-5, E-6 will pan hard right (and D#6 will not) int pandelta = (int)pChn->nRealPan + (int)((int)(pChn->nNote - pIns->nPPC - NOTE_MIN) * (int)pIns->nPPS) / 2; pChn->nRealPan = Clamp(pandelta, 0, 256); } } void CSoundFile::ProcessPanbrello(ModChannel *pChn) const { int pdelta = pChn->nPanbrelloOffset; if(pChn->rowCommand.command == CMD_PANBRELLO) { uint32 panpos; // IT compatibility: IT has its own, more precise tables if(m_playBehaviour[kITVibratoTremoloPanbrello]) panpos = pChn->nPanbrelloPos; else panpos = ((pChn->nPanbrelloPos + 0x10) >> 2); pdelta = GetVibratoDelta(pChn->nPanbrelloType, panpos); // IT compatibility: Sample-and-hold style random panbrello (tremolo and vibrato don't use this mechanism in IT) // Test case: RandomWaveform.it if(m_playBehaviour[kITSampleAndHoldPanbrello] && pChn->nPanbrelloType == 3) { if(pChn->nPanbrelloPos == 0 || pChn->nPanbrelloPos >= pChn->nPanbrelloSpeed) { pChn->nPanbrelloPos = 0; pChn->nPanbrelloRandomMemory = static_cast(pdelta); } pChn->nPanbrelloPos++; pdelta = pChn->nPanbrelloRandomMemory; } else { pChn->nPanbrelloPos += pChn->nPanbrelloSpeed; } // IT compatibility: Panbrello effect is active until next note or panning command. // Test case: PanbrelloHold.it if(m_playBehaviour[kITPanbrelloHold]) { pChn->nPanbrelloOffset = static_cast(pdelta); } } if(pdelta) { pdelta = ((pdelta * (int)pChn->nPanbrelloDepth) + 2) / 8; pdelta += pChn->nRealPan; pChn->nRealPan = Clamp(pdelta, 0, 256); } } void CSoundFile::ProcessArpeggio(CHANNELINDEX nChn, int &period, Tuning::NOTEINDEXTYPE &arpeggioSteps) { ModChannel *pChn = &m_PlayState.Chn[nChn]; #ifndef NO_PLUGINS // Plugin arpeggio if(pChn->pModInstrument && pChn->pModInstrument->nMixPlug && !pChn->pModInstrument->dwFlags[INS_MUTE] && !pChn->dwFlags[CHN_MUTE | CHN_SYNCMUTE]) { const ModInstrument *pIns = pChn->pModInstrument; IMixPlugin *pPlugin = m_MixPlugins[pIns->nMixPlug - 1].pMixPlugin; if(pPlugin) { uint8 step = 0; const bool arpOnRow = (pChn->rowCommand.command == CMD_ARPEGGIO); const ModCommand::NOTE lastNote = ModCommand::IsNote(pChn->nLastNote) ? pIns->NoteMap[pChn->nLastNote - NOTE_MIN] : NOTE_NONE; if(arpOnRow) { switch(m_PlayState.m_nTickCount % 3) { case 1: step = pChn->nArpeggio >> 4; break; case 2: step = pChn->nArpeggio & 0x0F; break; } pChn->nArpeggioBaseNote = lastNote; } // Trigger new note: // - If there's an arpeggio on this row and // - the note to trigger is not the same as the previous arpeggio note or // - a pattern note has just been triggered on this tick // - If there's no arpeggio // - but an arpeggio note is still active and // - there's no note stop or new note that would stop it anyway if((arpOnRow && pChn->nArpeggioLastNote != pChn->nArpeggioBaseNote + step && (!m_SongFlags[SONG_FIRSTTICK] || !pChn->rowCommand.IsNote())) || (!arpOnRow && pChn->rowCommand.note == NOTE_NONE && pChn->nArpeggioLastNote != NOTE_NONE)) SendMIDINote(nChn, pChn->nArpeggioBaseNote + step, static_cast(pChn->nVolume)); // Stop note: // - If some arpeggio note is still registered or // - When starting an arpeggio on a row with no other note on it, stop some possibly still playing note. if(pChn->nArpeggioLastNote != NOTE_NONE) SendMIDINote(nChn, pChn->nArpeggioLastNote + NOTE_MAX_SPECIAL, 0); else if(arpOnRow && m_SongFlags[SONG_FIRSTTICK] && !pChn->rowCommand.IsNote() && ModCommand::IsNote(lastNote)) SendMIDINote(nChn, lastNote + NOTE_MAX_SPECIAL, 0); if(pChn->rowCommand.command == CMD_ARPEGGIO) pChn->nArpeggioLastNote = pChn->nArpeggioBaseNote + step; else pChn->nArpeggioLastNote = NOTE_NONE; } } #endif // NO_PLUGINS if(pChn->nCommand == CMD_ARPEGGIO) { if((GetType() & MOD_TYPE_MPT) && pChn->pModInstrument && pChn->pModInstrument->pTuning) { switch(m_PlayState.m_nTickCount % 3) { case 0: arpeggioSteps = 0; break; case 1: arpeggioSteps = pChn->nArpeggio >> 4; break; case 2: arpeggioSteps = pChn->nArpeggio & 0x0F; break; } pChn->m_CalculateFreq = true; pChn->m_ReCalculateFreqOnFirstTick = true; } else { if(GetType() == MOD_TYPE_MT2 && m_SongFlags[SONG_FIRSTTICK]) { // MT2 resets any previous portamento when an arpeggio occurs. pChn->nPeriod = period = GetPeriodFromNote(pChn->nNote, pChn->nFineTune, pChn->nC5Speed); } if(m_playBehaviour[kITArpeggio]) { //IT playback compatibility 01 & 02 // Pattern delay restarts tick counting. Not quite correct yet! const uint32 tick = m_PlayState.m_nTickCount % (m_PlayState.m_nMusicSpeed + m_PlayState.m_nFrameDelay); if(pChn->nArpeggio != 0) { uint32 arpRatio = 65536; switch(tick % 3) { case 1: arpRatio = LinearSlideUpTable[(pChn->nArpeggio >> 4) * 16]; break; case 2: arpRatio = LinearSlideUpTable[(pChn->nArpeggio & 0x0F) * 16]; break; } if(PeriodsAreFrequencies()) period = Util::muldivr(period, arpRatio, 65536); else period = Util::muldivr(period, 65536, arpRatio); } } else if(m_playBehaviour[kFT2Arpeggio]) { // FastTracker 2: Swedish tracker logic (TM) arpeggio if(!m_SongFlags[SONG_FIRSTTICK]) { // Arpeggio is added on top of current note, but cannot do it the IT way because of // the behaviour in ArpeggioClamp.xm. // Test case: ArpSlide.xm auto note = GetNoteFromPeriod(period, pChn->nFineTune, pChn->nC5Speed); // The fact that arpeggio behaves in a totally fucked up way at 16 ticks/row or more is that the arpeggio offset LUT only has 16 entries in FT2. // At more than 16 ticks/row, FT2 reads into the vibrato table, which is placed right after the arpeggio table. // Test case: Arpeggio.xm int arpPos = m_PlayState.m_nMusicSpeed - (m_PlayState.m_nTickCount % m_PlayState.m_nMusicSpeed); if(arpPos > 16) arpPos = 2; else if(arpPos == 16) arpPos = 0; else arpPos %= 3; switch(arpPos) { case 1: note += (pChn->nArpeggio >> 4); break; case 2: note += (pChn->nArpeggio & 0x0F); break; } period = GetPeriodFromNote(note, pChn->nFineTune, pChn->nC5Speed); // FT2 compatibility: FT2 has a different note limit for Arpeggio. // Test case: ArpeggioClamp.xm if(note >= 108 + NOTE_MIN && arpPos != 0) { period = std::max(period, GetPeriodFromNote(108 + NOTE_MIN, 0, pChn->nC5Speed)); } } } // Other trackers else { uint32 tick = m_PlayState.m_nTickCount; // TODO other likely formats for MOD case: MED, OKT, etc uint8 note = (GetType() != MOD_TYPE_MOD) ? pChn->nNote : static_cast(GetNoteFromPeriod(period, pChn->nFineTune, pChn->nC5Speed)); switch(tick % 3) { case 1: note += (pChn->nArpeggio >> 4); break; case 2: note += (pChn->nArpeggio & 0x0F); break; } if(note != pChn->nNote || GetType() == MOD_TYPE_STM || m_playBehaviour[KST3PortaAfterArpeggio]) { if(m_SongFlags[SONG_PT_MODE]) { // Weird arpeggio wrap-around in ProTracker. // Test case: ArpWraparound.mod, and the snare sound in "Jim is dead" by doh. if(note == NOTE_MIDDLEC + 24) { period = int32_max; return; } else if(note > NOTE_MIDDLEC + 24) { note -= 37; } } period = GetPeriodFromNote(note, pChn->nFineTune, pChn->nC5Speed); if(GetType() & (MOD_TYPE_STM | MOD_TYPE_PSM)) { // The arpeggio note offset remains effective after the end of the current row in ScreamTracker 2. // This fixes the flute lead in MORPH.STM by Skaven, pattern 27. pChn->nPeriod = period; } else if(m_playBehaviour[KST3PortaAfterArpeggio]) { pChn->nArpeggioLastNote = note; } } } } } } void CSoundFile::ProcessVibrato(CHANNELINDEX nChn, int &period, Tuning::RATIOTYPE &vibratoFactor) { ModChannel &chn = m_PlayState.Chn[nChn]; if(chn.dwFlags[CHN_VIBRATO]) { if(GetType() == MOD_TYPE_669) { if(chn.nVibratoPos % 2u) { period += chn.nVibratoDepth * 167; // Already multiplied by 4, and it seems like the real factor here is 669... how original =) } chn.nVibratoPos++; return; } // IT compatibility: IT has its own, more precise tables and pre-increments the vibrato position if(m_playBehaviour[kITVibratoTremoloPanbrello]) chn.nVibratoPos += 4 * chn.nVibratoSpeed; int vdelta = GetVibratoDelta(chn.nVibratoType, chn.nVibratoPos); if(GetType() == MOD_TYPE_MPT && chn.pModInstrument && chn.pModInstrument->pTuning) { //Hack implementation: Scaling vibratofactor to [0.95; 1.05] //using figure from above tables and vibratodepth parameter vibratoFactor += 0.05f * (vdelta * chn.nVibratoDepth) / (128.0f * 60.0f); chn.m_CalculateFreq = true; chn.m_ReCalculateFreqOnFirstTick = false; if(m_PlayState.m_nTickCount + 1 == m_PlayState.m_nMusicSpeed) chn.m_ReCalculateFreqOnFirstTick = true; } else { // Original behaviour if(m_SongFlags.test_all(SONG_FIRSTTICK | SONG_PT_MODE) || ((GetType() & (MOD_TYPE_DIGI | MOD_TYPE_DBM)) && m_SongFlags[SONG_FIRSTTICK])) { // ProTracker doesn't apply vibrato nor advance on the first tick. // Test case: VibratoReset.mod return; } else if((GetType() & MOD_TYPE_XM) && (chn.nVibratoType & 0x03) == 1) { // FT2 compatibility: Vibrato ramp down table is upside down. // Test case: VibratoWaveforms.xm vdelta = -vdelta; } uint32 vdepth; // IT compatibility: correct vibrato depth if(m_playBehaviour[kITVibratoTremoloPanbrello]) { // Yes, vibrato goes backwards with old effects enabled! if(m_SongFlags[SONG_ITOLDEFFECTS]) { // Test case: vibrato-oldfx.it vdepth = 5; } else { // Test case: vibrato.it vdepth = 6; vdelta = -vdelta; } } else { if(m_SongFlags[SONG_S3MOLDVIBRATO]) vdepth = 5; else if(GetType() == MOD_TYPE_DTM) vdepth = 8; else if(GetType() & (MOD_TYPE_DBM | MOD_TYPE_MTM)) vdepth = 7; else if((GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) && !m_SongFlags[SONG_ITOLDEFFECTS]) vdepth = 7; else vdepth = 6; // ST3 compatibility: Do not distinguish between vibrato types in effect memory // Test case: VibratoTypeChange.s3m if(m_playBehaviour[kST3VibratoMemory] && chn.rowCommand.command == CMD_FINEVIBRATO) vdepth += 2; } vdelta = (vdelta * (int)chn.nVibratoDepth) / (1 << vdepth); #ifndef NO_PLUGINS int16 midiDelta = static_cast(-vdelta); // Periods are upside down #endif // NO_PLUGINS if (m_SongFlags[SONG_LINEARSLIDES] && GetType() != MOD_TYPE_XM) { int l = vdelta; if (l < 0) { l = -l; vdelta = Util::muldiv(period, GetLinearSlideUpTable(this, l / 4u), 65536) - period; if (l & 0x03) vdelta += Util::muldiv(period, GetFineLinearSlideUpTable(this, l & 0x03), 65536) - period; } else { vdelta = Util::muldiv(period, GetLinearSlideDownTable(this, l / 4u), 65536) - period; if (l & 0x03) vdelta += Util::muldiv(period, GetFineLinearSlideDownTable(this, l & 0x03), 65536) - period; } } period += vdelta; // Process MIDI vibrato for plugins: #ifndef NO_PLUGINS IMixPlugin *plugin = GetChannelInstrumentPlugin(nChn); if(plugin != nullptr) { // If the Pitch Wheel Depth is configured correctly (so it's the same as the plugin's PWD), // MIDI vibrato will sound identical to vibrato with linear slides enabled. int8 pwd = 2; if(chn.pModInstrument != nullptr) { pwd = chn.pModInstrument->midiPWD; } plugin->MidiVibrato(GetBestMidiChannel(nChn), midiDelta, pwd); } #endif // NO_PLUGINS } // Advance vibrato position - IT updates on every tick, unless "old effects" are enabled (in this case it only updates on non-first ticks like other trackers) if(!m_SongFlags[SONG_FIRSTTICK] || ((GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) && !(m_SongFlags[SONG_ITOLDEFFECTS]))) { // IT compatibility: IT has its own, more precise tables and pre-increments the vibrato position if(!m_playBehaviour[kITVibratoTremoloPanbrello]) chn.nVibratoPos += chn.nVibratoSpeed; } } else if(chn.dwOldFlags[CHN_VIBRATO]) { // Stop MIDI vibrato for plugins: #ifndef NO_PLUGINS IMixPlugin *plugin = GetChannelInstrumentPlugin(nChn); if(plugin != nullptr) { plugin->MidiVibrato(GetBestMidiChannel(nChn), 0, 0); } #endif // NO_PLUGINS } } void CSoundFile::ProcessSampleAutoVibrato(ModChannel *pChn, int &period, Tuning::RATIOTYPE &vibratoFactor, int &nPeriodFrac) const { // Sample Auto-Vibrato if ((pChn->pModSample) && (pChn->pModSample->nVibDepth)) { const ModSample *pSmp = pChn->pModSample; const bool alternativeTuning = pChn->pModInstrument && pChn->pModInstrument->pTuning; // In IT linear slide mode, we use frequencies, otherwise we use periods, which are upside down. // In this context, the "up" tables refer to the tables that increase frequency, and the down tables are the ones that decrease frequency. const bool useFreq = PeriodsAreFrequencies(); const uint32 (&upTable)[256] = useFreq ? LinearSlideUpTable : LinearSlideDownTable; const uint32 (&downTable)[256] = useFreq ? LinearSlideDownTable : LinearSlideUpTable; const uint32 (&fineUpTable)[16] = useFreq ? FineLinearSlideUpTable : FineLinearSlideDownTable; const uint32 (&fineDownTable)[16] = useFreq ? FineLinearSlideDownTable : FineLinearSlideUpTable; // IT compatibility: Autovibrato is so much different in IT that I just put this in a separate code block, to get rid of a dozen IsCompatibilityMode() calls. if(m_playBehaviour[kITVibratoTremoloPanbrello] && !alternativeTuning && GetType() != MOD_TYPE_MT2) { if(!pSmp->nVibRate) return; // Schism's autovibrato code /* X86 Assembler from ITTECH.TXT: 1) Mov AX, [SomeVariableNameRelatingToVibrato] 2) Add AL, Rate 3) AdC AH, 0 4) AH contains the depth of the vibrato as a fine-linear slide. 5) Mov [SomeVariableNameRelatingToVibrato], AX ; For the next cycle. */ const int vibpos = pChn->nAutoVibPos & 0xFF; int adepth = pChn->nAutoVibDepth; // (1) adepth += pSmp->nVibSweep; // (2 & 3) LimitMax(adepth, static_cast(pSmp->nVibDepth * 256u)); pChn->nAutoVibDepth = adepth; // (5) adepth /= 256; // (4) pChn->nAutoVibPos += pSmp->nVibRate; int vdelta; switch(pSmp->nVibType) { case VIB_RANDOM: vdelta = mpt::random(AccessPRNG()) - 0x40; break; case VIB_RAMP_DOWN: vdelta = 64 - (vibpos + 1) / 2; break; case VIB_RAMP_UP: vdelta = ((vibpos + 1) / 2) - 64; break; case VIB_SQUARE: vdelta = vibpos < 128 ? 64 : 0; break; case VIB_SINE: default: vdelta = ITSinusTable[vibpos]; break; } vdelta = (vdelta * adepth) / 64; uint32 l = mpt::abs(vdelta); LimitMax(period, Util::MaxValueOfType(period) / 256); period *= 256; if(vdelta < 0) { vdelta = Util::muldiv(period, downTable[l / 4u], 0x10000) - period; if (l & 0x03) { vdelta += Util::muldiv(period, fineDownTable[l & 0x03], 0x10000) - period; } } else { vdelta = Util::muldiv(period, upTable[l / 4u], 0x10000) - period; if (l & 0x03) { vdelta += Util::muldiv(period, fineUpTable[l & 0x03], 0x10000) - period; } } period = (period + vdelta) / 256; nPeriodFrac = vdelta & 0xFF; } else { // MPT's autovibrato code if (pSmp->nVibSweep == 0 && !(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT))) { pChn->nAutoVibDepth = pSmp->nVibDepth * 256; } else { // Calculate current autovibrato depth using vibsweep if (GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) { pChn->nAutoVibDepth += pSmp->nVibSweep * 2u; } else { if(!pChn->dwFlags[CHN_KEYOFF]) { pChn->nAutoVibDepth += (pSmp->nVibDepth * 256u) / pSmp->nVibSweep; } } LimitMax(pChn->nAutoVibDepth, static_cast(pSmp->nVibDepth * 256u)); } pChn->nAutoVibPos += pSmp->nVibRate; int vdelta; switch(pSmp->nVibType) { case VIB_RANDOM: vdelta = ModRandomTable[pChn->nAutoVibPos & 0x3F]; pChn->nAutoVibPos++; break; case VIB_RAMP_DOWN: vdelta = ((0x40 - (pChn->nAutoVibPos / 2u)) & 0x7F) - 0x40; break; case VIB_RAMP_UP: vdelta = ((0x40 + (pChn->nAutoVibPos / 2u)) & 0x7F) - 0x40; break; case VIB_SQUARE: vdelta = (pChn->nAutoVibPos & 128) ? +64 : -64; break; case VIB_SINE: default: if(GetType() != MOD_TYPE_MT2) { vdelta = ft2VibratoTable[pChn->nAutoVibPos & 0xFF]; } else { // Fix flat-sounding pads in "another worlds" by Eternal Engine. // Vibrato starts at the maximum amplitude of the sine wave // and the vibrato frequency never decreases below the original note's frequency. vdelta = (ft2VibratoTable[(pChn->nAutoVibPos + 192) & 0xFF] + 64) / 2; } } int n = (vdelta * pChn->nAutoVibDepth) / 256; if(alternativeTuning) { //Vib sweep is not taken into account here. vibratoFactor += 0.05F * pSmp->nVibDepth * vdelta / 4096.0f; //4096 == 64^2 //See vibrato for explanation. pChn->m_CalculateFreq = true; /* Finestep vibrato: const float autoVibDepth = pSmp->nVibDepth * val / 4096.0f; //4096 == 64^2 vibratoFineSteps += static_cast(pChn->pModInstrument->pTuning->GetFineStepCount() * autoVibDepth); pChn->m_CalculateFreq = true; */ } else //Original behavior { if (GetType() != MOD_TYPE_XM) { int df1, df2; if (n < 0) { n = -n; uint32 n1 = n / 256; df1 = downTable[n1]; df2 = downTable[n1+1]; } else { uint32 n1 = n / 256; df1 = upTable[n1]; df2 = upTable[n1+1]; } n /= 4; period = Util::muldiv(period, df1 + ((df2 - df1) * (n & 0x3F) / 64), 256); nPeriodFrac = period & 0xFF; period /= 256; } else { period += (n / 64); } } //Original MPT behavior } } } void CSoundFile::ProcessRamping(ModChannel *pChn) const { pChn->leftRamp = pChn->rightRamp = 0; if(pChn->dwFlags[CHN_VOLUMERAMP] && (pChn->leftVol != pChn->newLeftVol || pChn->rightVol != pChn->newRightVol)) { const bool rampUp = (pChn->newLeftVol > pChn->leftVol) || (pChn->newRightVol > pChn->rightVol); int32 rampLength, globalRampLength, instrRampLength = 0; rampLength = globalRampLength = (rampUp ? m_MixerSettings.GetVolumeRampUpSamples() : m_MixerSettings.GetVolumeRampDownSamples()); //XXXih: add real support for bidi ramping here if(m_playBehaviour[kFT2VolumeRamping] && (GetType() & MOD_TYPE_XM)) { // apply FT2-style super-soft volume ramping (5ms), overriding openmpt settings rampLength = globalRampLength = Util::muldivr(5, m_MixerSettings.gdwMixingFreq, 1000); } if(pChn->pModInstrument != nullptr && rampUp) { instrRampLength = pChn->pModInstrument->nVolRampUp; rampLength = instrRampLength ? (m_MixerSettings.gdwMixingFreq * instrRampLength / 100000) : globalRampLength; } const bool enableCustomRamp = (instrRampLength > 0); if(!rampLength) { rampLength = 1; } int32 leftDelta = ((pChn->newLeftVol - pChn->leftVol) * (1 << VOLUMERAMPPRECISION)); int32 rightDelta = ((pChn->newRightVol - pChn->rightVol) * (1 << VOLUMERAMPPRECISION)); if(!enableCustomRamp) { // Extra-smooth ramping, unless we're forced to use the default values if((pChn->leftVol | pChn->rightVol) && (pChn->newLeftVol | pChn->newRightVol) && !pChn->dwFlags[CHN_FASTVOLRAMP]) { rampLength = m_PlayState.m_nBufferCount; Limit(rampLength, globalRampLength, 1 << (VOLUMERAMPPRECISION - 1)); } } pChn->leftRamp = leftDelta / rampLength; pChn->rightRamp = rightDelta / rampLength; pChn->leftVol = pChn->newLeftVol - ((pChn->leftRamp * rampLength) / (1 << VOLUMERAMPPRECISION)); pChn->rightVol = pChn->newRightVol - ((pChn->rightRamp * rampLength) / (1 << VOLUMERAMPPRECISION)); if (pChn->leftRamp|pChn->rightRamp) { pChn->nRampLength = rampLength; } else { pChn->dwFlags.reset(CHN_VOLUMERAMP); pChn->leftVol = pChn->newLeftVol; pChn->rightVol = pChn->newRightVol; } } else { pChn->dwFlags.reset(CHN_VOLUMERAMP); pChn->leftVol = pChn->newLeftVol; pChn->rightVol = pChn->newRightVol; } pChn->rampLeftVol = pChn->leftVol * (1 << VOLUMERAMPPRECISION); pChn->rampRightVol = pChn->rightVol * (1 << VOLUMERAMPPRECISION); pChn->dwFlags.reset(CHN_FASTVOLRAMP); } SamplePosition CSoundFile::GetChannelIncrement(ModChannel *pChn, uint32 period, int periodFrac) const { uint32 freq; const ModInstrument *pIns = pChn->pModInstrument; if(GetType() != MOD_TYPE_MPT || pIns == nullptr || pIns->pTuning == nullptr) { freq = GetFreqFromPeriod(period, pChn->nC5Speed, periodFrac); } else { freq = pChn->m_Freq; } // Applying Pitch/Tempo lock. if(pIns && pIns->pitchToTempoLock.GetRaw()) { freq = Util::muldivr(freq, m_PlayState.m_nMusicTempo.GetRaw(), pIns->pitchToTempoLock.GetRaw()); } // Avoid increment to overflow and become negative with unrealisticly high frequencies. LimitMax(freq, uint32(int32_max)); return SamplePosition::Ratio(freq, m_MixerSettings.gdwMixingFreq << FREQ_FRACBITS); } //////////////////////////////////////////////////////////////////////////////////////////// // Handles envelopes & mixer setup bool CSoundFile::ReadNote() { #ifdef MODPLUG_TRACKER // Checking end of row ? if(m_SongFlags[SONG_PAUSED]) { m_PlayState.m_nTickCount = 0; if (!m_PlayState.m_nMusicSpeed) m_PlayState.m_nMusicSpeed = 6; if (!m_PlayState.m_nMusicTempo.GetRaw()) m_PlayState.m_nMusicTempo.Set(125); } else #endif // MODPLUG_TRACKER { if(!ProcessRow()) return false; } //////////////////////////////////////////////////////////////////////////////////// if (m_PlayState.m_nMusicTempo.GetRaw() == 0) return false; m_PlayState.m_nSamplesPerTick = GetTickDuration(m_PlayState); m_PlayState.m_nBufferCount = m_PlayState.m_nSamplesPerTick; // Master Volume + Pre-Amplification / Attenuation setup uint32 nMasterVol; { CHANNELINDEX nchn32 = Clamp(m_nChannels, CHANNELINDEX(1), CHANNELINDEX(31)); uint32 mastervol; if (m_PlayConfig.getUseGlobalPreAmp()) { int realmastervol = m_MixerSettings.m_nPreAmp; if (realmastervol > 0x80) { //Attenuate global pre-amp depending on num channels realmastervol = 0x80 + ((realmastervol - 0x80) * (nchn32 + 4)) / 16; } mastervol = (realmastervol * (m_nSamplePreAmp)) / 64; } else { //Preferred option: don't use global pre-amp at all. mastervol = m_nSamplePreAmp; } if (m_PlayConfig.getUseGlobalPreAmp()) { uint32 attenuation = #ifndef NO_AGC (m_MixerSettings.DSPMask & SNDDSP_AGC) ? PreAmpAGCTable[nchn32 / 2u] : #endif PreAmpTable[nchn32 / 2u]; if(attenuation < 1) attenuation = 1; nMasterVol = (mastervol << 7) / attenuation; } else { nMasterVol = mastervol; } } //////////////////////////////////////////////////////////////////////////////////// // Update channels data m_nMixChannels = 0; ModChannel *pChn = m_PlayState.Chn; for (CHANNELINDEX nChn = 0; nChn < MAX_CHANNELS; nChn++, pChn++) { // FT2 Compatibility: Prevent notes to be stopped after a fadeout. This way, a portamento effect can pick up a faded instrument which is long enough. // This occurs for example in the bassline (channel 11) of jt_burn.xm. I hope this won't break anything else... // I also suppose this could decrease mixing performance a bit, but hey, which CPU can't handle 32 muted channels these days... :-) if(pChn->dwFlags[CHN_NOTEFADE] && (!(pChn->nFadeOutVol|pChn->leftVol|pChn->rightVol)) && !m_playBehaviour[kFT2ProcessSilentChannels]) { pChn->nLength = 0; pChn->nROfs = pChn->nLOfs = 0; } // Check for unused channel if(pChn->dwFlags[CHN_MUTE] || (nChn >= m_nChannels && !pChn->nLength)) { if(nChn < m_nChannels) { // Process MIDI macros on channels that are currently muted. ProcessMacroOnChannel(nChn); } pChn->nLeftVU = pChn->nRightVU = 0; continue; } // Reset channel data pChn->increment = SamplePosition(0); pChn->nRealVolume = 0; pChn->nCalcVolume = 0; pChn->nRampLength = 0; //Aux variables Tuning::RATIOTYPE vibratoFactor = 1; Tuning::NOTEINDEXTYPE arpeggioSteps = 0; const ModInstrument *pIns = pChn->pModInstrument; // Calc Frequency int period; // Also process envelopes etc. when there's a plugin on this channel, for possible fake automation using volume and pan data. // We only care about master channels, though, since automation only "happens" on them. const bool samplePlaying = (pChn->nPeriod && pChn->nLength); const bool plugAssigned = (nChn < m_nChannels) && (ChnSettings[nChn].nMixPlugin || (pChn->pModInstrument != nullptr && pChn->pModInstrument->nMixPlug)); if (samplePlaying || plugAssigned) { int vol = pChn->nVolume; int insVol = pChn->nInsVol; // This is the "SV * IV" value in ITTECH.TXT ProcessVolumeSwing(pChn, m_playBehaviour[kITSwingBehaviour] ? insVol : vol); ProcessPanningSwing(pChn); ProcessTremolo(pChn, vol); ProcessTremor(nChn, vol); // Clip volume and multiply (extend to 14 bits) Limit(vol, 0, 256); vol <<= 6; // Process Envelopes if (pIns) { if(m_playBehaviour[kITEnvelopePositionHandling]) { // In IT compatible mode, envelope position indices are shifted by one for proper envelope pausing, // so we have to update the position before we actually process the envelopes. // When using MPT behaviour, we get the envelope position for the next tick while we are still calculating the current tick, // which then results in wrong position information when the envelope is paused on the next row. // Test cases: s77.it IncrementEnvelopePositions(pChn); } ProcessVolumeEnvelope(pChn, vol); ProcessInstrumentFade(pChn, vol); ProcessPanningEnvelope(pChn); ProcessPitchPanSeparation(pChn); } else { // No Envelope: key off => note cut if(pChn->dwFlags[CHN_NOTEFADE]) // 1.41-: CHN_KEYOFF|CHN_NOTEFADE { pChn->nFadeOutVol = 0; vol = 0; } } // vol is 14-bits if (vol) { // IMPORTANT: pChn->nRealVolume is 14 bits !!! // -> Util::muldiv( 14+8, 6+6, 18); => RealVolume: 14-bit result (22+12-20) if(pChn->dwFlags[CHN_SYNCMUTE]) { pChn->nRealVolume = 0; } else if (m_PlayConfig.getGlobalVolumeAppliesToMaster()) { // Don't let global volume affect level of sample if // Global volume is going to be applied to master output anyway. pChn->nRealVolume = Util::muldiv(vol * MAX_GLOBAL_VOLUME, pChn->nGlobalVol * insVol, 1 << 20); } else { pChn->nRealVolume = Util::muldiv(vol * m_PlayState.m_nGlobalVolume, pChn->nGlobalVol * insVol, 1 << 20); } } pChn->nCalcVolume = vol; // Update calculated volume for MIDI macros // ST3 only clamps the final output period, but never the channel's internal period. // Test case: PeriodLimit.s3m if (pChn->nPeriod < m_nMinPeriod && GetType() != MOD_TYPE_S3M && !PeriodsAreFrequencies()) { pChn->nPeriod = m_nMinPeriod; } if(m_playBehaviour[kFT2Periods]) Clamp(pChn->nPeriod, 1, 31999); period = pChn->nPeriod; // When glissando mode is set to semitones, clamp to the next halftone. if((pChn->dwFlags & (CHN_GLISSANDO | CHN_PORTAMENTO)) == (CHN_GLISSANDO | CHN_PORTAMENTO) && (!m_SongFlags[SONG_PT_MODE] || (pChn->rowCommand.IsPortamento() && !m_SongFlags[SONG_FIRSTTICK]))) { if(period != pChn->cachedPeriod) { // Only recompute this whole thing in case the base period has changed. pChn->cachedPeriod = period; pChn->glissandoPeriod = GetPeriodFromNote(GetNoteFromPeriod(period, pChn->nFineTune, pChn->nC5Speed), pChn->nFineTune, pChn->nC5Speed); } period = pChn->glissandoPeriod; } ProcessArpeggio(nChn, period, arpeggioSteps); // Preserve Amiga freq limits. // In ST3, the frequency is always clamped to periods 113 to 856, while in ProTracker, // the limit is variable, depending on the finetune of the sample. // The int32_max test is for the arpeggio wrap-around in ProcessArpeggio(). // Test case: AmigaLimits.s3m, AmigaLimitsFinetune.mod if(m_SongFlags[SONG_AMIGALIMITS | SONG_PT_MODE] && period != int32_max) { int limitLow = 113 * 4, limitHigh = 856 * 4; if(GetType() != MOD_TYPE_S3M) { const int tableOffset = XM2MODFineTune(pChn->nFineTune) * 12; limitLow = ProTrackerTunedPeriods[tableOffset + 11] / 2; limitHigh = ProTrackerTunedPeriods[tableOffset] * 2; // Amiga cannot actually keep up with lower periods if(limitLow < 113 * 4) limitLow = 113 * 4; } Limit(period, limitLow, limitHigh); Limit(pChn->nPeriod, limitLow, limitHigh); } ProcessPanbrello(pChn); } // IT Compatibility: Ensure that there is no pan swing, panbrello, panning envelopes, etc. applied on surround channels. // Test case: surround-pan.it if(pChn->dwFlags[CHN_SURROUND] && !m_SongFlags[SONG_SURROUNDPAN] && m_playBehaviour[kITNoSurroundPan]) { pChn->nRealPan = 128; } // Now that all relevant envelopes etc. have been processed, we can parse the MIDI macro data. ProcessMacroOnChannel(nChn); // After MIDI macros have been processed, we can also process the pitch / filter envelope and other pitch-related things. if(samplePlaying) { ProcessPitchFilterEnvelope(pChn, period); } if(pChn->rowCommand.volcmd == VOLCMD_VIBRATODEPTH && (pChn->rowCommand.command == CMD_VIBRATO || pChn->rowCommand.command == CMD_VIBRATOVOL || pChn->rowCommand.command == CMD_FINEVIBRATO)) { if(GetType() == MOD_TYPE_XM) { // XM Compatibility: Vibrato should be advanced twice (but not added up) if both volume-column and effect column vibrato is present. // Effect column vibrato parameter has precedence if non-zero. // Test case: VibratoDouble.xm if(!m_SongFlags[SONG_FIRSTTICK]) pChn->nVibratoPos += pChn->nVibratoSpeed; } else if(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) { // IT Compatibility: Vibrato should be applied twice if both volume-colum and effect column vibrato is present. // Volume column vibrato parameter has precedence if non-zero. // Test case: VibratoDouble.it Vibrato(pChn, pChn->rowCommand.vol); ProcessVibrato(nChn, period, vibratoFactor); } } // Plugins may also receive vibrato ProcessVibrato(nChn, period, vibratoFactor); if(samplePlaying) { int nPeriodFrac = 0; ProcessSampleAutoVibrato(pChn, period, vibratoFactor, nPeriodFrac); // Final Period // ST3 only clamps the final output period, but never the channel's internal period. // Test case: PeriodLimit.s3m if (period <= m_nMinPeriod) { if(m_playBehaviour[kST3LimitPeriod]) pChn->nLength = 0; // Pattern 15 in watcha.s3m period = m_nMinPeriod; } if(GetType() == MOD_TYPE_MPT && pIns != nullptr && pIns->pTuning != nullptr) { // In this case: GetType() == MOD_TYPE_MPT and using custom tunings. if(pChn->m_CalculateFreq || (pChn->m_ReCalculateFreqOnFirstTick && m_PlayState.m_nTickCount == 0)) { ModCommand::NOTE note = pChn->nNote; if(!ModCommand::IsNote(note)) note = pChn->nLastNote; if(m_playBehaviour[kITRealNoteMapping] && note >= NOTE_MIN && note <= NOTE_MAX) note = pIns->NoteMap[note - NOTE_MIN]; pChn->m_Freq = Util::Round((pChn->nC5Speed << FREQ_FRACBITS) * vibratoFactor * pIns->pTuning->GetRatio(note - NOTE_MIDDLEC + arpeggioSteps, pChn->nFineTune+pChn->m_PortamentoFineSteps)); if(!pChn->m_CalculateFreq) pChn->m_ReCalculateFreqOnFirstTick = false; else pChn->m_CalculateFreq = false; } } SamplePosition ninc = GetChannelIncrement(pChn, period, nPeriodFrac); #ifndef MODPLUG_TRACKER ninc.MulDiv(m_nFreqFactor, 65536); #endif // !MODPLUG_TRACKER if(ninc.IsZero()) { ninc.Set(0, 1); } pChn->increment = ninc; } // Increment envelope positions if(pIns != nullptr && !m_playBehaviour[kITEnvelopePositionHandling]) { // In IT and FT2 compatible mode, envelope positions are updated above. // Test cases: s77.it, EnvLoops.xm IncrementEnvelopePositions(pChn); } // Volume ramping pChn->dwFlags.set(CHN_VOLUMERAMP, (pChn->nRealVolume | pChn->rightVol | pChn->leftVol) != 0); if (pChn->nLeftVU > VUMETER_DECAY) pChn->nLeftVU -= VUMETER_DECAY; else pChn->nLeftVU = 0; if (pChn->nRightVU > VUMETER_DECAY) pChn->nRightVU -= VUMETER_DECAY; else pChn->nRightVU = 0; pChn->newLeftVol = pChn->newRightVol = 0; pChn->pCurrentSample = (pChn->pModSample && pChn->pModSample->pSample && pChn->nLength && pChn->IsSamplePlaying()) ? pChn->pModSample->pSample : nullptr; if (pChn->pCurrentSample || (pChn->HasMIDIOutput() && !pChn->dwFlags[CHN_KEYOFF | CHN_NOTEFADE])) { // Update VU-Meter (nRealVolume is 14-bit) uint32 vul = (pChn->nRealVolume * pChn->nRealPan) / (1 << 14); if (vul > 127) vul = 127; if (pChn->nLeftVU > 127) pChn->nLeftVU = (uint8)vul; vul /= 2; if (pChn->nLeftVU < vul) pChn->nLeftVU = (uint8)vul; uint32 vur = (pChn->nRealVolume * (256-pChn->nRealPan)) / (1 << 14); if (vur > 127) vur = 127; if (pChn->nRightVU > 127) pChn->nRightVU = (uint8)vur; vur /= 2; if (pChn->nRightVU < vur) pChn->nRightVU = (uint8)vur; } else { // Note change but no sample if (pChn->nLeftVU > 128) pChn->nLeftVU = 0; if (pChn->nRightVU > 128) pChn->nRightVU = 0; } if (pChn->pCurrentSample) { #ifdef MODPLUG_TRACKER const uint32 kChnMasterVol = pChn->dwFlags[CHN_EXTRALOUD] ? (uint32)m_PlayConfig.getNormalSamplePreAmp() : nMasterVol; #else const uint32 kChnMasterVol = nMasterVol; #endif // MODPLUG_TRACKER // Adjusting volumes if (m_MixerSettings.gnChannels >= 2) { int32 pan = pChn->nRealPan; Limit(pan, 0, 256); int32 realvol; if (m_PlayConfig.getUseGlobalPreAmp()) { realvol = (pChn->nRealVolume * kChnMasterVol) / 128; } else { // Extra attenuation required here if we're bypassing pre-amp. realvol = (pChn->nRealVolume * kChnMasterVol) / 256; } const ForcePanningMode panningMode = m_PlayConfig.getForcePanningMode(); if(panningMode == forceSoftPanning || (panningMode == dontForcePanningMode && (m_MixerSettings.MixerFlags & SNDMIX_SOFTPANNING))) { if (pan < 128) { pChn->newLeftVol = (realvol * 128) / 256; pChn->newRightVol = (realvol * pan) / 256; } else { pChn->newLeftVol = (realvol * (256 - pan)) / 256; pChn->newRightVol = (realvol * 128) / 256; } } else if(panningMode == forceFT2Panning) { // FT2 uses square root panning. There is a 257-entry LUT for this, // but FT2's internal panning ranges from 0 to 255 only, meaning that // you can never truly achieve 100% right panning in FT2, only 100% left. // Test case: FT2PanLaw.xm LimitMax(pan, 255); const int panL = pan > 0 ? XMPanningTable[256 - pan] : 65536; const int panR = XMPanningTable[pan]; pChn->newLeftVol = (realvol * panL) / 65536; pChn->newRightVol = (realvol * panR) / 65536; } else { pChn->newLeftVol = (realvol * (256 - pan)) / 256; pChn->newRightVol = (realvol * pan) / 256; } } else { pChn->newLeftVol = (pChn->nRealVolume * kChnMasterVol) / 256; pChn->newRightVol = pChn->newLeftVol; } // Clipping volumes //if (pChn->nNewRightVol > 0xFFFF) pChn->nNewRightVol = 0xFFFF; //if (pChn->nNewLeftVol > 0xFFFF) pChn->nNewLeftVol = 0xFFFF; if(pChn->pModInstrument && IsKnownResamplingMode(pChn->pModInstrument->nResampling)) { // For defined resampling modes, use per-instrument resampling mode if set pChn->resamplingMode = static_cast(pChn->pModInstrument->nResampling); } else if(IsKnownResamplingMode(m_nResampling)) { pChn->resamplingMode = static_cast(m_nResampling); } else if(m_SongFlags[SONG_ISAMIGA] && m_Resampler.m_Settings.emulateAmiga) { // Enforce Amiga resampler for Amiga modules pChn->resamplingMode = SRCMODE_AMIGA; } else { // Default to global mixer settings pChn->resamplingMode = static_cast(m_Resampler.m_Settings.SrcMode); } if(pChn->increment.IsUnity() && !(pChn->dwFlags[CHN_VIBRATO] || pChn->nAutoVibDepth || pChn->resamplingMode == SRCMODE_AMIGA)) { // Exact sample rate match, do not interpolate at all // - unless vibrato is applied, because in this case the constant enabling and disabling // of resampling can introduce clicks (this is easily observable with a sine sample // played at the mix rate). pChn->resamplingMode = SRCMODE_NEAREST; } const int extraAttenuation = m_PlayConfig.getExtraSampleAttenuation(); pChn->newLeftVol /= (1 << extraAttenuation); pChn->newRightVol /= (1 << extraAttenuation); // Dolby Pro-Logic Surround if(pChn->dwFlags[CHN_SURROUND] && m_MixerSettings.gnChannels == 2) pChn->newRightVol = - pChn->newRightVol; // Checking Ping-Pong Loops if(pChn->dwFlags[CHN_PINGPONGFLAG]) pChn->increment.Negate(); // Setting up volume ramp ProcessRamping(pChn); // Adding the channel in the channel list m_PlayState.ChnMix[m_nMixChannels++] = nChn; } else { pChn->rightVol = pChn->leftVol = 0; pChn->nLength = 0; } pChn->dwOldFlags = pChn->dwFlags; } // If there are more channels being mixed than allowed, order them by volume and discard the most quiet ones if(m_nMixChannels >= m_MixerSettings.m_nMaxMixChannels) { std::partial_sort(std::begin(m_PlayState.ChnMix), std::begin(m_PlayState.ChnMix) + m_MixerSettings.m_nMaxMixChannels, std::begin(m_PlayState.ChnMix) + m_nMixChannels, [this](CHANNELINDEX i, CHANNELINDEX j) { return (m_PlayState.Chn[i].nRealVolume > m_PlayState.Chn[j].nRealVolume); }); } return true; } void CSoundFile::ProcessMacroOnChannel(CHANNELINDEX nChn) { ModChannel *pChn = &m_PlayState.Chn[nChn]; if(nChn < GetNumChannels()) { // TODO evaluate per-plugin macros here //ProcessMIDIMacro(nChn, false, m_MidiCfg.szMidiGlb[MIDIOUT_PAN]); //ProcessMIDIMacro(nChn, false, m_MidiCfg.szMidiGlb[MIDIOUT_VOLUME]); if((pChn->rowCommand.command == CMD_MIDI && m_SongFlags[SONG_FIRSTTICK]) || pChn->rowCommand.command == CMD_SMOOTHMIDI) { if(pChn->rowCommand.param < 0x80) ProcessMIDIMacro(nChn, (pChn->rowCommand.command == CMD_SMOOTHMIDI), m_MidiCfg.szMidiSFXExt[pChn->nActiveMacro], pChn->rowCommand.param); else ProcessMIDIMacro(nChn, (pChn->rowCommand.command == CMD_SMOOTHMIDI), m_MidiCfg.szMidiZXXExt[(pChn->rowCommand.param & 0x7F)], 0); } } } #ifndef NO_PLUGINS void CSoundFile::ProcessMidiOut(CHANNELINDEX nChn) { ModChannel &chn = m_PlayState.Chn[nChn]; // Do we need to process MIDI? // For now there is no difference between mute and sync mute with VSTis. if(chn.dwFlags[CHN_MUTE | CHN_SYNCMUTE] || !chn.HasMIDIOutput()) return; // Get instrument info and plugin reference const ModInstrument *pIns = chn.pModInstrument; // Can't be nullptr at this point, as we have valid MIDI output. // No instrument or muted instrument? if(pIns->dwFlags[INS_MUTE]) { return; } // Check instrument plugins const PLUGINDEX nPlugin = GetBestPlugin(nChn, PrioritiseInstrument, RespectMutes); IMixPlugin *pPlugin = nullptr; if(nPlugin > 0 && nPlugin <= MAX_MIXPLUGINS) { pPlugin = m_MixPlugins[nPlugin - 1].pMixPlugin; } // Couldn't find a valid plugin if(pPlugin == nullptr) return; const ModCommand::NOTE note = chn.rowCommand.note; // Check for volume commands uint8 vol = 0xFF; if(chn.rowCommand.volcmd == VOLCMD_VOLUME) { vol = std::min(chn.rowCommand.vol, uint8(64)); } else if(chn.rowCommand.command == CMD_VOLUME) { vol = std::min(chn.rowCommand.param, uint8(64)); } const bool hasVolCommand = (vol != 0xFF); if(m_playBehaviour[kMIDICCBugEmulation]) { if(note != NOTE_NONE) { ModCommand::NOTE realNote = note; if(ModCommand::IsNote(note)) realNote = pIns->NoteMap[note - NOTE_MIN]; SendMIDINote(nChn, realNote, static_cast(chn.nVolume)); } else if(hasVolCommand) { pPlugin->MidiCC(GetBestMidiChannel(nChn), MIDIEvents::MIDICC_Volume_Fine, vol, nChn); } return; } const uint32 defaultVolume = pIns->nGlobalVol; //If new note, determine notevelocity to use. if(note != NOTE_NONE) { int32 velocity = static_cast(4 * defaultVolume); switch(pIns->nPluginVelocityHandling) { case PLUGIN_VELOCITYHANDLING_CHANNEL: velocity = chn.nVolume; break; } int32 swing = chn.nVolSwing; if(m_playBehaviour[kITSwingBehaviour]) swing *= 4; velocity += swing; Limit(velocity, 0, 256); ModCommand::NOTE realNote = note; if(ModCommand::IsNote(note)) realNote = pIns->NoteMap[note - NOTE_MIN]; // Experimental VST panning //ProcessMIDIMacro(nChn, false, m_MidiCfg.szMidiGlb[MIDIOUT_PAN], 0, nPlugin); SendMIDINote(nChn, realNote, static_cast(velocity)); } const bool processVolumeAlsoOnNote = (pIns->nPluginVelocityHandling == PLUGIN_VELOCITYHANDLING_VOLUME); if((hasVolCommand && !note) || (note && processVolumeAlsoOnNote)) { switch(pIns->nPluginVolumeHandling) { case PLUGIN_VOLUMEHANDLING_DRYWET: if(hasVolCommand) pPlugin->SetDryRatio(2 * vol); else pPlugin->SetDryRatio(2 * defaultVolume); break; case PLUGIN_VOLUMEHANDLING_MIDI: if(hasVolCommand) pPlugin->MidiCC(GetBestMidiChannel(nChn), MIDIEvents::MIDICC_Volume_Coarse, std::min(127u, 2u * vol), nChn); else pPlugin->MidiCC(GetBestMidiChannel(nChn), MIDIEvents::MIDICC_Volume_Coarse, static_cast(std::min(127u, 2u * defaultVolume)), nChn); break; } } } #endif // NO_PLUGINS template MPT_FORCEINLINE void ApplyGlobalVolumeWithRamping(int *SoundBuffer, int *RearBuffer, int32 lCount, int32 m_nGlobalVolume, int32 step, int32 &m_nSamplesToGlobalVolRampDest, int32 &m_lHighResRampingGlobalVolume) { const bool isStereo = (channels >= 2); const bool hasRear = (channels >= 4); for(int pos = 0; pos < lCount; ++pos) { if(m_nSamplesToGlobalVolRampDest > 0) { // Ramping required m_lHighResRampingGlobalVolume += step; SoundBuffer[0] = Util::muldiv(SoundBuffer[0], m_lHighResRampingGlobalVolume, MAX_GLOBAL_VOLUME << VOLUMERAMPPRECISION); MPT_CONSTANT_IF(isStereo) SoundBuffer[1] = Util::muldiv(SoundBuffer[1], m_lHighResRampingGlobalVolume, MAX_GLOBAL_VOLUME << VOLUMERAMPPRECISION); MPT_CONSTANT_IF(hasRear) RearBuffer[0] = Util::muldiv(RearBuffer[0] , m_lHighResRampingGlobalVolume, MAX_GLOBAL_VOLUME << VOLUMERAMPPRECISION); MPT_CONSTANT_IF(hasRear) RearBuffer[1] = Util::muldiv(RearBuffer[1] , m_lHighResRampingGlobalVolume, MAX_GLOBAL_VOLUME << VOLUMERAMPPRECISION); m_nSamplesToGlobalVolRampDest--; } else { SoundBuffer[0] = Util::muldiv(SoundBuffer[0], m_nGlobalVolume, MAX_GLOBAL_VOLUME); MPT_CONSTANT_IF(isStereo) SoundBuffer[1] = Util::muldiv(SoundBuffer[1], m_nGlobalVolume, MAX_GLOBAL_VOLUME); MPT_CONSTANT_IF(hasRear) RearBuffer[0] = Util::muldiv(RearBuffer[0] , m_nGlobalVolume, MAX_GLOBAL_VOLUME); MPT_CONSTANT_IF(hasRear) RearBuffer[1] = Util::muldiv(RearBuffer[1] , m_nGlobalVolume, MAX_GLOBAL_VOLUME); m_lHighResRampingGlobalVolume = m_nGlobalVolume << VOLUMERAMPPRECISION; } SoundBuffer += isStereo ? 2 : 1; MPT_CONSTANT_IF(hasRear) RearBuffer += 2; } } void CSoundFile::ProcessGlobalVolume(long lCount) { // should we ramp? if(IsGlobalVolumeUnset()) { // do not ramp if no global volume was set before (which is the case at song start), to prevent audible glitches when default volume is > 0 and it is set to 0 in the first row m_PlayState.m_nGlobalVolumeDestination = m_PlayState.m_nGlobalVolume; m_PlayState.m_nSamplesToGlobalVolRampDest = 0; m_PlayState.m_nGlobalVolumeRampAmount = 0; } else if(m_PlayState.m_nGlobalVolumeDestination != m_PlayState.m_nGlobalVolume) { // User has provided new global volume // m_nGlobalVolume: the last global volume which got set e.g. by a pattern command // m_nGlobalVolumeDestination: the current target of the ramping algorithm const bool rampUp = m_PlayState.m_nGlobalVolume > m_PlayState.m_nGlobalVolumeDestination; m_PlayState.m_nGlobalVolumeDestination = m_PlayState.m_nGlobalVolume; m_PlayState.m_nSamplesToGlobalVolRampDest = m_PlayState.m_nGlobalVolumeRampAmount = rampUp ? m_MixerSettings.GetVolumeRampUpSamples() : m_MixerSettings.GetVolumeRampDownSamples(); } // calculate ramping step int32 step = 0; if (m_PlayState.m_nSamplesToGlobalVolRampDest > 0) { // Still some ramping left to do. int32 highResGlobalVolumeDestination = static_cast(m_PlayState.m_nGlobalVolumeDestination) << VOLUMERAMPPRECISION; const long delta = highResGlobalVolumeDestination - m_PlayState.m_lHighResRampingGlobalVolume; step = delta / static_cast(m_PlayState.m_nSamplesToGlobalVolRampDest); if(m_nMixLevels == mixLevels1_17RC2) { // Define max step size as some factor of user defined ramping value: the lower the value, the more likely the click. // If step is too big (might cause click), extend ramp length. // Warning: This increases the volume ramp length by EXTREME amounts (factors of 100 are easily reachable) // compared to the user-defined setting, so this really should not be used! int32 maxStep = std::max(50, (10000 / (m_PlayState.m_nGlobalVolumeRampAmount + 1))); while(mpt::abs(step) > maxStep) { m_PlayState.m_nSamplesToGlobalVolRampDest += m_PlayState.m_nGlobalVolumeRampAmount; step = delta / static_cast(m_PlayState.m_nSamplesToGlobalVolRampDest); } } } // apply volume and ramping if(m_MixerSettings.gnChannels == 1) { ApplyGlobalVolumeWithRamping<1>(MixSoundBuffer, MixRearBuffer, lCount, m_PlayState.m_nGlobalVolume, step, m_PlayState.m_nSamplesToGlobalVolRampDest, m_PlayState.m_lHighResRampingGlobalVolume); } else if(m_MixerSettings.gnChannels == 2) { ApplyGlobalVolumeWithRamping<2>(MixSoundBuffer, MixRearBuffer, lCount, m_PlayState.m_nGlobalVolume, step, m_PlayState.m_nSamplesToGlobalVolRampDest, m_PlayState.m_lHighResRampingGlobalVolume); } else if(m_MixerSettings.gnChannels == 4) { ApplyGlobalVolumeWithRamping<4>(MixSoundBuffer, MixRearBuffer, lCount, m_PlayState.m_nGlobalVolume, step, m_PlayState.m_nSamplesToGlobalVolRampDest, m_PlayState.m_lHighResRampingGlobalVolume); } } void CSoundFile::ProcessStereoSeparation(long countChunk) { ApplyStereoSeparation(MixSoundBuffer, MixRearBuffer, m_MixerSettings.gnChannels, countChunk, m_MixerSettings.m_nStereoSeparation); } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/ContainerUMX.cpp0000644000372100037210000001202713161656666021137 00000000000000/* * ContainerUMX.cpp * ---------------- * Purpose: UMX (Unreal Music) module ripper * Notes : Obviously, this code only rips modules from older Unreal Engine games, such as Unreal 1, Unreal Tournament 1 and Deus Ex. * Authors: Johannes Schultz (inspired by code from http://wiki.beyondunreal.com/Legacy:Package_File_Format) * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" #include "UMXTools.h" #include "Container.h" #include "Sndfile.h" OPENMPT_NAMESPACE_BEGIN static bool ValidateHeader(const UMXFileHeader &fileHeader) { if(std::memcmp(fileHeader.magic, "\xC1\x83\x2A\x9E", 4) || fileHeader.nameCount == 0 || fileHeader.exportCount == 0 || fileHeader.importCount == 0 ) { return false; } return true; } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderUMX(MemoryFileReader file, const uint64 *pfilesize) { UMXFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return ProbeWantMoreData; } if(!ValidateHeader(fileHeader)) { return ProbeFailure; } if(!FindUMXNameTableEntryMemory(file, fileHeader, "music")) { return ProbeFailure; } MPT_UNREFERENCED_PARAMETER(pfilesize); return ProbeSuccess; } bool UnpackUMX(std::vector &containerItems, FileReader &file, ContainerLoadingFlags loadFlags) { file.Rewind(); containerItems.clear(); UMXFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return false; } if(!ValidateHeader(fileHeader)) { return false; } // Note that this can be a false positive, e.g. Unreal maps will have music and sound // in their name table because they usually import such files. However, it spares us // from wildly seeking through the file, as the name table is usually right at the // start of the file, so it is hopefully a good enough heuristic for our purposes. if(!FindUMXNameTableEntry(file, fileHeader, "music")) { return false; } if(loadFlags == ContainerOnlyVerifyHeader) { return true; } // Read name table std::vector names = ReadUMXNameTable(file, fileHeader); // Read import table if(!file.Seek(fileHeader.importOffset)) { return false; } std::vector classes; classes.reserve(fileHeader.importCount); for(uint32 i = 0; i < fileHeader.importCount && file.CanRead(4); i++) { int32 objName = ReadUMXImportTableEntry(file, fileHeader.packageVersion); if(static_cast(objName) < names.size()) { classes.push_back(objName); } } // Read export table if(!file.Seek(fileHeader.exportOffset)) { return false; } // Now we can be pretty sure that we're doing the right thing. for(uint32 i = 0; i < fileHeader.exportCount && file.CanRead(4); i++) { int32 objClass, objOffset, objSize, objName; ReadUMXExportTableEntry(file, objClass, objOffset, objSize, objName, fileHeader.packageVersion); if(objSize <= 0 || objClass >= 0) { continue; } // Look up object class name (we only want music). objClass = -objClass - 1; bool isMusic = false; if(static_cast(objClass) < classes.size()) { isMusic = (names[classes[objClass]] == "music"); } if(!isMusic) { continue; } FileReader chunk = file.GetChunkAt(objOffset, objSize); if(chunk.IsValid()) { if(fileHeader.packageVersion < 40) { chunk.Skip(8); // 00 00 00 00 00 00 00 00 } if(fileHeader.packageVersion < 60) { chunk.Skip(16); // 81 00 00 00 00 00 FF FF FF FF FF FF FF FF 00 00 } // Read object properties #if 0 size_t propertyName = static_cast(ReadUMXIndex(chunk)); if(propertyName >= names.size() || names[propertyName] != "none") { // Can't bother to implement property reading, as no UMX files I've seen so far use properties for the relevant objects, // and only the UAX files in the Unreal 1997/98 beta seem to use this and still load just fine when ignoring it. // If it should be necessary to implement this, check CUnProperty.cpp in http://ut-files.com/index.php?dir=Utilities/&file=utcms_source.zip MPT_ASSERT_NOTREACHED(); continue; } #else ReadUMXIndex(chunk); #endif if(fileHeader.packageVersion >= 120) { // UT2003 Packages ReadUMXIndex(chunk); chunk.Skip(8); } else if(fileHeader.packageVersion >= 100) { // AAO Packages chunk.Skip(4); ReadUMXIndex(chunk); chunk.Skip(4); } else if(fileHeader.packageVersion >= 62) { // UT Packages // Mech8.umx and a few other UT tunes have packageVersion = 62. // In CUnSound.cpp, the condition above reads "packageVersion >= 63" but if that is used, those tunes won't load properly. ReadUMXIndex(chunk); chunk.Skip(4); } else { // Old Unreal Packagaes ReadUMXIndex(chunk); } int32 size = ReadUMXIndex(chunk); ContainerItem item; if(objName >= 0 && static_cast(objName) < names.size()) { item.name = mpt::ToUnicode(mpt::CharsetISO8859_1, names[objName]); } item.file = chunk.ReadChunk(size); containerItems.push_back(std::move(item)); } } return !containerItems.empty(); } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Snd_fx.cpp0000644000372100037210000056773413234636016020054 00000000000000/* * Snd_fx.cpp * ----------- * Purpose: Processing of pattern commands, song length calculation... * Notes : This needs some heavy refactoring. * I thought of actually adding an effect interface class. Every pattern effect * could then be moved into its own class that inherits from the effect interface. * If effect handling differs severly between module formats, every format would have * its own class for that effect. Then, a call chain of effect classes could be set up * for each format, since effects cannot be processed in the same order in all formats. * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Sndfile.h" #include "mod_specifications.h" #ifdef MODPLUG_TRACKER #include "../mptrack/Moddoc.h" #endif // MODPLUG_TRACKER #include "tuning.h" #include "Tables.h" #include "modsmp_ctrl.h" // For updating the loop wraparound data with the invert loop effect #include "plugins/PlugInterface.h" OPENMPT_NAMESPACE_BEGIN // Formats which have 7-bit (0...128) instead of 6-bit (0...64) global volume commands, or which are imported to this range (mostly formats which are converted to IT internally) #ifdef MODPLUG_TRACKER #define GLOBALVOL_7BIT_FORMATS_EXT (MOD_TYPE_MT2) #else #define GLOBALVOL_7BIT_FORMATS_EXT Enum::value_type() #endif // MODPLUG_TRACKER #define GLOBALVOL_7BIT_FORMATS (MOD_TYPE_IT | MOD_TYPE_MPT | MOD_TYPE_IMF | MOD_TYPE_J2B | MOD_TYPE_MID | MOD_TYPE_AMS | MOD_TYPE_AMS2 | MOD_TYPE_DBM | MOD_TYPE_PTM | MOD_TYPE_MDL | MOD_TYPE_DTM | GLOBALVOL_7BIT_FORMATS_EXT) // Compensate frequency slide LUTs depending on whether we are handling periods or frequency - "up" and "down" in function name are seen from frequency perspective. static uint32 GetLinearSlideDownTable (const CSoundFile *sndFile, uint32 i) { MPT_ASSERT(i < CountOf(LinearSlideDownTable)); return sndFile->m_playBehaviour[kHertzInLinearMode] ? LinearSlideDownTable[i] : LinearSlideUpTable[i]; } static uint32 GetLinearSlideUpTable (const CSoundFile *sndFile, uint32 i) { MPT_ASSERT(i < CountOf(LinearSlideDownTable)); return sndFile->m_playBehaviour[kHertzInLinearMode] ? LinearSlideUpTable[i] : LinearSlideDownTable[i]; } static uint32 GetFineLinearSlideDownTable(const CSoundFile *sndFile, uint32 i) { MPT_ASSERT(i < CountOf(FineLinearSlideDownTable)); return sndFile->m_playBehaviour[kHertzInLinearMode] ? FineLinearSlideDownTable[i] : FineLinearSlideUpTable[i]; } static uint32 GetFineLinearSlideUpTable (const CSoundFile *sndFile, uint32 i) { MPT_ASSERT(i < CountOf(FineLinearSlideDownTable)); return sndFile->m_playBehaviour[kHertzInLinearMode] ? FineLinearSlideUpTable[i] : FineLinearSlideDownTable[i]; } //////////////////////////////////////////////////////////// // Length // Memory class for GetLength() code class GetLengthMemory { protected: const CSoundFile &sndFile; public: std::unique_ptr state; struct ChnSettings { double patLoop; CSoundFile::samplecount_t patLoopSmp; ROWINDEX patLoopStart; uint32 ticksToRender; // When using sample sync, we still need to render this many ticks bool incChanged; // When using sample sync, note frequency has changed uint8 vol; ChnSettings() : patLoop(0.0) , patLoopSmp(0) , patLoopStart(0) , ticksToRender(0) , incChanged(false) , vol(0xFF) { } }; #ifndef NO_PLUGINS typedef std::map, uint16> PlugParamMap; PlugParamMap plugParams; #endif std::vector chnSettings; double elapsedTime; static const uint32 IGNORE_CHANNEL = uint32_max; GetLengthMemory(const CSoundFile &sf) : sndFile(sf) , state(mpt::make_unique(sf.m_PlayState)) { Reset(); } void Reset() { plugParams.clear(); elapsedTime = 0.0; state->m_lTotalSampleCount = 0; state->m_nMusicSpeed = sndFile.m_nDefaultSpeed; state->m_nMusicTempo = sndFile.m_nDefaultTempo; state->m_nGlobalVolume = sndFile.m_nDefaultGlobalVolume; chnSettings.assign(sndFile.GetNumChannels(), ChnSettings()); for(CHANNELINDEX chn = 0; chn < sndFile.GetNumChannels(); chn++) { state->Chn[chn].Reset(ModChannel::resetTotal, sndFile, chn); state->Chn[chn].nOldGlobalVolSlide = 0; state->Chn[chn].nOldChnVolSlide = 0; state->Chn[chn].nNote = state->Chn[chn].nNewNote = state->Chn[chn].nLastNote = NOTE_NONE; } } // Increment playback position of sample and envelopes on a channel void RenderChannel(CHANNELINDEX channel, uint32 tickDuration, uint32 portaStart = uint32_max) { ModChannel &chn = state->Chn[channel]; uint32 numTicks = chnSettings[channel].ticksToRender; if(numTicks == IGNORE_CHANNEL || numTicks == 0 || (!chn.IsSamplePlaying() && !chnSettings[channel].incChanged) || chn.pModSample == nullptr) { return; } const SmpLength sampleEnd = chn.dwFlags[CHN_LOOP] ? chn.nLoopEnd : chn.nLength; const SmpLength loopLength = chn.nLoopEnd - chn.nLoopStart; const bool itEnvMode = sndFile.m_playBehaviour[kITEnvelopePositionHandling]; const bool updatePitchEnv = (chn.PitchEnv.flags & (ENV_ENABLED | ENV_FILTER)) == ENV_ENABLED; bool stopNote = false; SamplePosition inc = chn.increment * tickDuration; if(chn.dwFlags[CHN_PINGPONGFLAG]) inc.Negate(); for(uint32 i = 0; i < numTicks; i++) { bool updateInc = (chn.PitchEnv.flags & (ENV_ENABLED | ENV_FILTER)) == ENV_ENABLED; if(i >= portaStart) { chn.isFirstTick = false; const ModCommand &p = *sndFile.Patterns[state->m_nPattern].GetpModCommand(state->m_nRow, channel); if(p.command == CMD_TONEPORTAMENTO) sndFile.TonePortamento(&chn, p.param); else if(p.command == CMD_TONEPORTAVOL) sndFile.TonePortamento(&chn, 0); if(p.volcmd == VOLCMD_TONEPORTAMENTO) { uint32 param = p.vol; if(sndFile.GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT | MOD_TYPE_AMS | MOD_TYPE_AMS2 | MOD_TYPE_DMF | MOD_TYPE_DBM | MOD_TYPE_IMF | MOD_TYPE_PSM | MOD_TYPE_J2B | MOD_TYPE_ULT | MOD_TYPE_OKT | MOD_TYPE_MT2 | MOD_TYPE_MDL)) { param = ImpulseTrackerPortaVolCmd[param & 0x0F]; } else { // Close enough. Do not bother with idiosyncratic FT2 behaviour here. param <<= 4; } sndFile.TonePortamento(&chn, param); } updateInc = true; } int period = chn.nPeriod; if(itEnvMode) sndFile.IncrementEnvelopePositions(&chn); if(updatePitchEnv) { sndFile.ProcessPitchFilterEnvelope(&chn, period); updateInc = true; } if(!itEnvMode) sndFile.IncrementEnvelopePositions(&chn); int vol = 0; sndFile.ProcessInstrumentFade(&chn, vol); if(updateInc || chnSettings[channel].incChanged) { chn.increment = sndFile.GetChannelIncrement(&chn, period, 0); chnSettings[channel].incChanged = false; inc = chn.increment * tickDuration; if(chn.dwFlags[CHN_PINGPONGFLAG]) inc.Negate(); } chn.position += inc; if(chn.position.GetUInt() >= sampleEnd) { if(chn.dwFlags[CHN_LOOP]) { // We exceeded the sample loop, go back to loop start. if(chn.dwFlags[CHN_PINGPONGLOOP]) { if(chn.position < SamplePosition(chn.nLoopStart, 0)) { chn.position = SamplePosition(chn.nLoopStart + chn.nLoopStart, 0) - chn.position; chn.dwFlags.flip(CHN_PINGPONGFLAG); inc.Negate(); } SmpLength posInt = chn.position.GetUInt() - chn.nLoopStart; SmpLength pingpongLength = loopLength * 2; if(sndFile.m_playBehaviour[kITPingPongMode]) pingpongLength--; posInt %= pingpongLength; bool forward = (posInt < loopLength); if(forward) chn.position.SetInt(chn.nLoopStart + posInt); else chn.position.SetInt(chn.nLoopEnd - (posInt - loopLength)); if(forward == chn.dwFlags[CHN_PINGPONGFLAG]) { chn.dwFlags.flip(CHN_PINGPONGFLAG); inc.Negate(); } } else { SmpLength posInt = chn.position.GetUInt(); if(posInt >= chn.nLoopEnd + loopLength) { const SmpLength overshoot = posInt - chn.nLoopEnd; posInt -= (overshoot / loopLength) * loopLength; } while(posInt >= chn.nLoopEnd) { posInt -= loopLength; } chn.position.SetInt(posInt); } } else { // Past sample end. stopNote = true; break; } } } if(stopNote) { chn.Stop(); chn.nPortamentoDest = 0; } chnSettings[channel].ticksToRender = 0; } }; // Get mod length in various cases. Parameters: // [in] adjustMode: See enmGetLengthResetMode for possible adjust modes. // [in] target: Time or position target which should be reached, or no target to get length of the first sub song. Use GetLengthTarget::StartPos to also specify a position from where the seeking should begin. // [out] See definition of type GetLengthType for the returned values. std::vector CSoundFile::GetLength(enmGetLengthResetMode adjustMode, GetLengthTarget target) { std::vector results; GetLengthType retval; retval.startOrder = target.startOrder; retval.startRow = target.startRow; // Are we trying to reach a certain pattern position? const bool hasSearchTarget = target.mode != GetLengthTarget::NoTarget; const bool adjustSamplePos = (adjustMode & eAdjustSamplePositions) == eAdjustSamplePositions; SEQUENCEINDEX sequence = target.sequence; if(sequence >= Order.GetNumSequences()) sequence = Order.GetCurrentSequenceIndex(); const ModSequence &orderList = Order(sequence); GetLengthMemory memory(*this); CSoundFile::PlayState &playState = *memory.state; // Temporary visited rows vector (so that GetLength() won't interfere with the player code if the module is playing at the same time) RowVisitor visitedRows(*this, sequence); playState.m_nNextRow = playState.m_nRow = target.startRow; playState.m_nNextOrder = playState.m_nCurrentOrder = target.startOrder; // Fast LUTs for commands that are too weird / complicated / whatever to emulate in sample position adjust mode. std::bitset forbiddenCommands; std::bitset forbiddenVolCommands; if(adjustSamplePos) { forbiddenCommands.set(CMD_ARPEGGIO); forbiddenCommands.set(CMD_PORTAMENTOUP); forbiddenCommands.set(CMD_PORTAMENTODOWN); forbiddenCommands.set(CMD_XFINEPORTAUPDOWN); forbiddenCommands.set(CMD_NOTESLIDEUP); forbiddenCommands.set(CMD_NOTESLIDEUPRETRIG); forbiddenCommands.set(CMD_NOTESLIDEDOWN); forbiddenCommands.set(CMD_NOTESLIDEDOWNRETRIG); forbiddenVolCommands.set(VOLCMD_PORTAUP); forbiddenVolCommands.set(VOLCMD_PORTADOWN); forbiddenVolCommands.set(VOLCMD_VOLSLIDEUP); forbiddenVolCommands.set(VOLCMD_VOLSLIDEDOWN); // Optimize away channels for which it's pointless to adjust sample positions for(CHANNELINDEX i = 0; i < GetNumChannels(); i++) { if(ChnSettings[i].dwFlags[CHN_MUTE]) memory.chnSettings[i].ticksToRender = GetLengthMemory::IGNORE_CHANNEL; } if(target.mode == GetLengthTarget::SeekPosition && target.pos.order < orderList.size()) { // If we know where to seek, we can directly rule out any channels on which a new note would be triggered right at the start. const PATTERNINDEX seekPat = orderList[target.pos.order]; if(Patterns.IsValidPat(seekPat) && Patterns[seekPat].IsValidRow(target.pos.row)) { const ModCommand *m = Patterns[seekPat].GetRow(target.pos.row); for(CHANNELINDEX i = 0; i < GetNumChannels(); i++, m++) { if(m->note == NOTE_NOTECUT || m->note == NOTE_KEYOFF || (m->note == NOTE_FADE && GetNumInstruments()) || (m->IsNote() && !m->IsPortamento())) { memory.chnSettings[i].ticksToRender = GetLengthMemory::IGNORE_CHANNEL; } } } } } // If samples are being synced, force them to resync if tick duration changes uint32 oldTickDuration = 0; for (;;) { // Time target reached. if(target.mode == GetLengthTarget::SeekSeconds && memory.elapsedTime >= target.time) { retval.targetReached = true; break; } uint32 rowDelay = 0, tickDelay = 0; playState.m_nRow = playState.m_nNextRow; playState.m_nCurrentOrder = playState.m_nNextOrder; if(orderList.IsValidPat(playState.m_nCurrentOrder) && playState.m_nRow >= Patterns[orderList[playState.m_nCurrentOrder]].GetNumRows()) { playState.m_nRow = 0; if(m_playBehaviour[kFT2LoopE60Restart]) { playState.m_nRow = playState.m_nNextPatStartRow; playState.m_nNextPatStartRow = 0; } playState.m_nCurrentOrder = ++playState.m_nNextOrder; } // Check if pattern is valid playState.m_nPattern = playState.m_nCurrentOrder < orderList.size() ? orderList[playState.m_nCurrentOrder] : orderList.GetInvalidPatIndex(); bool positionJumpOnThisRow = false; bool patternBreakOnThisRow = false; bool patternLoopEndedOnThisRow = false, patternLoopStartedOnThisRow = false; if(playState.m_nPattern == orderList.GetIgnoreIndex() && target.mode == GetLengthTarget::SeekPosition && playState.m_nCurrentOrder == target.pos.order) { // Early test: Target is inside +++ pattern retval.targetReached = true; break; } while(playState.m_nPattern >= Patterns.Size()) { // End of song? if((playState.m_nPattern == orderList.GetInvalidPatIndex()) || (playState.m_nCurrentOrder >= orderList.size())) { if(playState.m_nCurrentOrder == orderList.GetRestartPos()) break; else playState.m_nCurrentOrder = orderList.GetRestartPos(); } else { playState.m_nCurrentOrder++; } playState.m_nPattern = (playState.m_nCurrentOrder < orderList.size()) ? orderList[playState.m_nCurrentOrder] : orderList.GetInvalidPatIndex(); playState.m_nNextOrder = playState.m_nCurrentOrder; if((!Patterns.IsValidPat(playState.m_nPattern)) && visitedRows.IsVisited(playState.m_nCurrentOrder, 0, true)) { if(!hasSearchTarget || !visitedRows.GetFirstUnvisitedRow(playState.m_nNextOrder, playState.m_nRow, true)) { // We aren't searching for a specific row, or we couldn't find any more unvisited rows. break; } else { // We haven't found the target row yet, but we found some other unplayed row... continue searching from here. retval.duration = memory.elapsedTime; results.push_back(retval); retval.startRow = playState.m_nRow; retval.startOrder = playState.m_nNextOrder; memory.Reset(); playState.m_nCurrentOrder = playState.m_nNextOrder; playState.m_nPattern = orderList[playState.m_nCurrentOrder]; playState.m_nNextRow = playState.m_nRow; break; } } } if(playState.m_nNextOrder == ORDERINDEX_INVALID) { // GetFirstUnvisitedRow failed, so there is nothing more to play break; } // Skip non-existing patterns if(!Patterns.IsValidPat(playState.m_nPattern)) { // If there isn't even a tune, we should probably stop here. if(playState.m_nCurrentOrder == orderList.GetRestartPos()) { if(!hasSearchTarget || !visitedRows.GetFirstUnvisitedRow(playState.m_nNextOrder, playState.m_nRow, true)) { // We aren't searching for a specific row, or we couldn't find any more unvisited rows. break; } else { // We haven't found the target row yet, but we found some other unplayed row... continue searching from here. retval.duration = memory.elapsedTime; results.push_back(retval); retval.startRow = playState.m_nRow; retval.startOrder = playState.m_nNextOrder; memory.Reset(); playState.m_nNextRow = playState.m_nRow; continue; } } playState.m_nNextOrder = playState.m_nCurrentOrder + 1; continue; } // Should never happen if(playState.m_nRow >= Patterns[playState.m_nPattern].GetNumRows()) playState.m_nRow = 0; // Check whether target was reached. if(target.mode == GetLengthTarget::SeekPosition && playState.m_nCurrentOrder == target.pos.order && playState.m_nRow == target.pos.row) { retval.targetReached = true; break; } if(visitedRows.IsVisited(playState.m_nCurrentOrder, playState.m_nRow, true)) { if(!hasSearchTarget || !visitedRows.GetFirstUnvisitedRow(playState.m_nNextOrder, playState.m_nRow, true)) { // We aren't searching for a specific row, or we couldn't find any more unvisited rows. break; } else { // We haven't found the target row yet, but we found some other unplayed row... continue searching from here. retval.duration = memory.elapsedTime; results.push_back(retval); retval.startRow = playState.m_nRow; retval.startOrder = playState.m_nNextOrder; memory.Reset(); playState.m_nNextRow = playState.m_nRow; continue; } } retval.endOrder = playState.m_nCurrentOrder; retval.endRow = playState.m_nRow; // Update next position playState.m_nNextRow = playState.m_nRow + 1; // Jumped to invalid pattern row? if(playState.m_nRow >= Patterns[playState.m_nPattern].GetNumRows()) { playState.m_nRow = 0; } // New pattern? if(!playState.m_nRow) { for(CHANNELINDEX chn = 0; chn < GetNumChannels(); chn++) { memory.chnSettings[chn].patLoop = memory.elapsedTime; memory.chnSettings[chn].patLoopSmp = playState.m_lTotalSampleCount; } } ModChannel *pChn = playState.Chn; // For various effects, we need to know first how many ticks there are in this row. const ModCommand *p = Patterns[playState.m_nPattern].GetpModCommand(playState.m_nRow, 0); for(CHANNELINDEX nChn = 0; nChn < GetNumChannels(); nChn++, p++) { if(m_playBehaviour[kST3NoMutedChannels] && ChnSettings[nChn].dwFlags[CHN_MUTE]) // not even effects are processed on muted S3M channels continue; if(p->IsPcNote()) { #ifndef NO_PLUGINS if((adjustMode & eAdjust) && p->instr > 0 && p->instr <= MAX_MIXPLUGINS) { memory.plugParams[std::make_pair(p->instr, p->GetValueVolCol())] = p->GetValueEffectCol(); } #endif // NO_PLUGINS pChn[nChn].rowCommand.Clear(); continue; } pChn[nChn].rowCommand = *p; switch(p->command) { case CMD_SPEED: SetSpeed(playState, p->param); break; case CMD_TEMPO: if(m_playBehaviour[kMODVBlankTiming]) { // ProTracker MODs with VBlank timing: All Fxx parameters set the tick count. if(p->param != 0) SetSpeed(playState, p->param); } break; case CMD_S3MCMDEX: if((p->param & 0xF0) == 0x60) { // Fine Pattern Delay tickDelay += (p->param & 0x0F); } if((p->param & 0xF0) == 0xE0 && !rowDelay) { // Pattern Delay if(!(GetType() & MOD_TYPE_S3M) || (p->param & 0x0F) != 0) { // While Impulse Tracker *does* count S60 as a valid row delay (and thus ignores any other row delay commands on the right), // Scream Tracker 3 simply ignores such commands. rowDelay = 1 + (p->param & 0x0F); } } break; case CMD_MODCMDEX: if((p->param & 0xF0) == 0xE0) { // Pattern Delay rowDelay = 1 + (p->param & 0x0F); } break; } } if(rowDelay == 0) rowDelay = 1; const uint32 numTicks = (playState.m_nMusicSpeed + tickDelay) * rowDelay; const uint32 nonRowTicks = numTicks - rowDelay; for(CHANNELINDEX nChn = 0; nChn < GetNumChannels(); pChn++, nChn++) if(!pChn->rowCommand.IsEmpty()) { if(m_playBehaviour[kST3NoMutedChannels] && ChnSettings[nChn].dwFlags[CHN_MUTE]) // not even effects are processed on muted S3M channels continue; ModCommand::COMMAND command = pChn->rowCommand.command; ModCommand::PARAM param = pChn->rowCommand.param; ModCommand::NOTE note = pChn->rowCommand.note; if (pChn->rowCommand.instr) { pChn->nNewIns = pChn->rowCommand.instr; pChn->nLastNote = NOTE_NONE; memory.chnSettings[nChn].vol = 0xFF; } if (pChn->rowCommand.IsNote()) pChn->nLastNote = note; // Update channel panning if(pChn->rowCommand.IsNote() || pChn->rowCommand.instr) { SAMPLEINDEX smp = 0; if(GetNumInstruments()) { ModInstrument *pIns; if(pChn->nNewIns <= GetNumInstruments() && (pIns = Instruments[pChn->nNewIns]) != nullptr) { if(pIns->dwFlags[INS_SETPANNING]) pChn->nPan = pIns->nPan; if(ModCommand::IsNote(note)) smp = pIns->Keyboard[note - NOTE_MIN]; } } else { smp = pChn->nNewIns; } if(smp > 0 && smp <= GetNumSamples() && Samples[smp].uFlags[CHN_PANNING]) { pChn->nPan = Samples[smp].nPan; } } if (pChn->rowCommand.volcmd == VOLCMD_VOLUME) { memory.chnSettings[nChn].vol = pChn->rowCommand.vol; } switch(command) { // Position Jump case CMD_POSITIONJUMP: positionJumpOnThisRow = true; playState.m_nNextOrder = static_cast(CalculateXParam(playState.m_nPattern, playState.m_nRow, nChn)); playState.m_nNextPatStartRow = 0; // FT2 E60 bug // see https://forum.openmpt.org/index.php?topic=2769.0 - FastTracker resets Dxx if Bxx is called _after_ Dxx // Test case: PatternJump.mod if(!patternBreakOnThisRow || (GetType() & (MOD_TYPE_MOD | MOD_TYPE_XM))) playState.m_nNextRow = 0; if (adjustMode & eAdjust) { pChn->nPatternLoopCount = 0; pChn->nPatternLoop = 0; } break; // Pattern Break case CMD_PATTERNBREAK: { ROWINDEX row = PatternBreak(playState, nChn, param); if(row != ROWINDEX_INVALID) { patternBreakOnThisRow = true; playState.m_nNextRow = row; if(!positionJumpOnThisRow) { playState.m_nNextOrder = playState.m_nCurrentOrder + 1; } if(adjustMode & eAdjust) { pChn->nPatternLoopCount = 0; pChn->nPatternLoop = 0; } } } break; // Set Tempo case CMD_TEMPO: if(!m_playBehaviour[kMODVBlankTiming]) { TEMPO tempo(CalculateXParam(playState.m_nPattern, playState.m_nRow, nChn), 0); if ((adjustMode & eAdjust) && (GetType() & (MOD_TYPE_S3M | MOD_TYPE_IT | MOD_TYPE_MPT))) { if (tempo.GetInt()) pChn->nOldTempo = static_cast(tempo.GetInt()); else tempo.Set(pChn->nOldTempo); } if (tempo.GetInt() >= 0x20) playState.m_nMusicTempo = tempo; else { // Tempo Slide TEMPO tempoDiff((tempo.GetInt() & 0x0F) * nonRowTicks, 0); if ((tempo.GetInt() & 0xF0) == 0x10) { playState.m_nMusicTempo += tempoDiff; } else { if(tempoDiff < playState.m_nMusicTempo) playState.m_nMusicTempo -= tempoDiff; else playState.m_nMusicTempo.Set(0); } } TEMPO tempoMin = GetModSpecifications().GetTempoMin(), tempoMax = GetModSpecifications().GetTempoMax(); if(m_playBehaviour[kTempoClamp]) // clamp tempo correctly in compatible mode { tempoMax.Set(255); } Limit(playState.m_nMusicTempo, tempoMin, tempoMax); } break; case CMD_S3MCMDEX: switch(param & 0xF0) { case 0x90: if(param <= 0x91) { pChn->dwFlags.set(CHN_SURROUND, param == 0x91); } break; case 0xA0: // High sample offset pChn->nOldHiOffset = param & 0x0F; break; case 0xB0: // Pattern Loop if (param & 0x0F) { patternLoopEndedOnThisRow = true; } else { CHANNELINDEX firstChn = nChn, lastChn = nChn; if(GetType() == MOD_TYPE_S3M) { // ST3 has only one global loop memory. firstChn = 0; lastChn = GetNumChannels() - 1; } for(CHANNELINDEX c = firstChn; c <= lastChn; c++) { memory.chnSettings[c].patLoop = memory.elapsedTime; memory.chnSettings[c].patLoopSmp = playState.m_lTotalSampleCount; memory.chnSettings[c].patLoopStart = playState.m_nRow; } patternLoopStartedOnThisRow = true; } break; } break; case CMD_MODCMDEX: if ((param & 0xF0) == 0x60) { // Pattern Loop if (param & 0x0F) { playState.m_nNextPatStartRow = memory.chnSettings[nChn].patLoopStart; // FT2 E60 bug patternLoopEndedOnThisRow = true; } else { patternLoopStartedOnThisRow = true; memory.chnSettings[nChn].patLoop = memory.elapsedTime; memory.chnSettings[nChn].patLoopSmp = playState.m_lTotalSampleCount; memory.chnSettings[nChn].patLoopStart = playState.m_nRow; } } break; case CMD_XFINEPORTAUPDOWN: // ignore high offset in compatible mode if(((param & 0xF0) == 0xA0) && !m_playBehaviour[kFT2RestrictXCommand]) pChn->nOldHiOffset = param & 0x0F; break; } // The following calculations are not interesting if we just want to get the song length. if (!(adjustMode & eAdjust)) continue; switch(command) { // Portamento Up/Down case CMD_PORTAMENTOUP: if(param) { // FT2 compatibility: Separate effect memory for all portamento commands // Test case: Porta-LinkMem.xm if(!m_playBehaviour[kFT2PortaUpDownMemory]) pChn->nOldPortaDown = param; pChn->nOldPortaUp = param; } break; case CMD_PORTAMENTODOWN: if(param) { // FT2 compatibility: Separate effect memory for all portamento commands // Test case: Porta-LinkMem.xm if(!m_playBehaviour[kFT2PortaUpDownMemory]) pChn->nOldPortaUp = param; pChn->nOldPortaDown = param; } break; // Tone-Portamento case CMD_TONEPORTAMENTO: if (param) pChn->nPortamentoSlide = param << 2; break; // Offset case CMD_OFFSET: if (param) pChn->oldOffset = param << 8; break; // Volume Slide case CMD_VOLUMESLIDE: case CMD_TONEPORTAVOL: if (param) pChn->nOldVolumeSlide = param; break; // Set Volume case CMD_VOLUME: memory.chnSettings[nChn].vol = param; break; // Global Volume case CMD_GLOBALVOLUME: if(!(GetType() & GLOBALVOL_7BIT_FORMATS) && param < 128) param *= 2; // IT compatibility 16. ST3 and IT ignore out-of-range values if(param <= 128) { playState.m_nGlobalVolume = param * 2; } else if(!(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT | MOD_TYPE_S3M))) { playState.m_nGlobalVolume = 256; } break; // Global Volume Slide case CMD_GLOBALVOLSLIDE: if(m_playBehaviour[kPerChannelGlobalVolSlide]) { // IT compatibility 16. Global volume slide params are stored per channel (FT2/IT) if (param) pChn->nOldGlobalVolSlide = param; else param = pChn->nOldGlobalVolSlide; } else { if (param) playState.Chn[0].nOldGlobalVolSlide = param; else param = playState.Chn[0].nOldGlobalVolSlide; } if (((param & 0x0F) == 0x0F) && (param & 0xF0)) { param >>= 4; if (!(GetType() & GLOBALVOL_7BIT_FORMATS)) param <<= 1; playState.m_nGlobalVolume += param << 1; } else if (((param & 0xF0) == 0xF0) && (param & 0x0F)) { param = (param & 0x0F) << 1; if (!(GetType() & GLOBALVOL_7BIT_FORMATS)) param <<= 1; playState.m_nGlobalVolume -= param; } else if (param & 0xF0) { param >>= 4; param <<= 1; if (!(GetType() & GLOBALVOL_7BIT_FORMATS)) param <<= 1; playState.m_nGlobalVolume += param * nonRowTicks; } else { param = (param & 0x0F) << 1; if (!(GetType() & GLOBALVOL_7BIT_FORMATS)) param <<= 1; playState.m_nGlobalVolume -= param * nonRowTicks; } Limit(playState.m_nGlobalVolume, 0, 256); break; case CMD_CHANNELVOLUME: if (param <= 64) pChn->nGlobalVol = param; break; case CMD_CHANNELVOLSLIDE: { if (param) pChn->nOldChnVolSlide = param; else param = pChn->nOldChnVolSlide; int32 volume = pChn->nGlobalVol; if((param & 0x0F) == 0x0F && (param & 0xF0)) volume += (param >> 4); // Fine Up else if((param & 0xF0) == 0xF0 && (param & 0x0F)) volume -= (param & 0x0F); // Fine Down else if(param & 0x0F) // Down volume -= (param & 0x0F) * nonRowTicks; else // Up volume += ((param & 0xF0) >> 4) * nonRowTicks; Limit(volume, 0, 64); pChn->nGlobalVol = volume; } break; case CMD_PANNING8: Panning(pChn, param, Pan8bit); break; case CMD_MODCMDEX: if(param < 0x10) { // LED filter for(CHANNELINDEX chn = 0; chn < GetNumChannels(); chn++) { playState.Chn[chn].dwFlags.set(CHN_AMIGAFILTER, !(param & 1)); } } MPT_FALLTHROUGH; case CMD_S3MCMDEX: if((param & 0xF0) == 0x80) { Panning(pChn, (param & 0x0F), Pan4bit); } break; case CMD_VIBRATOVOL: if (param) pChn->nOldVolumeSlide = param; param = 0; MPT_FALLTHROUGH; case CMD_VIBRATO: Vibrato(pChn, param); break; case CMD_FINEVIBRATO: FineVibrato(pChn, param); break; case CMD_TREMOLO: Tremolo(pChn, param); break; case CMD_PANBRELLO: Panbrello(pChn, param); break; } switch(pChn->rowCommand.volcmd) { case VOLCMD_PANNING: Panning(pChn, pChn->rowCommand.vol, Pan6bit); break; case VOLCMD_VIBRATOSPEED: // FT2 does not automatically enable vibrato with the "set vibrato speed" command if(m_playBehaviour[kFT2VolColVibrato]) pChn->nVibratoSpeed = pChn->rowCommand.vol & 0x0F; else Vibrato(pChn, pChn->rowCommand.vol << 4); break; case VOLCMD_VIBRATODEPTH: Vibrato(pChn, pChn->rowCommand.vol); break; } // Process vibrato / tremolo / panbrello switch(pChn->rowCommand.command) { case CMD_VIBRATO: case CMD_FINEVIBRATO: case CMD_VIBRATOVOL: if(adjustMode & eAdjust) { uint32 vibTicks = ((GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) && !m_SongFlags[SONG_ITOLDEFFECTS]) ? numTicks : nonRowTicks; uint32 inc = pChn->nVibratoSpeed * vibTicks; if(m_playBehaviour[kITVibratoTremoloPanbrello]) inc *= 4; pChn->nVibratoPos += static_cast(inc); } break; case CMD_TREMOLO: if(adjustMode & eAdjust) { uint32 tremTicks = ((GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) && !m_SongFlags[SONG_ITOLDEFFECTS]) ? numTicks : nonRowTicks; uint32 inc = pChn->nTremoloSpeed * tremTicks; if(m_playBehaviour[kITVibratoTremoloPanbrello]) inc *= 4; pChn->nTremoloPos += static_cast(inc); } break; case CMD_PANBRELLO: if(adjustMode & eAdjust) { // Panbrello effect is permanent in compatible mode, so actually apply panbrello for the last tick of this row pChn->nPanbrelloPos += static_cast(pChn->nPanbrelloSpeed * (numTicks - 1)); ProcessPanbrello(pChn); } break; } } // Interpret F00 effect in XM files as "stop song" if(GetType() == MOD_TYPE_XM && playState.m_nMusicSpeed == uint16_max) { break; } playState.m_nCurrentRowsPerBeat = m_nDefaultRowsPerBeat; if(Patterns[playState.m_nPattern].GetOverrideSignature()) { playState.m_nCurrentRowsPerBeat = Patterns[playState.m_nPattern].GetRowsPerBeat(); } const uint32 tickDuration = GetTickDuration(playState); const uint32 rowDuration = tickDuration * numTicks; memory.elapsedTime += static_cast(rowDuration) / static_cast(m_MixerSettings.gdwMixingFreq); playState.m_lTotalSampleCount += rowDuration; if(adjustSamplePos) { // Super experimental and dirty sample seeking pChn = playState.Chn; for(CHANNELINDEX nChn = 0; nChn < GetNumChannels(); pChn++, nChn++) { if(memory.chnSettings[nChn].ticksToRender == GetLengthMemory::IGNORE_CHANNEL) continue; uint32 startTick = 0; const ModCommand &m = pChn->rowCommand; uint32 paramHi = m.param >> 4, paramLo = m.param & 0x0F; bool porta = m.command == CMD_TONEPORTAMENTO || m.command == CMD_TONEPORTAVOL || m.volcmd == VOLCMD_TONEPORTAMENTO; bool stopNote = patternLoopStartedOnThisRow; // It's too much trouble to keep those pattern loops in sync... if(m.instr) pChn->proTrackerOffset = 0; if(m.IsNote()) { if(porta && memory.chnSettings[nChn].incChanged) { // If there's a portamento, the current channel increment mustn't be 0 in NoteChange() pChn->increment = GetChannelIncrement(pChn, pChn->nPeriod, 0); } int32 setPan = pChn->nPan; pChn->nNewNote = pChn->nLastNote; if(pChn->nNewIns != 0) InstrumentChange(pChn, pChn->nNewIns, porta); NoteChange(pChn, m.note, porta); memory.chnSettings[nChn].incChanged = true; if((m.command == CMD_MODCMDEX || m.command == CMD_S3MCMDEX) && (m.param & 0xF0) == 0xD0 && paramLo < numTicks) { startTick = paramLo; } else if(m.command == CMD_DELAYCUT && paramHi < numTicks) { startTick = paramHi; } if(rowDelay > 1 && startTick != 0 && (GetType() & (MOD_TYPE_S3M | MOD_TYPE_IT | MOD_TYPE_MPT))) { startTick += (playState.m_nMusicSpeed + tickDelay) * (rowDelay - 1); } if(!porta) memory.chnSettings[nChn].ticksToRender = 0; // Panning commands have to be re-applied after a note change with potential pan change. if(m.command == CMD_PANNING8 || ((m.command == CMD_MODCMDEX || m.command == CMD_S3MCMDEX) && paramHi == 0x8) || m.volcmd == VOLCMD_PANNING) { pChn->nPan = setPan; } if(m.command == CMD_OFFSET) { bool isExtended = false; SmpLength offset = CalculateXParam(playState.m_nPattern, playState.m_nRow, nChn, &isExtended); if(!isExtended) { offset <<= 8; if(offset == 0) offset = pChn->oldOffset; offset += static_cast(pChn->nOldHiOffset) << 16; } SampleOffset(*pChn, offset); } else if(m.command == CMD_OFFSETPERCENTAGE) { SampleOffset(*pChn, Util::muldiv_unsigned(pChn->nLength, m.param, 255)); } else if(m.command == CMD_REVERSEOFFSET && pChn->pModSample != nullptr) { memory.RenderChannel(nChn, oldTickDuration); // Re-sync what we've got so far ReverseSampleOffset(*pChn, m.param); startTick = playState.m_nMusicSpeed - 1; } else if(m.volcmd == VOLCMD_OFFSET) { if(m.vol <= CountOf(pChn->pModSample->cues) && pChn->pModSample != nullptr) { SmpLength offset; if(m.vol == 0) offset = pChn->oldOffset; else offset = pChn->oldOffset = pChn->pModSample->cues[m.vol - 1]; SampleOffset(*pChn, offset); } } } if(m.note == NOTE_KEYOFF || m.note == NOTE_NOTECUT || (m.note == NOTE_FADE && GetNumInstruments()) || ((m.command == CMD_MODCMDEX || m.command == CMD_S3MCMDEX) && (m.param & 0xF0) == 0xC0 && paramLo < numTicks) || (m.command == CMD_DELAYCUT && paramLo != 0 && startTick + paramLo < numTicks)) { stopNote = true; } if(m.command == CMD_VOLUME) { pChn->nVolume = m.param * 4; } else if(m.volcmd == VOLCMD_VOLUME) { pChn->nVolume = m.vol * 4; } if(pChn->pModSample && !stopNote) { // Check if we don't want to emulate some effect and thus stop processing. if(m.command < MAX_EFFECTS) { if(forbiddenCommands[m.command]) { stopNote = true; } else if(m.command == CMD_MODCMDEX) { // Special case: Slides using extended commands switch(m.param & 0xF0) { case 0x10: case 0x20: stopNote = true; } } } if(m.volcmd < forbiddenVolCommands.size() && forbiddenVolCommands[m.volcmd]) { stopNote = true; } } if(stopNote) { pChn->Stop(); memory.chnSettings[nChn].ticksToRender = 0; } else { if(oldTickDuration != tickDuration && oldTickDuration != 0) { memory.RenderChannel(nChn, oldTickDuration); // Re-sync what we've got so far } switch(m.command) { case CMD_TONEPORTAVOL: case CMD_VOLUMESLIDE: case CMD_VIBRATOVOL: if(m.param || (GetType() != MOD_TYPE_MOD)) { for(uint32 i = 0; i < numTicks; i++) { pChn->isFirstTick = (i == 0); VolumeSlide(pChn, m.param); } } break; case CMD_MODCMDEX: if((m.param & 0x0F) || (GetType() & (MOD_TYPE_XM | MOD_TYPE_MT2))) { pChn->isFirstTick = true; switch(m.param & 0xF0) { case 0xA0: FineVolumeUp(pChn, m.param & 0x0F, false); break; case 0xB0: FineVolumeDown(pChn, m.param & 0x0F, false); break; } } break; case CMD_S3MCMDEX: if(m.param == 0x9E) { // Play forward memory.RenderChannel(nChn, oldTickDuration); // Re-sync what we've got so far pChn->dwFlags.reset(CHN_PINGPONGFLAG); } else if(m.param == 0x9F) { // Reverse memory.RenderChannel(nChn, oldTickDuration); // Re-sync what we've got so far pChn->dwFlags.set(CHN_PINGPONGFLAG); if(!pChn->position.GetInt() && pChn->nLength && (m.IsNote() || !pChn->dwFlags[CHN_LOOP])) { pChn->position.Set(pChn->nLength - 1, SamplePosition::fractMax); } } else if((m.param & 0xF0) == 0x70) { // TODO //ExtendedS3MCommands(nChn, param); } break; } pChn->isFirstTick = true; switch(m.volcmd) { case VOLCMD_FINEVOLUP: FineVolumeUp(pChn, m.vol, m_playBehaviour[kITVolColMemory]); break; case VOLCMD_FINEVOLDOWN: FineVolumeDown(pChn, m.vol, m_playBehaviour[kITVolColMemory]); break; } if(porta) { // Portamento needs immediate syncing, as the pitch changes on each tick uint32 portaTick = memory.chnSettings[nChn].ticksToRender + startTick + 1; memory.chnSettings[nChn].ticksToRender += numTicks; memory.RenderChannel(nChn, tickDuration, portaTick); } else { memory.chnSettings[nChn].ticksToRender += (numTicks - startTick); } } } } oldTickDuration = tickDuration; // Pattern loop is not executed in FT2 if there are any position jump or pattern break commands on the same row. // Pattern loop is not executed in IT if there are any position jump commands on the same row. // Test case for FT2 exception: PatLoop-Jumps.xm, PatLoop-Various.xm // Test case for IT: exception: LoopBreak.it if(patternLoopEndedOnThisRow && (!m_playBehaviour[kFT2PatternLoopWithJumps] || !(positionJumpOnThisRow || patternBreakOnThisRow)) && (!m_playBehaviour[kITPatternLoopWithJumps] || !positionJumpOnThisRow)) { std::map startTimes; // This is really just a simple estimation for nested pattern loops. It should handle cases correctly where all parallel loops start and end on the same row. // If one of them starts or ends "in between", it will most likely calculate a wrong duration. // For S3M files, it's also way off. pChn = playState.Chn; for(CHANNELINDEX nChn = 0; nChn < GetNumChannels(); nChn++, pChn++) { ModCommand::COMMAND command = pChn->rowCommand.command; ModCommand::PARAM param = pChn->rowCommand.param; if((command == CMD_S3MCMDEX && param >= 0xB1 && param <= 0xBF) || (command == CMD_MODCMDEX && param >= 0x61 && param <= 0x6F)) { const double start = memory.chnSettings[nChn].patLoop; if(!startTimes[start]) startTimes[start] = 1; startTimes[start] = mpt::lcm(startTimes[start], 1 + (param & 0x0F)); } } for(const auto &i : startTimes) { memory.elapsedTime += (memory.elapsedTime - i.first) * (double)(i.second - 1); for(CHANNELINDEX nChn = 0; nChn < GetNumChannels(); nChn++, pChn++) { if(memory.chnSettings[nChn].patLoop == i.first) { playState.m_lTotalSampleCount += (playState.m_lTotalSampleCount - memory.chnSettings[nChn].patLoopSmp) * (i.second - 1); break; } } } if(GetType() == MOD_TYPE_IT) { // IT pattern loop start row update - at the end of a pattern loop, set pattern loop start to next row (for upcoming pattern loops with missing SB0) for(CHANNELINDEX nChn = 0; nChn < GetNumChannels(); nChn++) { if((pChn->rowCommand.command == CMD_S3MCMDEX && pChn->rowCommand.param >= 0xB1 && pChn->rowCommand.param <= 0xBF)) { memory.chnSettings[nChn].patLoop = memory.elapsedTime; memory.chnSettings[nChn].patLoopSmp = playState.m_lTotalSampleCount; } } } } } // Now advance the sample positions for sample seeking on channels that are still playing if(adjustSamplePos) { for(CHANNELINDEX nChn = 0; nChn < GetNumChannels(); nChn++) { if(memory.chnSettings[nChn].ticksToRender != GetLengthMemory::IGNORE_CHANNEL) { memory.RenderChannel(nChn, oldTickDuration); } } } if(retval.targetReached || target.mode == GetLengthTarget::NoTarget) { retval.lastOrder = playState.m_nCurrentOrder; retval.lastRow = playState.m_nRow; } retval.duration = memory.elapsedTime; results.push_back(retval); // Store final variables if(adjustMode & eAdjust) { if(retval.targetReached || target.mode == GetLengthTarget::NoTarget) { // Target found, or there is no target (i.e. play whole song)... m_PlayState = std::move(playState); m_PlayState.m_nNextRow = m_PlayState.m_nRow; m_PlayState.m_nFrameDelay = m_PlayState.m_nPatternDelay = 0; m_PlayState.m_nTickCount = Util::MaxValueOfType(m_PlayState.m_nTickCount) - 1; m_PlayState.m_bPositionChanged = true; for(CHANNELINDEX n = 0; n < GetNumChannels(); n++) { if(m_PlayState.Chn[n].nLastNote != NOTE_NONE) { m_PlayState.Chn[n].nNewNote = m_PlayState.Chn[n].nLastNote; } if(memory.chnSettings[n].vol != 0xFF && !adjustSamplePos) { m_PlayState.Chn[n].nVolume = std::min(memory.chnSettings[n].vol, uint8(64)) * 4; } } #ifndef NO_PLUGINS // If there were any PC events, update plugin parameters to their latest value. std::bitset plugSetProgram; for(const auto ¶m : memory.plugParams) { PLUGINDEX plug = param.first.first - 1; IMixPlugin *plugin = m_MixPlugins[plug].pMixPlugin; if(plugin != nullptr) { if(!plugSetProgram[plug]) { // Used for bridged plugins to avoid sending out individual messages for each parameter. plugSetProgram.set(plug); plugin->BeginSetProgram(); } plugin->SetParameter(param.first.second, param.second / PlugParamValue(ModCommand::maxColumnValue)); } } if(plugSetProgram.any()) { for(PLUGINDEX i = 0; i < MAX_MIXPLUGINS; i++) { if(plugSetProgram[i]) { m_MixPlugins[i].pMixPlugin->EndSetProgram(); } } } #endif // NO_PLUGINS } else if(adjustMode != eAdjustOnSuccess) { // Target not found (e.g. when jumping to a hidden sub song), reset global variables... m_PlayState.m_nMusicSpeed = m_nDefaultSpeed; m_PlayState.m_nMusicTempo = m_nDefaultTempo; m_PlayState.m_nGlobalVolume = m_nDefaultGlobalVolume; } // When adjusting the playback status, we will also want to update the visited rows vector according to the current position. if(sequence != Order.GetCurrentSequenceIndex()) { Order.SetSequence(sequence); } visitedSongRows.Set(visitedRows); } return results; } ////////////////////////////////////////////////////////////////////////////////////////////////// // Effects // Change sample or instrument number. void CSoundFile::InstrumentChange(ModChannel *pChn, uint32 instr, bool bPorta, bool bUpdVol, bool bResetEnv) const { const ModInstrument *pIns = instr <= GetNumInstruments() ? Instruments[instr] : nullptr; const ModSample *pSmp = &Samples[instr]; ModCommand::NOTE note = pChn->nNewNote; if(note == NOTE_NONE && m_playBehaviour[kITInstrWithoutNote]) return; if(pIns != nullptr && ModCommand::IsNote(note)) { // Impulse Tracker ignores empty slots. // We won't ignore them if a plugin is assigned to this slot, so that VSTis still work as intended. // Test case: emptyslot.it, PortaInsNum.it, gxsmp.it, gxsmp2.it if(pIns->Keyboard[note - NOTE_MIN] == 0 && m_playBehaviour[kITEmptyNoteMapSlot] && !pIns->HasValidMIDIChannel()) { pChn->pModInstrument = pIns; return; } if(pIns->NoteMap[note - NOTE_MIN] > NOTE_MAX) return; uint32 n = pIns->Keyboard[note - NOTE_MIN]; pSmp = ((n) && (n < MAX_SAMPLES)) ? &Samples[n] : nullptr; } else if(GetNumInstruments()) { // No valid instrument, or not a valid note. if (note >= NOTE_MIN_SPECIAL) return; if(m_playBehaviour[kITEmptyNoteMapSlot] && (pIns == nullptr || !pIns->HasValidMIDIChannel())) { // Impulse Tracker ignores empty slots. // We won't ignore them if a plugin is assigned to this slot, so that VSTis still work as intended. // Test case: emptyslot.it, PortaInsNum.it, gxsmp.it, gxsmp2.it pChn->pModInstrument = nullptr; pChn->nNewIns = 0; return; } pSmp = nullptr; } bool returnAfterVolumeAdjust = false; // instrumentChanged is used for IT carry-on env option bool instrumentChanged = (pIns != pChn->pModInstrument); const bool sampleChanged = (pChn->pModSample != nullptr) && (pSmp != pChn->pModSample); const bool newTuning = (GetType() == MOD_TYPE_MPT && pIns && pIns->pTuning); // Playback behavior change for MPT: With portamento don't change sample if it is in // the same instrument as previous sample. if(bPorta && newTuning && pIns == pChn->pModInstrument && sampleChanged) return; if(sampleChanged && bPorta) { // IT compatibility: No sample change (also within multi-sample instruments) during portamento when using Compatible Gxx. // Test case: PortaInsNumCompat.it, PortaSampleCompat.it, PortaCutCompat.it if(m_playBehaviour[kITPortamentoInstrument] && m_SongFlags[SONG_ITCOMPATGXX] && pChn->nLength != 0) { pSmp = pChn->pModSample; } // Special XM hack (also applies to MOD / S3M, except when playing IT-style S3Ms, such as k_vision.s3m) // Test case: PortaSmpChange.mod, PortaSmpChange.s3m if((!instrumentChanged && (GetType() & (MOD_TYPE_XM | MOD_TYPE_MT2)) && pIns) || (GetType() == MOD_TYPE_PLM) || (GetType() == MOD_TYPE_MOD && pChn->IsSamplePlaying()) || m_playBehaviour[kST3PortaSampleChange]) { // FT2 doesn't change the sample in this case, // but still uses the sample info from the old one (bug?) returnAfterVolumeAdjust = true; } } // IT compatibility: A lone instrument number should only reset sample properties to those of the corresponding sample in instrument mode. // C#5 01 ... <-- sample 1 // C-5 .. g02 <-- sample 2 // ... 01 ... <-- still sample 1, but with properties of sample 2 // In the above example, no sample change happens on the second row. In the third row, sample 1 keeps playing but with the // volume and panning properties of sample 2. // Test case: InstrAfterMultisamplePorta.it if(m_nInstruments && !instrumentChanged && sampleChanged && pChn->pCurrentSample != nullptr && m_playBehaviour[kITMultiSampleInstrumentNumber] && !pChn->rowCommand.IsNote()) { returnAfterVolumeAdjust = true; } // IT Compatibility: Envelope pickup after SCx cut (but don't do this when working with plugins, or else envelope carry stops working) // Test case: cut-carry.it if(!pChn->IsSamplePlaying() && (GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) && (!pIns || !pIns->HasValidMIDIChannel())) { instrumentChanged = true; } // FT2 compatibility: new instrument + portamento = ignore new instrument number, but reload old instrument settings (the world of XM is upside down...) // And this does *not* happen if volume column portamento is used together with note delay... (handled in ProcessEffects(), where all the other note delay stuff is.) // Test case: porta-delay.xm if(instrumentChanged && bPorta && m_playBehaviour[kFT2PortaIgnoreInstr] && (pChn->pModInstrument != nullptr || pChn->pModSample != nullptr)) { pIns = pChn->pModInstrument; pSmp = pChn->pModSample; instrumentChanged = false; } else { pChn->pModInstrument = pIns; } // Update Volume if (bUpdVol && (!(GetType() & (MOD_TYPE_MOD | MOD_TYPE_S3M)) || ((pSmp != nullptr && pSmp->pSample != nullptr) || pChn->HasMIDIOutput()))) { if(pSmp) { if(!pSmp->uFlags[SMP_NODEFAULTVOLUME]) pChn->nVolume = pSmp->nVolume; } else if(pIns && pIns->nMixPlug) { pChn->nVolume = pChn->GetVSTVolume(); } else { pChn->nVolume = 0; } } if(returnAfterVolumeAdjust && sampleChanged && m_playBehaviour[kMODSampleSwap] && pSmp != nullptr) { // ProTracker applies new instrument's finetune but keeps the old sample playing. // Test case: PortaSwapPT.mod pChn->nFineTune = pSmp->nFineTune; } if(returnAfterVolumeAdjust) return; // Instrument adjust pChn->nNewIns = 0; // IT Compatiblity: NNA is reset on every note change, not every instrument change (fixes s7xinsnum.it). if (pIns && ((!m_playBehaviour[kITNNAReset] && pSmp) || pIns->nMixPlug)) pChn->nNNA = pIns->nNNA; // Update volume pChn->UpdateInstrumentVolume(pSmp, pIns); // Update panning // FT2 compatibility: Only reset panning on instrument numbers, not notes (bUpdVol condition) // Test case: PanMemory.xm // IT compatibility: Sample and instrument panning is only applied on note change, not instrument change // Test case: PanReset.it if((bUpdVol || !(GetType() & (MOD_TYPE_XM | MOD_TYPE_MT2))) && !m_playBehaviour[kITPanningReset]) { ApplyInstrumentPanning(pChn, pIns, pSmp); } // Reset envelopes if(bResetEnv) { // Blurb by Storlek (from the SchismTracker code): // Conditions experimentally determined to cause envelope reset in Impulse Tracker: // - no note currently playing (of course) // - note given, no portamento // - instrument number given, portamento, compat gxx enabled // - instrument number given, no portamento, after keyoff, old effects enabled // If someone can enlighten me to what the logic really is here, I'd appreciate it. // Seems like it's just a total mess though, probably to get XMs to play right. bool reset, resetAlways; // IT Compatibility: Envelope reset // Test case: EnvReset.it if(m_playBehaviour[kITEnvelopeReset]) { const bool insNumber = (instr != 0); reset = (!pChn->nLength || (insNumber && bPorta && m_SongFlags[SONG_ITCOMPATGXX]) || (insNumber && !bPorta && pChn->dwFlags[CHN_NOTEFADE | CHN_KEYOFF] && m_SongFlags[SONG_ITOLDEFFECTS])); // NOTE: IT2.14 with SB/GUS/etc. output is different. We are going after IT's WAV writer here. // For SB/GUS/etc. emulation, envelope carry should only apply when the NNA isn't set to "Note Cut". // Test case: CarryNNA.it resetAlways = (!pChn->nFadeOutVol || instrumentChanged || pChn->dwFlags[CHN_KEYOFF]); } else { reset = (!bPorta || !(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT | MOD_TYPE_DBM)) || m_SongFlags[SONG_ITCOMPATGXX] || !pChn->nLength || (pChn->dwFlags[CHN_NOTEFADE] && !pChn->nFadeOutVol)); resetAlways = !(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT | MOD_TYPE_DBM)) || instrumentChanged || pIns == nullptr || pChn->dwFlags[CHN_KEYOFF | CHN_NOTEFADE]; } if(reset) { pChn->dwFlags.set(CHN_FASTVOLRAMP); if(pIns != nullptr) { if(resetAlways) { pChn->ResetEnvelopes(); } else { if(!pIns->VolEnv.dwFlags[ENV_CARRY]) pChn->VolEnv.Reset(); if(!pIns->PanEnv.dwFlags[ENV_CARRY]) pChn->PanEnv.Reset(); if(!pIns->PitchEnv.dwFlags[ENV_CARRY]) pChn->PitchEnv.Reset(); } } // IT Compatibility: Autovibrato reset if(!m_playBehaviour[kITVibratoTremoloPanbrello]) { pChn->nAutoVibDepth = 0; pChn->nAutoVibPos = 0; } } else if(pIns != nullptr && !pIns->VolEnv.dwFlags[ENV_ENABLED]) { if(m_playBehaviour[kITPortamentoInstrument]) { pChn->VolEnv.Reset(); } else { pChn->ResetEnvelopes(); } } } // Invalid sample ? if(pSmp == nullptr && (pIns == nullptr || !pIns->HasValidMIDIChannel())) { pChn->pModSample = nullptr; pChn->nInsVol = 0; return; } // Tone-Portamento doesn't reset the pingpong direction flag if(bPorta && pSmp == pChn->pModSample && pSmp != nullptr) { // If channel length is 0, we cut a previous sample using SCx. In that case, we have to update sample length, loop points, etc... if(GetType() & (MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_MPT) && pChn->nLength != 0) return; pChn->dwFlags.reset(CHN_KEYOFF | CHN_NOTEFADE); pChn->dwFlags = (pChn->dwFlags & (CHN_CHANNELFLAGS | CHN_PINGPONGFLAG)); } else //if(!instrumentChanged || pChn->rowCommand.instr != 0 || !IsCompatibleMode(TRK_FASTTRACKER2)) // SampleChange.xm? { pChn->dwFlags.reset(CHN_KEYOFF | CHN_NOTEFADE); // IT compatibility tentative fix: Don't change bidi loop direction when // no sample nor instrument is changed. if((m_playBehaviour[kITPingPongNoReset] || !(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT))) && pSmp == pChn->pModSample && !instrumentChanged) pChn->dwFlags = (pChn->dwFlags & (CHN_CHANNELFLAGS | CHN_PINGPONGFLAG)); else pChn->dwFlags = (pChn->dwFlags & CHN_CHANNELFLAGS); if(pIns) { // Copy envelope flags (we actually only need the "enabled" and "pitch" flag) pChn->VolEnv.flags = pIns->VolEnv.dwFlags; pChn->PanEnv.flags = pIns->PanEnv.dwFlags; pChn->PitchEnv.flags = pIns->PitchEnv.dwFlags; // A cutoff frequency of 0 should not be reset just because the filter envelope is enabled. // Test case: FilterEnvReset.it if((pIns->PitchEnv.dwFlags & (ENV_ENABLED | ENV_FILTER)) == (ENV_ENABLED | ENV_FILTER) && !m_playBehaviour[kITFilterBehaviour]) { if(!pChn->nCutOff) pChn->nCutOff = 0x7F; } if(pIns->IsCutoffEnabled()) pChn->nCutOff = pIns->GetCutoff(); if(pIns->IsResonanceEnabled()) pChn->nResonance = pIns->GetResonance(); } } if(pSmp == nullptr) { pChn->pModSample = nullptr; pChn->nLength = 0; return; } if(bPorta && pChn->nLength == 0 && (m_playBehaviour[kFT2PortaNoNote] || m_playBehaviour[kITPortaNoNote])) { // IT/FT2 compatibility: If the note just stopped on the previous tick, prevent it from restarting. // Test cases: PortaJustStoppedNote.xm, PortaJustStoppedNote.it pChn->increment.Set(0); } pChn->pModSample = pSmp; pChn->nLength = pSmp->nLength; pChn->nLoopStart = pSmp->nLoopStart; pChn->nLoopEnd = pSmp->nLoopEnd; // ProTracker "oneshot" loops (if loop start is 0, play the whole sample once and then repeat until loop end) if(m_playBehaviour[kMODOneShotLoops] && pChn->nLoopStart == 0) pChn->nLoopEnd = pSmp->nLength; pChn->dwFlags |= (pSmp->uFlags & (CHN_SAMPLEFLAGS | CHN_SURROUND)); // IT Compatibility: Autovibrato reset if(m_playBehaviour[kITVibratoTremoloPanbrello]) { pChn->nAutoVibDepth = 0; pChn->nAutoVibPos = 0; } if(newTuning) { pChn->nC5Speed = pSmp->nC5Speed; pChn->m_CalculateFreq = true; pChn->nFineTune = 0; } else if(!bPorta || sampleChanged || !(GetType() & (MOD_TYPE_MOD | MOD_TYPE_XM))) { // Don't reset finetune changed by "set finetune" command. // Test case: finetune.xm, finetune.mod // But *do* change the finetune if we switch to a different sample, to fix // Miranda`s axe by Jamson (jam007.xm) - this file doesn't use compatible play mode, // so we may want to use IsCompatibleMode instead if further problems arise. pChn->nC5Speed = pSmp->nC5Speed; pChn->nFineTune = pSmp->nFineTune; } pChn->nTranspose = pSmp->RelativeTone; // FT2 compatibility: Don't reset portamento target with new instrument numbers. // Test case: Porta-Pickup.xm // ProTracker does the same. // Test case: PortaTarget.mod if(!m_playBehaviour[kFT2PortaTargetNoReset] && GetType() != MOD_TYPE_MOD) { pChn->nPortamentoDest = 0; } pChn->m_PortamentoFineSteps = 0; if(pChn->dwFlags[CHN_SUSTAINLOOP]) { pChn->nLoopStart = pSmp->nSustainStart; pChn->nLoopEnd = pSmp->nSustainEnd; if(pChn->dwFlags[CHN_PINGPONGSUSTAIN]) pChn->dwFlags.set(CHN_PINGPONGLOOP); pChn->dwFlags.set(CHN_LOOP); } if(pChn->dwFlags[CHN_LOOP] && pChn->nLoopEnd < pChn->nLength) pChn->nLength = pChn->nLoopEnd; // Fix sample position on instrument change. This is needed for IT "on the fly" sample change. // XXX is this actually called? In ProcessEffects(), a note-on effect is emulated if there's an on the fly sample change! if(pChn->position.GetUInt() >= pChn->nLength) { if((GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT))) { pChn->position.Set(0); } } } void CSoundFile::NoteChange(ModChannel *pChn, int note, bool bPorta, bool bResetEnv, bool bManual) const { if (note < NOTE_MIN) return; const ModSample *pSmp = pChn->pModSample; const ModInstrument *pIns = pChn->pModInstrument; const bool newTuning = (GetType() == MOD_TYPE_MPT && pIns != nullptr && pIns->pTuning); // save the note that's actually used, as it's necessary to properly calculate PPS and stuff const int realnote = note; if((pIns) && (note - NOTE_MIN < (int)CountOf(pIns->Keyboard))) { uint32 n = pIns->Keyboard[note - NOTE_MIN]; if((n) && (n < MAX_SAMPLES)) { pSmp = &Samples[n]; } else if(m_playBehaviour[kITEmptyNoteMapSlot] && !pChn->HasMIDIOutput()) { // Impulse Tracker ignores empty slots. // We won't ignore them if a plugin is assigned to this slot, so that VSTis still work as intended. // Test case: emptyslot.it, PortaInsNum.it, gxsmp.it, gxsmp2.it return; } note = pIns->NoteMap[note - NOTE_MIN]; } // Key Off if(note > NOTE_MAX) { // Key Off (+ Invalid Note for XM - TODO is this correct?) if(note == NOTE_KEYOFF || !(GetType() & (MOD_TYPE_IT|MOD_TYPE_MPT))) { KeyOff(pChn); } else // Invalid Note -> Note Fade { if(/*note == NOTE_FADE && */ GetNumInstruments()) pChn->dwFlags.set(CHN_NOTEFADE); } // Note Cut if (note == NOTE_NOTECUT) { pChn->dwFlags.set(CHN_NOTEFADE | CHN_FASTVOLRAMP); // IT compatibility: Stopping sample playback by setting sample increment to 0 rather than volume // Test case: NoteOffInstr.it if ((!(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT))) || (m_nInstruments != 0 && !m_playBehaviour[kITInstrWithNoteOff])) pChn->nVolume = 0; if(m_playBehaviour[kITInstrWithNoteOff]) pChn->increment.Set(0); pChn->nFadeOutVol = 0; } // IT compatibility tentative fix: Clear channel note memory. if(m_playBehaviour[kITClearOldNoteAfterCut]) { pChn->nNote = pChn->nNewNote = NOTE_NONE; } return; } if(newTuning) { if(!bPorta || pChn->nNote == NOTE_NONE) pChn->nPortamentoDest = 0; else { pChn->nPortamentoDest = pIns->pTuning->GetStepDistance(pChn->nNote, pChn->m_PortamentoFineSteps, static_cast(note), 0); //Here pChn->nPortamentoDest means 'steps to slide'. pChn->m_PortamentoFineSteps = -pChn->nPortamentoDest; } } if(!bPorta && (GetType() & (MOD_TYPE_XM | MOD_TYPE_MED | MOD_TYPE_MT2))) { if(pSmp) { pChn->nTranspose = pSmp->RelativeTone; pChn->nFineTune = pSmp->nFineTune; } } // IT Compatibility: Update multisample instruments frequency even if instrument is not specified (fixes the guitars in spx-shuttledeparture.it) // Test case: freqreset-noins.it if(!bPorta && pSmp && m_playBehaviour[kITMultiSampleBehaviour]) pChn->nC5Speed = pSmp->nC5Speed; if(bPorta && !pChn->IsSamplePlaying()) { if(m_playBehaviour[kFT2PortaNoNote]) { // FT2 Compatibility: Ignore notes with portamento if there was no note playing. // Test case: 3xx-no-old-samp.xm pChn->nPeriod = 0; return; } else if(m_playBehaviour[kITPortaNoNote]) { // IT Compatibility: Ignore portamento command if no note was playing (e.g. if a previous note has faded out). // Test case: Fade-Porta.it bPorta = false; } } if(GetType() & (MOD_TYPE_XM|MOD_TYPE_MT2|MOD_TYPE_MED|MOD_TYPE_MOD)) { note += pChn->nTranspose; // RealNote = PatternNote + RelativeTone; (0..118, 0 = C-0, 118 = A#9) Limit(note, NOTE_MIN + 11, NOTE_MIN + 130); // 119 possible notes } else { Limit(note, NOTE_MIN, NOTE_MAX); } if(m_playBehaviour[kITRealNoteMapping]) { // need to memorize the original note for various effects (e.g. PPS) pChn->nNote = static_cast(Clamp(realnote, NOTE_MIN, NOTE_MAX)); } else { pChn->nNote = static_cast(note); } pChn->m_CalculateFreq = true; if ((!bPorta) || (GetType() & (MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_MPT))) pChn->nNewIns = 0; uint32 period = GetPeriodFromNote(note, pChn->nFineTune, pChn->nC5Speed); pChn->nPanbrelloOffset = 0; // IT compatibility: Sample and instrument panning is only applied on note change, not instrument change // Test case: PanReset.it if(m_playBehaviour[kITPanningReset]) ApplyInstrumentPanning(pChn, pIns, pSmp); if(bResetEnv && !bPorta) { pChn->nVolSwing = pChn->nPanSwing = 0; pChn->nResSwing = pChn->nCutSwing = 0; if(pIns) { // IT Compatiblity: NNA is reset on every note change, not every instrument change (fixes spx-farspacedance.it). if(m_playBehaviour[kITNNAReset]) pChn->nNNA = pIns->nNNA; if(!pIns->VolEnv.dwFlags[ENV_CARRY]) pChn->VolEnv.Reset(); if(!pIns->PanEnv.dwFlags[ENV_CARRY]) pChn->PanEnv.Reset(); if(!pIns->PitchEnv.dwFlags[ENV_CARRY]) pChn->PitchEnv.Reset(); // Volume Swing if(pIns->nVolSwing) { pChn->nVolSwing = static_cast(((mpt::random(AccessPRNG()) * pIns->nVolSwing) / 64 + 1) * (m_playBehaviour[kITSwingBehaviour] ? pChn->nInsVol : ((pChn->nVolume + 1) / 2)) / 199); } // Pan Swing if(pIns->nPanSwing) { pChn->nPanSwing = static_cast(((mpt::random(AccessPRNG()) * pIns->nPanSwing * 4) / 128)); if(!m_playBehaviour[kITSwingBehaviour]) { pChn->nRestorePanOnNewNote = static_cast(pChn->nPan + 1); } } // Cutoff Swing if(pIns->nCutSwing) { int32 d = ((int32)pIns->nCutSwing * (int32)(static_cast(mpt::random(AccessPRNG())) + 1)) / 128; pChn->nCutSwing = static_cast((d * pChn->nCutOff + 1) / 128); pChn->nRestoreCutoffOnNewNote = pChn->nCutOff + 1; } // Resonance Swing if(pIns->nResSwing) { int32 d = ((int32)pIns->nResSwing * (int32)(static_cast(mpt::random(AccessPRNG())) + 1)) / 128; pChn->nResSwing = static_cast((d * pChn->nResonance + 1) / 128); pChn->nRestoreResonanceOnNewNote = pChn->nResonance + 1; } } } if(!pSmp) return; if(period) { if((!bPorta) || (!pChn->nPeriod)) pChn->nPeriod = period; if(!newTuning) { // FT2 compatibility: Don't reset portamento target with new notes. // Test case: Porta-Pickup.xm // ProTracker does the same. // Test case: PortaTarget.mod // IT compatibility: Portamento target is completely cleared with new notes. // Test case: PortaReset.it if(bPorta || !(m_playBehaviour[kFT2PortaTargetNoReset] || m_playBehaviour[kITClearPortaTarget] || GetType() == MOD_TYPE_MOD)) { pChn->nPortamentoDest = period; } } if(!bPorta || (!pChn->nLength && !(GetType() & MOD_TYPE_S3M))) { pChn->pModSample = pSmp; pChn->nLength = pSmp->nLength; pChn->nLoopEnd = pSmp->nLength; pChn->nLoopStart = 0; pChn->position.Set(0); if(m_SongFlags[SONG_PT_MODE] && !pChn->rowCommand.instr) { pChn->position.SetInt(std::min(pChn->proTrackerOffset, pChn->nLength - 1)); } else { pChn->proTrackerOffset = 0; } pChn->dwFlags = (pChn->dwFlags & CHN_CHANNELFLAGS) | (pSmp->uFlags & (CHN_SAMPLEFLAGS | CHN_SURROUND)); pChn->dwFlags.reset(CHN_PORTAMENTO); if(pChn->dwFlags[CHN_SUSTAINLOOP]) { pChn->nLoopStart = pSmp->nSustainStart; pChn->nLoopEnd = pSmp->nSustainEnd; pChn->dwFlags.set(CHN_PINGPONGLOOP, pChn->dwFlags[CHN_PINGPONGSUSTAIN]); pChn->dwFlags.set(CHN_LOOP); if (pChn->nLength > pChn->nLoopEnd) pChn->nLength = pChn->nLoopEnd; } else if(pChn->dwFlags[CHN_LOOP]) { pChn->nLoopStart = pSmp->nLoopStart; pChn->nLoopEnd = pSmp->nLoopEnd; if (pChn->nLength > pChn->nLoopEnd) pChn->nLength = pChn->nLoopEnd; } // ProTracker "oneshot" loops (if loop start is 0, play the whole sample once and then repeat until loop end) if(m_playBehaviour[kMODOneShotLoops] && pChn->nLoopStart == 0) pChn->nLoopEnd = pChn->nLength = pSmp->nLength; if(pChn->dwFlags[CHN_REVERSE]) { pChn->dwFlags.set(CHN_PINGPONGFLAG); pChn->position.SetInt(pChn->nLength - 1); } // Handle "retrigger" waveform type if(pChn->nVibratoType < 4) { // IT Compatibilty: Slightly different waveform offsets (why does MPT have two different offsets here with IT old effects enabled and disabled?) if(!m_playBehaviour[kITVibratoTremoloPanbrello] && (GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) && !m_SongFlags[SONG_ITOLDEFFECTS]) pChn->nVibratoPos = 0x10; else if(GetType() == MOD_TYPE_MTM) pChn->nVibratoPos = 0x20; else if(!(GetType() & (MOD_TYPE_DIGI | MOD_TYPE_DBM))) pChn->nVibratoPos = 0; } // IT Compatibility: No "retrigger" waveform here if(!m_playBehaviour[kITVibratoTremoloPanbrello] && pChn->nTremoloType < 4) { pChn->nTremoloPos = 0; } } if(pChn->position.GetUInt() >= pChn->nLength) pChn->position.SetInt(pChn->nLoopStart); } else { bPorta = false; } if (!bPorta || (!(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT | MOD_TYPE_DBM))) || (pChn->dwFlags[CHN_NOTEFADE] && !pChn->nFadeOutVol) || (m_SongFlags[SONG_ITCOMPATGXX] && pChn->rowCommand.instr != 0)) { if((GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT | MOD_TYPE_DBM)) && pChn->dwFlags[CHN_NOTEFADE] && !pChn->nFadeOutVol) { pChn->ResetEnvelopes(); // IT Compatibility: Autovibrato reset if(!m_playBehaviour[kITVibratoTremoloPanbrello]) { pChn->nAutoVibDepth = 0; pChn->nAutoVibPos = 0; } pChn->dwFlags.reset(CHN_NOTEFADE); pChn->nFadeOutVol = 65536; } if ((!bPorta) || (!m_SongFlags[SONG_ITCOMPATGXX]) || (pChn->rowCommand.instr)) { if ((!(GetType() & (MOD_TYPE_XM|MOD_TYPE_MT2))) || (pChn->rowCommand.instr)) { pChn->dwFlags.reset(CHN_NOTEFADE); pChn->nFadeOutVol = 65536; } } } // IT compatibility: Don't reset key-off flag on porta notes unless Compat Gxx is enabled // Test case: Off-Porta.it, Off-Porta-CompatGxx.it if(m_playBehaviour[kITDontResetNoteOffOnPorta] && bPorta && (!m_SongFlags[SONG_ITCOMPATGXX] || pChn->rowCommand.instr == 0)) pChn->dwFlags.reset(CHN_EXTRALOUD); else pChn->dwFlags.reset(CHN_EXTRALOUD | CHN_KEYOFF); // Enable Ramping if(!bPorta) { pChn->nLeftVU = pChn->nRightVU = 0xFF; pChn->dwFlags.reset(CHN_FILTER); pChn->dwFlags.set(CHN_FASTVOLRAMP); // IT compatibility 15. Retrigger is reset in RetrigNote (Tremor doesn't store anything here, so we just don't reset this as well) if(!m_playBehaviour[kITRetrigger] && !m_playBehaviour[kITTremor]) { // FT2 compatibility: Retrigger is reset in RetrigNote, tremor in ProcessEffects if(!m_playBehaviour[kFT2Retrigger] && !m_playBehaviour[kFT2Tremor]) { pChn->nRetrigCount = 0; pChn->nTremorCount = 0; } } if(bResetEnv) { pChn->nAutoVibDepth = 0; pChn->nAutoVibPos = 0; } pChn->rightVol = pChn->leftVol = 0; bool useFilter = !m_SongFlags[SONG_MPTFILTERMODE]; // Setup Initial Filter for this note if(pIns) { if(pIns->IsResonanceEnabled()) { pChn->nResonance = pIns->GetResonance(); useFilter = true; } if(pIns->IsCutoffEnabled()) { pChn->nCutOff = pIns->GetCutoff(); useFilter = true; } if(useFilter && (pIns->nFilterMode != FLTMODE_UNCHANGED)) { pChn->nFilterMode = pIns->nFilterMode; } } else { pChn->nVolSwing = pChn->nPanSwing = 0; pChn->nCutSwing = pChn->nResSwing = 0; } if((pChn->nCutOff < 0x7F || m_playBehaviour[kITFilterBehaviour]) && useFilter) { SetupChannelFilter(pChn, true); } } // Special case for MPT if (bManual) pChn->dwFlags.reset(CHN_MUTE); if((pChn->dwFlags[CHN_MUTE] && (m_MixerSettings.MixerFlags & SNDMIX_MUTECHNMODE)) || (pChn->pModSample != nullptr && pChn->pModSample->uFlags[CHN_MUTE] && !bManual) || (pChn->pModInstrument != nullptr && pChn->pModInstrument->dwFlags[INS_MUTE] && !bManual)) { if (!bManual) pChn->nPeriod = 0; } // Reset the Amiga resampler for this channel if(!bPorta) { pChn->paulaState.Reset(); } } // Apply sample or instrumernt panning void CSoundFile::ApplyInstrumentPanning(ModChannel *pChn, const ModInstrument *instr, const ModSample *smp) const { int32 newPan = int32_min; // Default instrument panning if(instr != nullptr && instr->dwFlags[INS_SETPANNING]) newPan = instr->nPan; // Default sample panning if(smp != nullptr && smp->uFlags[CHN_PANNING]) newPan = smp->nPan; if(newPan != int32_min) { pChn->nPan = newPan; // IT compatibility: Sample and instrument panning overrides channel surround status. // Test case: SmpInsPanSurround.it if(m_playBehaviour[kPanOverride] && !m_SongFlags[SONG_SURROUNDPAN]) { pChn->dwFlags.reset(CHN_SURROUND); } } } CHANNELINDEX CSoundFile::GetNNAChannel(CHANNELINDEX nChn) const { const ModChannel *pChn = &m_PlayState.Chn[nChn]; // Check for empty channel const ModChannel *pi = &m_PlayState.Chn[m_nChannels]; for (CHANNELINDEX i = m_nChannels; i < MAX_CHANNELS; i++, pi++) if (!pi->nLength) return i; if (!pChn->nFadeOutVol) return 0; // All channels are used: check for lowest volume CHANNELINDEX result = 0; uint32 vol = (1u << (14 + 9)) / 4u; // 25% uint32 envpos = uint32_max; const ModChannel *pj = &m_PlayState.Chn[m_nChannels]; for (CHANNELINDEX j = m_nChannels; j < MAX_CHANNELS; j++, pj++) { if (!pj->nFadeOutVol) return j; // Use a combination of real volume [14 bit] (which includes volume envelopes, but also potentially global volume) and note volume [9 bit]. // Rationale: We need volume envelopes in case e.g. all NNA channels are playing at full volume but are looping on a 0-volume envelope node. // But if global volume is not applied to master and the global volume temporarily drops to 0, we would kill arbitrary channels. Hence, add the note volume as well. uint32 v = (pj->nRealVolume << 9) | pj->nVolume; if(pj->dwFlags[CHN_LOOP]) v >>= 1; if ((v < vol) || ((v == vol) && (pj->VolEnv.nEnvPosition > envpos))) { envpos = pj->VolEnv.nEnvPosition; vol = v; result = j; } } return result; } CHANNELINDEX CSoundFile::CheckNNA(CHANNELINDEX nChn, uint32 instr, int note, bool forceCut) { CHANNELINDEX nnaChn = CHANNELINDEX_INVALID; ModChannel &srcChn = m_PlayState.Chn[nChn]; const ModInstrument *pIns = nullptr; if(!ModCommand::IsNote(static_cast(note))) { return nnaChn; } // Always NNA cut - using if((!(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT | MOD_TYPE_MT2)) || !m_nInstruments || forceCut) && !srcChn.HasMIDIOutput()) { if(!srcChn.nLength || srcChn.dwFlags[CHN_MUTE] || !(srcChn.rightVol | srcChn.leftVol)) { return CHANNELINDEX_INVALID; } nnaChn = GetNNAChannel(nChn); if(!nnaChn) return CHANNELINDEX_INVALID; ModChannel &chn = m_PlayState.Chn[nnaChn]; // Copy Channel chn = srcChn; chn.dwFlags.reset(CHN_VIBRATO | CHN_TREMOLO | CHN_MUTE | CHN_PORTAMENTO); chn.nPanbrelloOffset = 0; chn.nMasterChn = nChn + 1; chn.nCommand = CMD_NONE; chn.rowCommand.Clear(); // Cut the note chn.nFadeOutVol = 0; chn.dwFlags.set(CHN_NOTEFADE | CHN_FASTVOLRAMP); // Stop this channel srcChn.nLength = 0; srcChn.position.Set(0); srcChn.nROfs = srcChn.nLOfs = 0; srcChn.rightVol = srcChn.leftVol = 0; return nnaChn; } if(instr > GetNumInstruments()) instr = 0; const ModSample *pSample = srcChn.pModSample; // If no instrument is given, assume previous instrument to still be valid. // Test case: DNA-NoInstr.it pIns = instr > 0 ? Instruments[instr] : srcChn.pModInstrument; if(pIns != nullptr) { uint32 n = pIns->Keyboard[note - NOTE_MIN]; note = pIns->NoteMap[note - NOTE_MIN]; if ((n) && (n < MAX_SAMPLES)) { pSample = &Samples[n]; } else if(m_playBehaviour[kITEmptyNoteMapSlot] && !pIns->HasValidMIDIChannel()) { // Impulse Tracker ignores empty slots. // We won't ignore them if a plugin is assigned to this slot, so that VSTis still work as intended. // Test case: emptyslot.it, PortaInsNum.it, gxsmp.it, gxsmp2.it return CHANNELINDEX_INVALID; } } if (srcChn.dwFlags[CHN_MUTE]) return CHANNELINDEX_INVALID; bool applyDNAtoPlug; //rewbs.VSTiNNA for(CHANNELINDEX i = nChn; i < MAX_CHANNELS; i++) if(i >= m_nChannels || i == nChn) { ModChannel &chn = m_PlayState.Chn[i]; applyDNAtoPlug = false; //rewbs.VSTiNNA if((chn.nMasterChn == nChn + 1 || i == nChn) && chn.pModInstrument != nullptr) { bool bOk = false; // Duplicate Check Type switch(chn.pModInstrument->nDCT) { // Note case DCT_NOTE: if(note && chn.nNote == note && pIns == chn.pModInstrument) bOk = true; if(pIns && pIns->nMixPlug) applyDNAtoPlug = true; //rewbs.VSTiNNA break; // Sample case DCT_SAMPLE: if(pSample != nullptr && pSample == chn.pModSample) bOk = true; break; // Instrument case DCT_INSTRUMENT: if(pIns == chn.pModInstrument) bOk = true; //rewbs.VSTiNNA if(pIns && pIns->nMixPlug) applyDNAtoPlug = true; break; // Plugin case DCT_PLUGIN: if(pIns && (pIns->nMixPlug) && (pIns->nMixPlug == chn.pModInstrument->nMixPlug)) { applyDNAtoPlug = true; bOk = true; } //end rewbs.VSTiNNA break; } // Duplicate Note Action if (bOk) { #ifndef NO_PLUGINS if (applyDNAtoPlug && chn.nNote != NOTE_NONE) { switch(chn.pModInstrument->nDNA) { case DNA_NOTECUT: case DNA_NOTEOFF: case DNA_NOTEFADE: // Switch off duplicated note played on this plugin SendMIDINote(i, chn.GetPluginNote(m_playBehaviour[kITRealNoteMapping]) + NOTE_MAX_SPECIAL, 0); chn.nArpeggioLastNote = NOTE_NONE; break; } } #endif // NO_PLUGINS switch(chn.pModInstrument->nDNA) { // Cut case DNA_NOTECUT: KeyOff(&chn); chn.nVolume = 0; break; // Note Off case DNA_NOTEOFF: KeyOff(&chn); break; // Note Fade case DNA_NOTEFADE: chn.dwFlags.set(CHN_NOTEFADE); break; } if(!chn.nVolume) { chn.nFadeOutVol = 0; chn.dwFlags.set(CHN_NOTEFADE | CHN_FASTVOLRAMP); } } } } // Do we need to apply New/Duplicate Note Action to a VSTi? bool applyNNAtoPlug = false; #ifndef NO_PLUGINS IMixPlugin *pPlugin = nullptr; if(srcChn.HasMIDIOutput() && ModCommand::IsNote(srcChn.nNote)) // instro sends to a midi chan { PLUGINDEX nPlugin = GetBestPlugin(nChn, PrioritiseInstrument, RespectMutes); if(nPlugin > 0 && nPlugin <= MAX_MIXPLUGINS) { pPlugin = m_MixPlugins[nPlugin-1].pMixPlugin; if(pPlugin) { // apply NNA to this plugin iff it is currently playing a note on this tracking channel // (and if it is playing a note, we know that would be the last note played on this chan). applyNNAtoPlug = pPlugin->IsNotePlaying(srcChn.GetPluginNote(m_playBehaviour[kITRealNoteMapping]), GetBestMidiChannel(nChn), nChn); } } } #endif // NO_PLUGINS // New Note Action //if ((pChn.nVolume) && (pChn.nLength)) if((srcChn.nVolume != 0 && srcChn.nLength != 0) || applyNNAtoPlug) //rewbs.VSTiNNA { nnaChn = GetNNAChannel(nChn); if(nnaChn != 0) { ModChannel &chn = m_PlayState.Chn[nnaChn]; // Copy Channel chn = srcChn; chn.dwFlags.reset(CHN_VIBRATO | CHN_TREMOLO | CHN_PORTAMENTO); chn.nPanbrelloOffset = 0; chn.nMasterChn = nChn < GetNumChannels() ? nChn + 1 : 0; chn.nCommand = CMD_NONE; #ifndef NO_PLUGINS if(applyNNAtoPlug && pPlugin) { //Move note to the NNA channel (odd, but makes sense with DNA stuff). //Actually a bad idea since it then become very hard to kill some notes. //pPlugin->MoveNote(pChn.nNote, pChn.pModInstrument->nMidiChannel, nChn, n); switch(srcChn.nNNA) { case NNA_NOTEOFF: case NNA_NOTECUT: case NNA_NOTEFADE: //switch off note played on this plugin, on this tracker channel and midi channel //pPlugin->MidiCommand(pChn.pModInstrument->nMidiChannel, pChn.pModInstrument->nMidiProgram, pChn.nNote + NOTE_MAX_SPECIAL, 0, n); SendMIDINote(nChn, NOTE_KEYOFF, 0); srcChn.nArpeggioLastNote = NOTE_NONE; break; } } #endif // NO_PLUGINS // Key Off the note switch(srcChn.nNNA) { case NNA_NOTEOFF: KeyOff(&chn); break; case NNA_NOTECUT: chn.nFadeOutVol = 0; chn.dwFlags.set(CHN_NOTEFADE); break; case NNA_NOTEFADE: chn.dwFlags.set(CHN_NOTEFADE); break; } if(!chn.nVolume) { chn.nFadeOutVol = 0; chn.dwFlags.set(CHN_NOTEFADE | CHN_FASTVOLRAMP); } // Stop this channel srcChn.nLength = 0; srcChn.position.Set(0); srcChn.nROfs = srcChn.nLOfs = 0; } } return nnaChn; } bool CSoundFile::ProcessEffects() { ModChannel *pChn = m_PlayState.Chn; ROWINDEX nBreakRow = ROWINDEX_INVALID; // Is changed if a break to row command is encountered ROWINDEX nPatLoopRow = ROWINDEX_INVALID; // Is changed if a pattern loop jump-back is executed ORDERINDEX nPosJump = ORDERINDEX_INVALID; for(CHANNELINDEX nChn = 0; nChn < GetNumChannels(); nChn++, pChn++) { const uint32 tickCount = m_PlayState.m_nTickCount % (m_PlayState.m_nMusicSpeed + m_PlayState.m_nFrameDelay); uint32 instr = pChn->rowCommand.instr; ModCommand::VOLCMD volcmd = pChn->rowCommand.volcmd; uint32 vol = pChn->rowCommand.vol; ModCommand::COMMAND cmd = pChn->rowCommand.command; uint32 param = pChn->rowCommand.param; bool bPorta = pChn->rowCommand.IsPortamento(); uint32 nStartTick = 0; pChn->isFirstTick = m_SongFlags[SONG_FIRSTTICK]; // Process parameter control note. if(pChn->rowCommand.note == NOTE_PC) { #ifndef NO_PLUGINS const PLUGINDEX plug = pChn->rowCommand.instr; const PlugParamIndex plugparam = pChn->rowCommand.GetValueVolCol(); const PlugParamValue value = pChn->rowCommand.GetValueEffectCol() / PlugParamValue(ModCommand::maxColumnValue); if(plug > 0 && plug <= MAX_MIXPLUGINS && m_MixPlugins[plug - 1].pMixPlugin) m_MixPlugins[plug-1].pMixPlugin->SetParameter(plugparam, value); #endif // NO_PLUGINS } // Process continuous parameter control note. // Row data is cleared after first tick so on following // ticks using channels m_nPlugParamValueStep to identify // the need for parameter control. The condition cmd == 0 // is to make sure that m_nPlugParamValueStep != 0 because // of NOTE_PCS, not because of macro. if(pChn->rowCommand.note == NOTE_PCS || (cmd == CMD_NONE && pChn->m_plugParamValueStep != 0)) { #ifndef NO_PLUGINS const bool isFirstTick = m_SongFlags[SONG_FIRSTTICK]; if(isFirstTick) pChn->m_RowPlug = pChn->rowCommand.instr; const PLUGINDEX nPlug = pChn->m_RowPlug; const bool hasValidPlug = (nPlug > 0 && nPlug <= MAX_MIXPLUGINS && m_MixPlugins[nPlug-1].pMixPlugin); if(hasValidPlug) { if(isFirstTick) pChn->m_RowPlugParam = ModCommand::GetValueVolCol(pChn->rowCommand.volcmd, pChn->rowCommand.vol); const PlugParamIndex plugparam = pChn->m_RowPlugParam; if(isFirstTick) { PlugParamValue targetvalue = ModCommand::GetValueEffectCol(pChn->rowCommand.command, pChn->rowCommand.param) / PlugParamValue(ModCommand::maxColumnValue); pChn->m_plugParamTargetValue = targetvalue; pChn->m_plugParamValueStep = (targetvalue - m_MixPlugins[nPlug-1].pMixPlugin->GetParameter(plugparam)) / float(GetNumTicksOnCurrentRow()); } if(m_PlayState.m_nTickCount + 1 == GetNumTicksOnCurrentRow()) { // On last tick, set parameter exactly to target value. m_MixPlugins[nPlug-1].pMixPlugin->SetParameter(plugparam, pChn->m_plugParamTargetValue); } else m_MixPlugins[nPlug-1].pMixPlugin->ModifyParameter(plugparam, pChn->m_plugParamValueStep); } #endif // NO_PLUGINS } // Apart from changing parameters, parameter control notes are intended to be 'invisible'. // To achieve this, clearing the note data so that rest of the process sees the row as empty row. if(ModCommand::IsPcNote(pChn->rowCommand.note)) { pChn->ClearRowCmd(); instr = 0; volcmd = VOLCMD_NONE; vol = 0; cmd = CMD_NONE; param = 0; bPorta = false; } // Process Invert Loop (MOD Effect, called every row if it's active) if(!m_SongFlags[SONG_FIRSTTICK]) { InvertLoop(&m_PlayState.Chn[nChn]); } else { if(instr) m_PlayState.Chn[nChn].nEFxOffset = 0; } // Process special effects (note delay, pattern delay, pattern loop) if (cmd == CMD_DELAYCUT) { //:xy --> note delay until tick x, note cut at tick x+y nStartTick = (param & 0xF0) >> 4; const uint32 cutAtTick = nStartTick + (param & 0x0F); NoteCut(nChn, cutAtTick, m_playBehaviour[kITSCxStopsSample]); } else if ((cmd == CMD_MODCMDEX) || (cmd == CMD_S3MCMDEX)) { if ((!param) && (GetType() & (MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_MPT))) param = pChn->nOldCmdEx; else pChn->nOldCmdEx = static_cast(param); // Note Delay ? if ((param & 0xF0) == 0xD0) { nStartTick = param & 0x0F; if(nStartTick == 0) { //IT compatibility 22. SD0 == SD1 if(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) nStartTick = 1; //ST3 ignores notes with SD0 completely else if(GetType() == MOD_TYPE_S3M) continue; } else if(nStartTick >= (m_PlayState.m_nMusicSpeed + m_PlayState.m_nFrameDelay) && m_playBehaviour[kITOutOfRangeDelay]) { // IT compatibility 08. Handling of out-of-range delay command. // Additional test case: tickdelay.it if(instr) { pChn->nNewIns = static_cast(instr); } continue; } } else if(m_SongFlags[SONG_FIRSTTICK]) { // Pattern Loop ? if((((param & 0xF0) == 0x60 && cmd == CMD_MODCMDEX) || ((param & 0xF0) == 0xB0 && cmd == CMD_S3MCMDEX)) && !(m_playBehaviour[kST3NoMutedChannels] && ChnSettings[nChn].dwFlags[CHN_MUTE])) // not even effects are processed on muted S3M channels { ROWINDEX nloop = PatternLoop(pChn, param & 0x0F); if (nloop != ROWINDEX_INVALID) { // FT2 compatibility: E6x overwrites jump targets of Dxx effects that are located left of the E6x effect. // Test cases: PatLoop-Jumps.xm, PatLoop-Various.xm if(nBreakRow != ROWINDEX_INVALID && m_playBehaviour[kFT2PatternLoopWithJumps]) { nBreakRow = nloop; } nPatLoopRow = nloop; } if(GetType() == MOD_TYPE_S3M) { // ST3 doesn't have per-channel pattern loop memory, so spam all changes to other channels as well. for (CHANNELINDEX i = 0; i < GetNumChannels(); i++) { m_PlayState.Chn[i].nPatternLoop = pChn->nPatternLoop; m_PlayState.Chn[i].nPatternLoopCount = pChn->nPatternLoopCount; } } } else if ((param & 0xF0) == 0xE0) { // Pattern Delay // In Scream Tracker 3 / Impulse Tracker, only the first delay command on this row is considered. // Test cases: PatternDelays.it, PatternDelays.s3m, PatternDelays.xm // XXX In Scream Tracker 3, the "left" channels are evaluated before the "right" channels, which is not emulated here! if(!(GetType() & (MOD_TYPE_S3M | MOD_TYPE_IT | MOD_TYPE_MPT)) || !m_PlayState.m_nPatternDelay) { if(!(GetType() & (MOD_TYPE_S3M)) || (param & 0x0F) != 0) { // While Impulse Tracker *does* count S60 as a valid row delay (and thus ignores any other row delay commands on the right), // Scream Tracker 3 simply ignores such commands. m_PlayState.m_nPatternDelay = 1 + (param & 0x0F); } } } } } if(GetType() == MOD_TYPE_MTM && cmd == CMD_MODCMDEX && (param & 0xF0) == 0xD0) { // Apparently, retrigger and note delay have the same behaviour in MultiTracker: // They both restart the note at tick x, and if there is a note on the same row, // this note is started on the first tick. nStartTick = 0; param = 0x90 | (param & 0x0F); } if(nStartTick != 0 && pChn->rowCommand.note == NOTE_KEYOFF && pChn->rowCommand.volcmd == VOLCMD_PANNING && m_playBehaviour[kFT2PanWithDelayedNoteOff]) { // FT2 compatibility: If there's a delayed note off, panning commands are ignored. WTF! // Test case: PanOff.xm pChn->rowCommand.volcmd = VOLCMD_NONE; } bool triggerNote = (m_PlayState.m_nTickCount == nStartTick); // Can be delayed by a note delay effect if(m_playBehaviour[kFT2OutOfRangeDelay] && nStartTick >= m_PlayState.m_nMusicSpeed) { // FT2 compatibility: Note delays greater than the song speed should be ignored. // However, EEx pattern delay is *not* considered at all. // Test case: DelayCombination.xm, PortaDelay.xm triggerNote = false; } else if(m_playBehaviour[kRowDelayWithNoteDelay] && nStartTick > 0 && tickCount == nStartTick) { // IT compatibility: Delayed notes (using SDx) that are on the same row as a Row Delay effect are retriggered. // ProTracker / Scream Tracker 3 / FastTracker 2 do the same. // Test case: PatternDelay-NoteDelay.it, PatternDelay-NoteDelay.xm, PatternDelaysRetrig.mod triggerNote = true; } // IT compatibility: Tick-0 vs non-tick-0 effect distinction is always based on tick delay. // Test case: SlideDelay.it if(m_playBehaviour[kITFirstTickHandling]) { pChn->isFirstTick = tickCount == nStartTick; } // FT2 compatibility: Note + portamento + note delay = no portamento // Test case: PortaDelay.xm if(m_playBehaviour[kFT2PortaDelay] && nStartTick != 0) { bPorta = false; } if(m_SongFlags[SONG_PT_MODE] && instr && !m_PlayState.m_nTickCount) { // Instrument number resets the stacked ProTracker offset. // Test case: ptoffset.mod pChn->proTrackerOffset = 0; // ProTracker compatibility: Sample properties are always loaded on the first tick, even when there is a note delay. // Test case: InstrDelay.mod if(!triggerNote && pChn->IsSamplePlaying()) { pChn->nNewIns = static_cast(instr); if(instr <= GetNumSamples()) { pChn->nVolume = Samples[instr].nVolume; pChn->nFineTune = Samples[instr].nFineTune; } } } // Handles note/instrument/volume changes if(triggerNote) { ModCommand::NOTE note = pChn->rowCommand.note; if(instr) pChn->nNewIns = static_cast(instr); if(ModCommand::IsNote(note) && m_playBehaviour[kFT2Transpose]) { // Notes that exceed FT2's limit are completely ignored. // Test case: NoteLimit.xm int transpose = pChn->nTranspose; if(instr && !bPorta) { // Refresh transpose // Test case: NoteLimit2.xm SAMPLEINDEX sample = SAMPLEINDEX_INVALID; if(GetNumInstruments()) { // Instrument mode if(instr <= GetNumInstruments() && Instruments[instr] != nullptr) { sample = Instruments[instr]->Keyboard[note - NOTE_MIN]; } } else { // Sample mode sample = static_cast(instr); } if(sample <= GetNumSamples()) { transpose = GetSample(sample).RelativeTone; } } const int computedNote = note + transpose; if((computedNote < NOTE_MIN + 11 || computedNote > NOTE_MIN + 130)) { note = NOTE_NONE; } } else if((GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) && GetNumInstruments() != 0 && ModCommand::IsNoteOrEmpty(static_cast(note))) { // IT compatibility: Invalid instrument numbers do nothing, but they are remembered for upcoming notes and do not trigger a note in that case. // Test case: InstrumentNumberChange.it INSTRUMENTINDEX instrToCheck = static_cast((instr != 0) ? instr : pChn->nOldIns); if(instrToCheck != 0 && (instrToCheck > GetNumInstruments() || Instruments[instrToCheck] == nullptr)) { note = NOTE_NONE; instr = 0; } } // XM: FT2 ignores a note next to a K00 effect, and a fade-out seems to be done when no volume envelope is present (not exactly the Kxx behaviour) if(cmd == CMD_KEYOFF && param == 0 && m_playBehaviour[kFT2KeyOff]) { note = NOTE_NONE; instr = 0; } bool retrigEnv = note == NOTE_NONE && instr != 0; // Apparently, any note number in a pattern causes instruments to recall their original volume settings - no matter if there's a Note Off next to it or whatever. // Test cases: keyoff+instr.xm, delay.xm bool reloadSampleSettings = (m_playBehaviour[kFT2ReloadSampleSettings] && instr != 0); // ProTracker Compatibility: If a sample was stopped before, lone instrument numbers can retrigger it // Test case: PTSwapEmpty.mod bool keepInstr = (GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) || (m_playBehaviour[kMODSampleSwap] && !pChn->IsSamplePlaying() && pChn->pModSample != nullptr && pChn->pModSample->pSample == nullptr); // Now it's time for some FT2 crap... if (GetType() & (MOD_TYPE_XM | MOD_TYPE_MT2)) { // XM: Key-Off + Sample == Note Cut (BUT: Only if no instr number or volume effect is present!) // Test case: NoteOffVolume.xm if(note == NOTE_KEYOFF && ((!instr && volcmd != VOLCMD_VOLUME && cmd != CMD_VOLUME) || !m_playBehaviour[kFT2KeyOff]) && (pChn->pModInstrument == nullptr || !pChn->pModInstrument->VolEnv.dwFlags[ENV_ENABLED])) { pChn->dwFlags.set(CHN_FASTVOLRAMP); pChn->nVolume = 0; note = NOTE_NONE; instr = 0; retrigEnv = false; // FT2 Compatbility: Start fading the note for notes with no delay. Only relevant when a volume command is encountered after the note-off. // Test case: NoteOffFadeNoEnv.xm if(m_SongFlags[SONG_FIRSTTICK] && m_playBehaviour[kFT2NoteOffFlags]) pChn->dwFlags.set(CHN_NOTEFADE); } else if(m_playBehaviour[kFT2RetrigWithNoteDelay] && !m_SongFlags[SONG_FIRSTTICK]) { // FT2 Compatibility: Some special hacks for rogue note delays... (EDx with x > 0) // Apparently anything that is next to a note delay behaves totally unpredictable in FT2. Swedish tracker logic. :) retrigEnv = true; // Portamento + Note Delay = No Portamento // Test case: porta-delay.xm bPorta = false; if(note == NOTE_NONE) { // If there's a note delay but no real note, retrig the last note. // Test case: delay2.xm, delay3.xm note = static_cast(pChn->nNote - pChn->nTranspose); } else if(note >= NOTE_MIN_SPECIAL) { // Gah! Even Note Off + Note Delay will cause envelopes to *retrigger*! How stupid is that? // ... Well, and that is actually all it does if there's an envelope. No fade out, no nothing. *sigh* // Test case: OffDelay.xm note = NOTE_NONE; keepInstr = false; reloadSampleSettings = true; } else { // Normal note keepInstr = true; reloadSampleSettings = true; } } } if((retrigEnv && !m_playBehaviour[kFT2ReloadSampleSettings]) || reloadSampleSettings) { const ModSample *oldSample = nullptr; // Reset default volume when retriggering envelopes if(GetNumInstruments()) { oldSample = pChn->pModSample; } else if (instr <= GetNumSamples()) { // Case: Only samples are used; no instruments. oldSample = &Samples[instr]; } if(oldSample != nullptr) { if(!oldSample->uFlags[SMP_NODEFAULTVOLUME]) pChn->nVolume = oldSample->nVolume; if(reloadSampleSettings) { // Also reload panning pChn->nPan = oldSample->nPan; } } } // FT2 compatibility: Instrument number disables tremor effect // Test case: TremorInstr.xm, TremoRecover.xm if(m_playBehaviour[kFT2Tremor] && instr != 0) { pChn->nTremorCount = 0x20; } if(retrigEnv) //Case: instrument with no note data. { //IT compatibility: Instrument with no note. if(m_playBehaviour[kITInstrWithoutNote] || GetType() == MOD_TYPE_PLM) { // IT compatibility: Completely retrigger note after sample end to also reset portamento. // Test case: PortaResetAfterRetrigger.it bool triggerAfterSmpEnd = m_playBehaviour[kITMultiSampleInstrumentNumber] && !pChn->IsSamplePlaying(); if(GetNumInstruments()) { // Instrument mode if(instr <= GetNumInstruments() && (pChn->pModInstrument != Instruments[instr] || triggerAfterSmpEnd)) note = pChn->nNote; } else { // Sample mode if(instr < MAX_SAMPLES && (pChn->pModSample != &Samples[instr] || triggerAfterSmpEnd)) note = pChn->nNote; } } if (GetNumInstruments() && (GetType() & (MOD_TYPE_XM|MOD_TYPE_MT2))) { pChn->ResetEnvelopes(); pChn->dwFlags.set(CHN_FASTVOLRAMP); pChn->dwFlags.reset(CHN_NOTEFADE); pChn->nAutoVibDepth = 0; pChn->nAutoVibPos = 0; pChn->nFadeOutVol = 65536; // FT2 Compatbility: Reset key-off status with instrument number // Test case: NoteOffInstrChange.xm if(m_playBehaviour[kFT2NoteOffFlags]) pChn->dwFlags.reset(CHN_KEYOFF); } if (!keepInstr) instr = 0; } // Note Cut/Off/Fade => ignore instrument if (note >= NOTE_MIN_SPECIAL) { // IT compatibility: Default volume of sample is recalled if instrument number is next to a note-off. // Test case: NoteOffInstr.it, noteoff2.it if(m_playBehaviour[kITInstrWithNoteOff] && instr) { SAMPLEINDEX smp = static_cast(instr); if(GetNumInstruments()) { smp = 0; if(instr <= GetNumInstruments() && Instruments[instr] != nullptr && ModCommand::IsNote(pChn->nLastNote)) { smp = Instruments[instr]->Keyboard[pChn->nLastNote - NOTE_MIN]; } } if(smp > 0 && smp <= GetNumSamples() && !Samples[smp].uFlags[SMP_NODEFAULTVOLUME]) pChn->nVolume = Samples[smp].nVolume; } instr = 0; } if(ModCommand::IsNote(note)) { pChn->nNewNote = pChn->nLastNote = note; // New Note Action ? if(!bPorta) { CheckNNA(nChn, instr, note, false); } } if(note) { if(pChn->nRestorePanOnNewNote > 0) { pChn->nPan = pChn->nRestorePanOnNewNote - 1; pChn->nRestorePanOnNewNote = 0; } if(pChn->nRestoreResonanceOnNewNote > 0) { pChn->nResonance = pChn->nRestoreResonanceOnNewNote - 1; pChn->nRestoreResonanceOnNewNote = 0; } if(pChn->nRestoreCutoffOnNewNote > 0) { pChn->nCutOff = pChn->nRestoreCutoffOnNewNote - 1; pChn->nRestoreCutoffOnNewNote = 0; } } // Instrument Change ? if(instr) { const ModSample *oldSample = pChn->pModSample; //const ModInstrument *oldInstrument = pChn->pModInstrument; InstrumentChange(pChn, instr, bPorta, true); // IT compatibility: Keep new instrument number for next instrument-less note even if sample playback is stopped // Test case: StoppedInstrSwap.it if(GetType() == MOD_TYPE_MOD) { // Test case: PortaSwapPT.mod if(!bPorta || !m_playBehaviour[kMODSampleSwap]) pChn->nNewIns = 0; } else { if(!m_playBehaviour[kITInstrWithNoteOff] || ModCommand::IsNote(note)) pChn->nNewIns = 0; } if(m_playBehaviour[kITPortamentoSwapResetsPos]) { // Test cases: PortaInsNum.it, PortaSample.it if(ModCommand::IsNote(note) && oldSample != pChn->pModSample) { //const bool newInstrument = oldInstrument != pChn->pModInstrument && pChn->pModInstrument->Keyboard[pChn->nNewNote - NOTE_MIN] != 0; pChn->position.Set(0); } } else if ((GetType() & (MOD_TYPE_S3M | MOD_TYPE_IT | MOD_TYPE_MPT) && oldSample != pChn->pModSample && ModCommand::IsNote(note))) { // Special IT case: portamento+note causes sample change -> ignore portamento bPorta = false; } else if(m_playBehaviour[kMODSampleSwap] && pChn->increment.IsZero()) { // If channel was paused and is resurrected by a lone instrument number, reset the sample position. // Test case: PTSwapEmpty.mod pChn->position.Set(0); } } // New Note ? if (note) { if ((!instr) && (pChn->nNewIns) && (note < 0x80)) { InstrumentChange(pChn, pChn->nNewIns, bPorta, false, !(GetType() & (MOD_TYPE_XM|MOD_TYPE_MT2))); pChn->nNewIns = 0; } NoteChange(pChn, note, bPorta, !(GetType() & (MOD_TYPE_XM|MOD_TYPE_MT2))); if ((bPorta) && (GetType() & (MOD_TYPE_XM|MOD_TYPE_MT2)) && (instr)) { pChn->dwFlags.set(CHN_FASTVOLRAMP); pChn->ResetEnvelopes(); pChn->nAutoVibDepth = 0; pChn->nAutoVibPos = 0; } } // Tick-0 only volume commands if (volcmd == VOLCMD_VOLUME) { if (vol > 64) vol = 64; pChn->nVolume = vol << 2; pChn->dwFlags.set(CHN_FASTVOLRAMP); } else if (volcmd == VOLCMD_PANNING) { Panning(pChn, vol, Pan6bit); } #ifndef NO_PLUGINS if (m_nInstruments) ProcessMidiOut(nChn); #endif // NO_PLUGINS } if(m_playBehaviour[kST3NoMutedChannels] && ChnSettings[nChn].dwFlags[CHN_MUTE]) // not even effects are processed on muted S3M channels continue; // Volume Column Effect (except volume & panning) /* A few notes, paraphrased from ITTECH.TXT by Storlek (creator of schismtracker): Ex/Fx/Gx are shared with Exx/Fxx/Gxx; Ex/Fx are 4x the 'normal' slide value Gx is linked with Ex/Fx if Compat Gxx is off, just like Gxx is with Exx/Fxx Gx values: 1, 4, 8, 16, 32, 64, 96, 128, 255 Ax/Bx/Cx/Dx values are used directly (i.e. D9 == D09), and are NOT shared with Dxx (value is stored into nOldVolParam and used by A0/B0/C0/D0) Hx uses the same value as Hxx and Uxx, and affects the *depth* so... hxx = (hx | (oldhxx & 0xf0)) ??? TODO is this done correctly? */ bool doVolumeColumn = m_PlayState.m_nTickCount >= nStartTick; // FT2 compatibility: If there's a note delay, volume column effects are NOT executed // on the first tick and, if there's an instrument number, on the delayed tick. // Test case: VolColDelay.xm, PortaDelay.xm if(m_playBehaviour[kFT2VolColDelay] && nStartTick != 0) { doVolumeColumn = m_PlayState.m_nTickCount != 0 && (m_PlayState.m_nTickCount != nStartTick || (pChn->rowCommand.instr == 0 && volcmd != VOLCMD_TONEPORTAMENTO)); } if(volcmd > VOLCMD_PANNING && doVolumeColumn) { if (volcmd == VOLCMD_TONEPORTAMENTO) { uint32 porta = 0; if(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT | MOD_TYPE_AMS | MOD_TYPE_AMS2 | MOD_TYPE_DMF | MOD_TYPE_DBM | MOD_TYPE_IMF | MOD_TYPE_PSM | MOD_TYPE_J2B | MOD_TYPE_ULT | MOD_TYPE_OKT | MOD_TYPE_MT2 | MOD_TYPE_MDL)) { porta = ImpulseTrackerPortaVolCmd[vol & 0x0F]; } else { if(cmd == CMD_TONEPORTAMENTO && GetType() == MOD_TYPE_XM) { // Yes, FT2 is *that* weird. If there is a Mx command in the volume column // and a normal 3xx command, the 3xx command is ignored but the Mx command's // effectiveness is doubled. // Test case: TonePortamentoMemory.xm cmd = CMD_NONE; vol *= 2; } porta = vol << 4; // FT2 compatibility: If there's a portamento and a note delay, execute the portamento, but don't update the parameter // Test case: PortaDelay.xm if(m_playBehaviour[kFT2PortaDelay] && nStartTick != 0) { porta = 0; } } TonePortamento(pChn, porta); } else { // FT2 Compatibility: FT2 ignores some volume commands with parameter = 0. if(m_playBehaviour[kFT2VolColMemory] && vol == 0) { switch(volcmd) { case VOLCMD_VOLUME: case VOLCMD_PANNING: case VOLCMD_VIBRATODEPTH: break; case VOLCMD_PANSLIDELEFT: // FT2 Compatibility: Pan slide left with zero parameter causes panning to be set to full left on every non-row tick. // Test case: PanSlideZero.xm if(!m_SongFlags[SONG_FIRSTTICK]) { pChn->nPan = 0; } MPT_FALLTHROUGH; default: // no memory here. volcmd = VOLCMD_NONE; } } else if(!m_playBehaviour[kITVolColMemory]) { // IT Compatibility: Effects in the volume column don't have an unified memory. // Test case: VolColMemory.it if(vol) pChn->nOldVolParam = static_cast(vol); else vol = pChn->nOldVolParam; } switch(volcmd) { case VOLCMD_VOLSLIDEUP: case VOLCMD_VOLSLIDEDOWN: // IT Compatibility: Volume column volume slides have their own memory // Test case: VolColMemory.it if(vol == 0 && m_playBehaviour[kITVolColMemory]) { vol = pChn->nOldVolParam; if(vol == 0) break; } else { pChn->nOldVolParam = static_cast(vol); } VolumeSlide(pChn, static_cast(volcmd == VOLCMD_VOLSLIDEUP ? (vol << 4) : vol)); break; case VOLCMD_FINEVOLUP: // IT Compatibility: Fine volume slides in the volume column are only executed on the first tick, not on multiples of the first tick in case of pattern delay // Test case: FineVolColSlide.it if(m_PlayState.m_nTickCount == nStartTick || !m_playBehaviour[kITVolColMemory]) { // IT Compatibility: Volume column volume slides have their own memory // Test case: VolColMemory.it FineVolumeUp(pChn, static_cast(vol), m_playBehaviour[kITVolColMemory]); } break; case VOLCMD_FINEVOLDOWN: // IT Compatibility: Fine volume slides in the volume column are only executed on the first tick, not on multiples of the first tick in case of pattern delay // Test case: FineVolColSlide.it if(m_PlayState.m_nTickCount == nStartTick || !m_playBehaviour[kITVolColMemory]) { // IT Compatibility: Volume column volume slides have their own memory // Test case: VolColMemory.it FineVolumeDown(pChn, static_cast(vol), m_playBehaviour[kITVolColMemory]); } break; case VOLCMD_VIBRATOSPEED: // FT2 does not automatically enable vibrato with the "set vibrato speed" command if(m_playBehaviour[kFT2VolColVibrato]) pChn->nVibratoSpeed = vol & 0x0F; else Vibrato(pChn, vol << 4); break; case VOLCMD_VIBRATODEPTH: Vibrato(pChn, vol); break; case VOLCMD_PANSLIDELEFT: PanningSlide(pChn, static_cast(vol), !m_playBehaviour[kFT2VolColMemory]); break; case VOLCMD_PANSLIDERIGHT: PanningSlide(pChn, static_cast(vol << 4), !m_playBehaviour[kFT2VolColMemory]); break; case VOLCMD_PORTAUP: // IT compatibility (one of the first testcases - link effect memory) PortamentoUp(nChn, static_cast(vol << 2), m_playBehaviour[kITVolColFinePortamento]); break; case VOLCMD_PORTADOWN: // IT compatibility (one of the first testcases - link effect memory) PortamentoDown(nChn, static_cast(vol << 2), m_playBehaviour[kITVolColFinePortamento]); break; case VOLCMD_OFFSET: if (triggerNote && pChn->pModSample && vol <= CountOf(pChn->pModSample->cues)) { SmpLength offset; if(vol == 0) offset = pChn->oldOffset; else offset = pChn->oldOffset = pChn->pModSample->cues[vol - 1]; SampleOffset(*pChn, offset); } break; } } } // Effects if(cmd != CMD_NONE) switch (cmd) { // Set Volume case CMD_VOLUME: if(m_SongFlags[SONG_FIRSTTICK]) { pChn->nVolume = (param < 64) ? param * 4 : 256; pChn->dwFlags.set(CHN_FASTVOLRAMP); } break; // Portamento Up case CMD_PORTAMENTOUP: if ((!param) && (GetType() & MOD_TYPE_MOD)) break; PortamentoUp(nChn, static_cast(param)); break; // Portamento Down case CMD_PORTAMENTODOWN: if ((!param) && (GetType() & MOD_TYPE_MOD)) break; PortamentoDown(nChn, static_cast(param)); break; // Volume Slide case CMD_VOLUMESLIDE: if (param || (GetType() != MOD_TYPE_MOD)) VolumeSlide(pChn, static_cast(param)); break; // Tone-Portamento case CMD_TONEPORTAMENTO: TonePortamento(pChn, param); break; // Tone-Portamento + Volume Slide case CMD_TONEPORTAVOL: if ((param) || (GetType() != MOD_TYPE_MOD)) VolumeSlide(pChn, static_cast(param)); TonePortamento(pChn, 0); break; // Vibrato case CMD_VIBRATO: Vibrato(pChn, param); break; // Vibrato + Volume Slide case CMD_VIBRATOVOL: if ((param) || (GetType() != MOD_TYPE_MOD)) VolumeSlide(pChn, static_cast(param)); Vibrato(pChn, 0); break; // Set Speed case CMD_SPEED: if(m_SongFlags[SONG_FIRSTTICK]) SetSpeed(m_PlayState, param); break; // Set Tempo case CMD_TEMPO: if(m_playBehaviour[kMODVBlankTiming]) { // ProTracker MODs with VBlank timing: All Fxx parameters set the tick count. if(m_SongFlags[SONG_FIRSTTICK] && param != 0) SetSpeed(m_PlayState, param); break; } { param = CalculateXParam(m_PlayState.m_nPattern, m_PlayState.m_nRow, nChn); if (GetType() & (MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_MPT)) { if (param) pChn->nOldTempo = static_cast(param); else param = pChn->nOldTempo; } TEMPO t(param, 0); LimitMax(t, GetModSpecifications().GetTempoMax()); SetTempo(t); } break; // Set Offset case CMD_OFFSET: if (triggerNote) { // FT2 compatibility: Portamento + Offset = Ignore offset // Test case: porta-offset.xm if(bPorta && GetType() == MOD_TYPE_XM) { break; } bool isExtended = false; SmpLength offset = CalculateXParam(m_PlayState.m_nPattern, m_PlayState.m_nRow, nChn, &isExtended); if(!isExtended) { // No X-param (normal behaviour) offset <<= 8; if (offset) pChn->oldOffset = offset; else offset = pChn->oldOffset; offset += static_cast(pChn->nOldHiOffset) << 16; } SampleOffset(*pChn, offset); } break; // Disorder Tracker 2 percentage offset case CMD_OFFSETPERCENTAGE: if(triggerNote) { SampleOffset(*pChn, Util::muldiv_unsigned(pChn->nLength, param, 255)); } break; // Arpeggio case CMD_ARPEGGIO: // IT compatibility 01. Don't ignore Arpeggio if no note is playing (also valid for ST3) if(m_PlayState.m_nTickCount) break; if((!pChn->nPeriod || !pChn->nNote) && (pChn->pModInstrument == nullptr || !pChn->pModInstrument->HasValidMIDIChannel()) // Plugin arpeggio && !m_playBehaviour[kITArpeggio] && (GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT))) break; if (!param && (GetType() & (MOD_TYPE_XM | MOD_TYPE_MOD))) break; // Only important when editing MOD/XM files (000 effects are removed when loading files where this means "no effect") pChn->nCommand = CMD_ARPEGGIO; if (param) pChn->nArpeggio = static_cast(param); break; // Retrig case CMD_RETRIG: if (GetType() & (MOD_TYPE_XM|MOD_TYPE_MT2)) { if (!(param & 0xF0)) param |= pChn->nRetrigParam & 0xF0; if (!(param & 0x0F)) param |= pChn->nRetrigParam & 0x0F; param |= 0x100; // increment retrig count on first row } // IT compatibility 15. Retrigger if(m_playBehaviour[kITRetrigger]) { if (param) pChn->nRetrigParam = static_cast(param & 0xFF); RetrigNote(nChn, pChn->nRetrigParam, (volcmd == VOLCMD_OFFSET) ? vol + 1 : 0); } else { // XM Retrig if (param) pChn->nRetrigParam = static_cast(param & 0xFF); else param = pChn->nRetrigParam; RetrigNote(nChn, param, (volcmd == VOLCMD_OFFSET) ? vol + 1 : 0); } break; // Tremor case CMD_TREMOR: if(!m_SongFlags[SONG_FIRSTTICK]) { break; } // IT compatibility 12. / 13. Tremor (using modified DUMB's Tremor logic here because of old effects - http://dumb.sf.net/) if(m_playBehaviour[kITTremor]) { if(param && !m_SongFlags[SONG_ITOLDEFFECTS]) { // Old effects have different length interpretation (+1 for both on and off) if(param & 0xF0) param -= 0x10; if(param & 0x0F) param -= 0x01; } pChn->nTremorCount |= 0x80; // set on/off flag } else if(m_playBehaviour[kFT2Tremor]) { // XM Tremor. Logic is being processed in sndmix.cpp pChn->nTremorCount |= 0x80; // set on/off flag } pChn->nCommand = CMD_TREMOR; if (param) pChn->nTremorParam = static_cast(param); break; // Set Global Volume case CMD_GLOBALVOLUME: // IT compatibility: Only apply global volume on first tick (and multiples) // Test case: GlobalVolFirstTick.it if(!m_SongFlags[SONG_FIRSTTICK]) break; // ST3 applies global volume on tick 1 and does other weird things, but we won't emulate this for now. // if(((GetType() & MOD_TYPE_S3M) && m_nTickCount != 1) // || (!(GetType() & MOD_TYPE_S3M) && !m_SongFlags[SONG_FIRSTTICK])) // { // break; // } // FT2 compatibility: On channels that are "left" of the global volume command, the new global volume is not applied // until the second tick of the row. Since we apply global volume on the mix buffer rather than note volumes, this // cannot be fixed for now. // Test case: GlobalVolume.xm // if(IsCompatibleMode(TRK_FASTTRACKER2) && m_SongFlags[SONG_FIRSTTICK] && m_nMusicSpeed > 1) // { // break; // } if (!(GetType() & GLOBALVOL_7BIT_FORMATS)) param *= 2; // IT compatibility 16. ST3 and IT ignore out-of-range values. // Test case: globalvol-invalid.it if(param <= 128) { m_PlayState.m_nGlobalVolume = param * 2; } else if(!(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT | MOD_TYPE_S3M))) { m_PlayState.m_nGlobalVolume = 256; } break; // Global Volume Slide case CMD_GLOBALVOLSLIDE: //IT compatibility 16. Saving last global volume slide param per channel (FT2/IT) if(m_playBehaviour[kPerChannelGlobalVolSlide]) GlobalVolSlide(static_cast(param), pChn->nOldGlobalVolSlide); else GlobalVolSlide(static_cast(param), m_PlayState.Chn[0].nOldGlobalVolSlide); break; // Set 8-bit Panning case CMD_PANNING8: if(m_SongFlags[SONG_FIRSTTICK]) { Panning(pChn, param, Pan8bit); } break; // Panning Slide case CMD_PANNINGSLIDE: PanningSlide(pChn, static_cast(param)); break; // Tremolo case CMD_TREMOLO: Tremolo(pChn, param); break; // Fine Vibrato case CMD_FINEVIBRATO: FineVibrato(pChn, param); break; // MOD/XM Exx Extended Commands case CMD_MODCMDEX: ExtendedMODCommands(nChn, static_cast(param)); break; // S3M/IT Sxx Extended Commands case CMD_S3MCMDEX: if(m_playBehaviour[kST3EffectMemory] && param == 0) { param = pChn->nArpeggio; // S00 uses the last non-zero effect parameter as memory, like other effects including Arpeggio, so we "borrow" our memory there. } ExtendedS3MCommands(nChn, static_cast(param)); break; // Key Off case CMD_KEYOFF: // This is how Key Off is supposed to sound... (in FT2 at least) if(m_playBehaviour[kFT2KeyOff]) { if (m_PlayState.m_nTickCount == param) { // XM: Key-Off + Sample == Note Cut if(pChn->pModInstrument == nullptr || !pChn->pModInstrument->VolEnv.dwFlags[ENV_ENABLED]) { if(param == 0 && (pChn->rowCommand.instr || pChn->rowCommand.volcmd != VOLCMD_NONE)) // FT2 is weird.... { pChn->dwFlags.set(CHN_NOTEFADE); } else { pChn->dwFlags.set(CHN_FASTVOLRAMP); pChn->nVolume = 0; } } KeyOff(pChn); } } // This is how it's NOT supposed to sound... else { if(m_SongFlags[SONG_FIRSTTICK]) KeyOff(pChn); } break; // Extra-fine porta up/down case CMD_XFINEPORTAUPDOWN: switch(param & 0xF0) { case 0x10: ExtraFinePortamentoUp(pChn, param & 0x0F); break; case 0x20: ExtraFinePortamentoDown(pChn, param & 0x0F); break; // ModPlug XM Extensions (ignore in compatible mode) case 0x50: case 0x60: case 0x70: case 0x90: case 0xA0: if(!m_playBehaviour[kFT2RestrictXCommand]) ExtendedS3MCommands(nChn, static_cast(param)); break; } break; // Set Channel Global Volume case CMD_CHANNELVOLUME: if(!m_SongFlags[SONG_FIRSTTICK]) break; if (param <= 64) { pChn->nGlobalVol = param; pChn->dwFlags.set(CHN_FASTVOLRAMP); } break; // Channel volume slide case CMD_CHANNELVOLSLIDE: ChannelVolSlide(pChn, static_cast(param)); break; // Panbrello (IT) case CMD_PANBRELLO: Panbrello(pChn, param); break; // Set Envelope Position case CMD_SETENVPOSITION: if(m_SongFlags[SONG_FIRSTTICK]) { pChn->VolEnv.nEnvPosition = param; // FT2 compatibility: FT2 only sets the position of the panning envelope if the volume envelope's sustain flag is set // Test case: SetEnvPos.xm if(!m_playBehaviour[kFT2SetPanEnvPos] || pChn->VolEnv.flags[ENV_SUSTAIN]) { pChn->PanEnv.nEnvPosition = param; pChn->PitchEnv.nEnvPosition = param; } } break; // Position Jump case CMD_POSITIONJUMP: m_PlayState.m_nNextPatStartRow = 0; // FT2 E60 bug nPosJump = static_cast(CalculateXParam(m_PlayState.m_nPattern, m_PlayState.m_nRow, nChn)); // see https://forum.openmpt.org/index.php?topic=2769.0 - FastTracker resets Dxx if Bxx is called _after_ Dxx // Test case: PatternJump.mod if((GetType() & (MOD_TYPE_MOD | MOD_TYPE_XM)) && nBreakRow != ROWINDEX_INVALID) { nBreakRow = 0; } break; // Pattern Break case CMD_PATTERNBREAK: { ROWINDEX row = PatternBreak(m_PlayState, nChn, static_cast(param)); if(row != ROWINDEX_INVALID) { nBreakRow = row; if(m_SongFlags[SONG_PATTERNLOOP]) { //If song is set to loop and a pattern break occurs we should stay on the same pattern. //Use nPosJump to force playback to "jump to this pattern" rather than move to next, as by default. //rewbs.to nPosJump = m_PlayState.m_nCurrentOrder; } } } break; // IMF / PTM Note Slides case CMD_NOTESLIDEUP: case CMD_NOTESLIDEDOWN: case CMD_NOTESLIDEUPRETRIG: case CMD_NOTESLIDEDOWNRETRIG: // Note that this command seems to be a bit buggy in Polytracker... Luckily, no tune seems to seriously use this // (Vic uses it e.g. in Spaceman or Perfect Reason to slide effect samples, noone will notice the difference :) NoteSlide(pChn, param, cmd == CMD_NOTESLIDEUP || cmd == CMD_NOTESLIDEUPRETRIG, cmd == CMD_NOTESLIDEUPRETRIG || cmd == CMD_NOTESLIDEDOWNRETRIG); break; // PTM Reverse sample + offset (executed on every tick) case CMD_REVERSEOFFSET: ReverseSampleOffset(*pChn, static_cast(param)); break; #ifndef NO_PLUGINS // DBM: Toggle DSP Echo case CMD_DBMECHO: if(m_PlayState.m_nTickCount == 0) { uint32 chns = (param >> 4), enable = (param & 0x0F); if(chns > 1 || enable > 2) { break; } CHANNELINDEX firstChn = nChn, lastChn = nChn; if(chns == 1) { firstChn = 0; lastChn = m_nChannels - 1; } for(CHANNELINDEX c = firstChn; c <= lastChn; c++) { ChnSettings[c].dwFlags.set(CHN_NOFX, enable == 1); m_PlayState.Chn[c].dwFlags.set(CHN_NOFX, enable == 1); } } break; #endif // NO_PLUGINS } if(m_playBehaviour[kST3EffectMemory] && param != 0) { UpdateS3MEffectMemory(pChn, static_cast(param)); } if(pChn->rowCommand.instr) { // Not necessarily consistent with actually playing instrument for IT compatibility pChn->nOldIns = pChn->rowCommand.instr; } } // for(...) end // Navigation Effects if(m_SongFlags[SONG_FIRSTTICK]) { const bool doPatternLoop = (nPatLoopRow != ROWINDEX_INVALID); const bool doBreakRow = (nBreakRow != ROWINDEX_INVALID); const bool doPosJump = (nPosJump != ORDERINDEX_INVALID); // Pattern Loop if(doPatternLoop) { m_PlayState.m_nNextOrder = m_PlayState.m_nCurrentOrder; m_PlayState.m_nNextRow = nPatLoopRow; if(m_PlayState.m_nPatternDelay) { m_PlayState.m_nNextRow++; } // IT Compatibility: If the restart row is past the end of the current pattern // (e.g. when continued from a previous pattern without explicit SB0 effect), continue the next pattern. // Test case: LoopStartAfterPatternEnd.it if(nPatLoopRow >= Patterns[m_PlayState.m_nPattern].GetNumRows()) { m_PlayState.m_nNextOrder++; m_PlayState.m_nNextRow = 0; } // As long as the pattern loop is running, mark the looped rows as not visited yet visitedSongRows.ResetPatternLoop(m_PlayState.m_nCurrentOrder, nPatLoopRow); } // Pattern Break / Position Jump only if no loop running // Exception: FastTracker 2 in all cases, Impulse Tracker in case of position jump // Test case for FT2 exception: PatLoop-Jumps.xm, PatLoop-Various.xm // Test case for IT: exception: LoopBreak.it if((doBreakRow || doPosJump) && (!doPatternLoop || m_playBehaviour[kFT2PatternLoopWithJumps] || (m_playBehaviour[kITPatternLoopWithJumps] && doPosJump))) { if(!doPosJump) nPosJump = m_PlayState.m_nCurrentOrder + 1; if(!doBreakRow) nBreakRow = 0; m_SongFlags.set(SONG_BREAKTOROW); if(nPosJump >= Order().size()) { nPosJump = Order().GetRestartPos(); } // IT / FT2 compatibility: don't reset loop count on pattern break. // Test case: gm-trippy01.it, PatLoop-Break.xm, PatLoop-Weird.xm, PatLoop-Break.mod if(nPosJump != m_PlayState.m_nCurrentOrder && !m_playBehaviour[kITPatternLoopBreak] && !m_playBehaviour[kFT2PatternLoopWithJumps] && GetType() != MOD_TYPE_MOD) { for(CHANNELINDEX i = 0; i < GetNumChannels(); i++) { m_PlayState.Chn[i].nPatternLoopCount = 0; } } m_PlayState.m_nNextRow = nBreakRow; if(!m_SongFlags[SONG_PATTERNLOOP]) m_PlayState.m_nNextOrder = nPosJump; } } return true; } //////////////////////////////////////////////////////////// // Channels effects // Update the effect memory of all S3M effects that use the last non-zero effect parameter as memory (Dxy, Exx, Fxx, Ixy, Jxy, Kxy, Lxy, Qxy, Rxy, Sxy) // Test case: ParamMemory.s3m void CSoundFile::UpdateS3MEffectMemory(ModChannel *pChn, ModCommand::PARAM param) const { pChn->nOldVolumeSlide = param; // Dxy / Kxy / Lxy pChn->nOldPortaUp = param; // Exx / Fxx pChn->nOldPortaDown = param; // Exx / Fxx pChn->nTremorParam = param; // Ixy pChn->nArpeggio = param; // Jxy pChn->nRetrigParam = param; // Qxy pChn->nTremoloDepth = (param & 0x0F) << 2; // Rxy pChn->nTremoloSpeed = (param >> 4) & 0x0F; // Rxy // Sxy is not handled here. } // Calculate full parameter for effects that support parameter extension at the given pattern location. // maxCommands sets the maximum number of XParam commands to look at for this effect // isExtended returns if the command is actually using any XParam extensions. uint32 CSoundFile::CalculateXParam(PATTERNINDEX pat, ROWINDEX row, CHANNELINDEX chn, bool *isExtended) const { if(isExtended != nullptr) *isExtended = false; ROWINDEX maxCommands = 4; const ModCommand *m = Patterns[pat].GetpModCommand(row, chn); uint32 val = m->param; switch(m->command) { case CMD_OFFSET: // 24 bit command maxCommands = 2; break; case CMD_TEMPO: case CMD_PATTERNBREAK: case CMD_POSITIONJUMP: // 16 bit command maxCommands = 1; break; default: return val; } const bool xmTempoFix = m->command == CMD_TEMPO && GetType() == MOD_TYPE_XM; ROWINDEX numRows = std::min(Patterns[pat].GetNumRows() - row - 1, maxCommands); while(numRows > 0) { m += Patterns[pat].GetNumChannels(); if(m->command != CMD_XPARAM) { break; } if(xmTempoFix && val < 256) { // With XM, 0x20 is the lowest tempo. Anything below changes ticks per row. val -= 0x20; } val = (val << 8) | m->param; numRows--; if(isExtended != nullptr) *isExtended = true; } return val; } ROWINDEX CSoundFile::PatternBreak(PlayState &state, CHANNELINDEX chn, uint8 param) const { if(param >= 64 && (GetType() & MOD_TYPE_S3M)) { // ST3 ignores invalid pattern breaks. return ROWINDEX_INVALID; } state.m_nNextPatStartRow = 0; // FT2 E60 bug return static_cast(CalculateXParam(state.m_nPattern, state.m_nRow, chn)); } void CSoundFile::PortamentoUp(CHANNELINDEX nChn, ModCommand::PARAM param, const bool doFinePortamentoAsRegular) { ModChannel *pChn = &m_PlayState.Chn[nChn]; if(param) { // FT2 compatibility: Separate effect memory for all portamento commands // Test case: Porta-LinkMem.xm if(!m_playBehaviour[kFT2PortaUpDownMemory]) pChn->nOldPortaDown = param; pChn->nOldPortaUp = param; } else { param = pChn->nOldPortaUp; } const bool doFineSlides = !doFinePortamentoAsRegular && !(GetType() & (MOD_TYPE_MOD | MOD_TYPE_XM | MOD_TYPE_MT2 | MOD_TYPE_MED | MOD_TYPE_AMF0 | MOD_TYPE_DIGI | MOD_TYPE_STP | MOD_TYPE_DTM)); // Process MIDI pitch bend for instrument plugins MidiPortamento(nChn, param, doFineSlides); if(GetType() == MOD_TYPE_MPT && pChn->pModInstrument && pChn->pModInstrument->pTuning) { // Portamento for instruments with custom tuning if(param >= 0xF0 && !doFinePortamentoAsRegular) PortamentoFineMPT(pChn, param - 0xF0); else if(param >= 0xE0 && !doFinePortamentoAsRegular) PortamentoExtraFineMPT(pChn, param - 0xE0); else PortamentoMPT(pChn, param); return; } else if(GetType() == MOD_TYPE_PLM) { // A normal portamento up or down makes a follow-up tone portamento go the same direction. pChn->nPortamentoDest = 1; } if (doFineSlides && param >= 0xE0) { if (param & 0x0F) { if ((param & 0xF0) == 0xF0) { FinePortamentoUp(pChn, param & 0x0F); return; } else if ((param & 0xF0) == 0xE0 && GetType() != MOD_TYPE_DBM) { ExtraFinePortamentoUp(pChn, param & 0x0F); return; } } if(GetType() != MOD_TYPE_DBM) { // DBM only has fine slides, no extra-fine slides. return; } } // Regular Slide if(!pChn->isFirstTick || (m_PlayState.m_nMusicSpeed == 1 && m_playBehaviour[kSlidesAtSpeed1]) || GetType() == MOD_TYPE_669) { DoFreqSlide(pChn, -int(param) * 4); } } void CSoundFile::PortamentoDown(CHANNELINDEX nChn, ModCommand::PARAM param, const bool doFinePortamentoAsRegular) { ModChannel *pChn = &m_PlayState.Chn[nChn]; if(param) { // FT2 compatibility: Separate effect memory for all portamento commands // Test case: Porta-LinkMem.xm if(!m_playBehaviour[kFT2PortaUpDownMemory]) pChn->nOldPortaUp = param; pChn->nOldPortaDown = param; } else { param = pChn->nOldPortaDown; } const bool doFineSlides = !doFinePortamentoAsRegular && !(GetType() & (MOD_TYPE_MOD | MOD_TYPE_XM | MOD_TYPE_MT2 | MOD_TYPE_MED | MOD_TYPE_AMF0 | MOD_TYPE_DIGI | MOD_TYPE_STP | MOD_TYPE_DTM)); // Process MIDI pitch bend for instrument plugins MidiPortamento(nChn, -static_cast(param), doFineSlides); if(GetType() == MOD_TYPE_MPT && pChn->pModInstrument && pChn->pModInstrument->pTuning) { // Portamento for instruments with custom tuning if(param >= 0xF0 && !doFinePortamentoAsRegular) PortamentoFineMPT(pChn, -static_cast(param - 0xF0)); else if(param >= 0xE0 && !doFinePortamentoAsRegular) PortamentoExtraFineMPT(pChn, -static_cast(param - 0xE0)); else PortamentoMPT(pChn, -static_cast(param)); return; } else if(GetType() == MOD_TYPE_PLM) { // A normal portamento up or down makes a follow-up tone portamento go the same direction. pChn->nPortamentoDest = 65535; } if(doFineSlides && param >= 0xE0) { if (param & 0x0F) { if ((param & 0xF0) == 0xF0) { FinePortamentoDown(pChn, param & 0x0F); return; } else if ((param & 0xF0) == 0xE0 && GetType() != MOD_TYPE_DBM) { ExtraFinePortamentoDown(pChn, param & 0x0F); return; } } if(GetType() != MOD_TYPE_DBM) { // DBM only has fine slides, no extra-fine slides. return; } } if(!pChn->isFirstTick || (m_PlayState.m_nMusicSpeed == 1 && m_playBehaviour[kSlidesAtSpeed1]) || GetType() == MOD_TYPE_669) { DoFreqSlide(pChn, int(param) * 4); } } // Send portamento commands to plugins void CSoundFile::MidiPortamento(CHANNELINDEX nChn, int param, bool doFineSlides) { int actualParam = mpt::abs(param); int pitchBend = 0; // Old MIDI Pitch Bends: // - Applied on every tick // - No fine pitch slides (they are interpreted as normal slides) // New MIDI Pitch Bends: // - Behaviour identical to sample pitch bends if the instrument's PWD parameter corresponds to the actual VSTi setting. if(doFineSlides && actualParam >= 0xE0 && !m_playBehaviour[kOldMIDIPitchBends]) { if(m_PlayState.Chn[nChn].isFirstTick) { // Extra fine slide... pitchBend = (actualParam & 0x0F) * sgn(param); if(actualParam >= 0xF0) { // ... or just a fine slide! pitchBend *= 4; } } } else if(!m_PlayState.Chn[nChn].isFirstTick || m_playBehaviour[kOldMIDIPitchBends]) { // Regular slide pitchBend = param * 4; } if(pitchBend) { #ifndef NO_PLUGINS IMixPlugin *plugin = GetChannelInstrumentPlugin(nChn); if(plugin != nullptr) { int8 pwd = 13; // Early OpenMPT legacy... Actually it's not *exactly* 13, but close enough... if(m_PlayState.Chn[nChn].pModInstrument != nullptr) { pwd = m_PlayState.Chn[nChn].pModInstrument->midiPWD; } plugin->MidiPitchBend(GetBestMidiChannel(nChn), pitchBend, pwd); } #endif // NO_PLUGINS } } void CSoundFile::FinePortamentoUp(ModChannel *pChn, ModCommand::PARAM param) const { if(GetType() == MOD_TYPE_XM) { // FT2 compatibility: E1x / E2x / X1x / X2x memory is not linked // Test case: Porta-LinkMem.xm if(param) pChn->nOldFinePortaUpDown = (pChn->nOldFinePortaUpDown & 0x0F) | (param << 4); else param = (pChn->nOldFinePortaUpDown >> 4); } else if(GetType() == MOD_TYPE_MT2) { if(param) pChn->nOldFinePortaUpDown = param; else param = pChn->nOldFinePortaUpDown; } if(pChn->isFirstTick) { if ((pChn->nPeriod) && (param)) { if(m_SongFlags[SONG_LINEARSLIDES] && GetType() != MOD_TYPE_XM) { const auto oldPeriod = pChn->nPeriod; pChn->nPeriod = Util::muldivr(pChn->nPeriod, GetLinearSlideUpTable(this, param & 0x0F), 65536); if(oldPeriod == pChn->nPeriod) { if(m_playBehaviour[kHertzInLinearMode] && pChn->nPeriod < Util::MaxValueOfType(pChn->nPeriod)) pChn->nPeriod++; else if(!m_playBehaviour[kHertzInLinearMode] && pChn->nPeriod > 1) pChn->nPeriod--; } } else { pChn->nPeriod -= (int)(param * 4); if (pChn->nPeriod < 1) { pChn->nPeriod = 1; if(GetType() == MOD_TYPE_S3M) { pChn->nFadeOutVol = 0; pChn->dwFlags.set(CHN_NOTEFADE | CHN_FASTVOLRAMP); } } } } } } void CSoundFile::FinePortamentoDown(ModChannel *pChn, ModCommand::PARAM param) const { if(GetType() == MOD_TYPE_XM) { // FT2 compatibility: E1x / E2x / X1x / X2x memory is not linked // Test case: Porta-LinkMem.xm if(param) pChn->nOldFinePortaUpDown = (pChn->nOldFinePortaUpDown & 0xF0) | (param & 0x0F); else param = (pChn->nOldFinePortaUpDown & 0x0F); } else if(GetType() == MOD_TYPE_MT2) { if(param) pChn->nOldFinePortaUpDown = param; else param = pChn->nOldFinePortaUpDown; } if(pChn->isFirstTick) { if ((pChn->nPeriod) && (param)) { if (m_SongFlags[SONG_LINEARSLIDES] && GetType() != MOD_TYPE_XM) { const auto oldPeriod = pChn->nPeriod; pChn->nPeriod = Util::muldivr(pChn->nPeriod, GetLinearSlideDownTable(this, param & 0x0F), 65536); if(oldPeriod == pChn->nPeriod) { if(!m_playBehaviour[kHertzInLinearMode] && pChn->nPeriod < Util::MaxValueOfType(pChn->nPeriod)) pChn->nPeriod++; else if(m_playBehaviour[kHertzInLinearMode] && pChn->nPeriod > 1) pChn->nPeriod--; } } else { pChn->nPeriod += (int)(param * 4); if (pChn->nPeriod > 0xFFFF) pChn->nPeriod = 0xFFFF; } } } } void CSoundFile::ExtraFinePortamentoUp(ModChannel *pChn, ModCommand::PARAM param) const { if(GetType() == MOD_TYPE_XM) { // FT2 compatibility: E1x / E2x / X1x / X2x memory is not linked // Test case: Porta-LinkMem.xm if(param) pChn->nOldExtraFinePortaUpDown = (pChn->nOldExtraFinePortaUpDown & 0x0F) | (param << 4); else param = (pChn->nOldExtraFinePortaUpDown >> 4); } else if(GetType() == MOD_TYPE_MT2) { if(param) pChn->nOldFinePortaUpDown = param; else param = pChn->nOldFinePortaUpDown; } if(pChn->isFirstTick) { if ((pChn->nPeriod) && (param)) { if(m_SongFlags[SONG_LINEARSLIDES] && GetType() != MOD_TYPE_XM) { int oldPeriod = pChn->nPeriod; pChn->nPeriod = Util::muldivr(pChn->nPeriod, GetFineLinearSlideUpTable(this, param & 0x0F), 65536); if(oldPeriod == pChn->nPeriod) pChn->nPeriod++; } else { pChn->nPeriod -= (int)(param); if (pChn->nPeriod < 1) { pChn->nPeriod = 1; if(GetType() == MOD_TYPE_S3M) { pChn->nFadeOutVol = 0; pChn->dwFlags.set(CHN_NOTEFADE | CHN_FASTVOLRAMP); } } } } } } void CSoundFile::ExtraFinePortamentoDown(ModChannel *pChn, ModCommand::PARAM param) const { if(GetType() == MOD_TYPE_XM) { // FT2 compatibility: E1x / E2x / X1x / X2x memory is not linked // Test case: Porta-LinkMem.xm if(param) pChn->nOldExtraFinePortaUpDown = (pChn->nOldExtraFinePortaUpDown & 0xF0) | (param & 0x0F); else param = (pChn->nOldExtraFinePortaUpDown & 0x0F); } else if(GetType() == MOD_TYPE_MT2) { if(param) pChn->nOldFinePortaUpDown = param; else param = pChn->nOldFinePortaUpDown; } if(pChn->isFirstTick) { if ((pChn->nPeriod) && (param)) { if(m_SongFlags[SONG_LINEARSLIDES] && GetType() != MOD_TYPE_XM) { int oldPeriod = pChn->nPeriod; pChn->nPeriod = Util::muldivr(pChn->nPeriod, GetFineLinearSlideDownTable(this, param & 0x0F), 65536); if(oldPeriod == pChn->nPeriod) pChn->nPeriod--; } else { pChn->nPeriod += (int)(param); if (pChn->nPeriod > 0xFFFF) pChn->nPeriod = 0xFFFF; } } } } // Implemented for IMF compatibility, can't actually save this in any formats // Slide up / down every x ticks by y semitones void CSoundFile::NoteSlide(ModChannel *pChn, uint32 param, bool slideUp, bool retrig) const { uint8 x, y; if(m_SongFlags[SONG_FIRSTTICK]) { x = param & 0xF0; if (x) pChn->nNoteSlideSpeed = (x >> 4); y = param & 0x0F; if (y) pChn->nNoteSlideStep = y; pChn->nNoteSlideCounter = pChn->nNoteSlideSpeed; } else { if (--pChn->nNoteSlideCounter == 0) { pChn->nNoteSlideCounter = pChn->nNoteSlideSpeed; // update it pChn->nPeriod = GetPeriodFromNote ((slideUp ? 1 : -1) * pChn->nNoteSlideStep + GetNoteFromPeriod(pChn->nPeriod), 8363, 0); if(retrig) { pChn->position.Set(0); } } } } // Portamento Slide void CSoundFile::TonePortamento(ModChannel *pChn, uint32 param) const { pChn->dwFlags.set(CHN_PORTAMENTO); //IT compatibility 03: Share effect memory with portamento up/down if((!m_SongFlags[SONG_ITCOMPATGXX] && m_playBehaviour[kITPortaMemoryShare]) || GetType() == MOD_TYPE_PLM) { if(param == 0) param = pChn->nOldPortaUp; pChn->nOldPortaUp = pChn->nOldPortaDown = static_cast(param); } if(GetType() == MOD_TYPE_MPT && pChn->pModInstrument && pChn->pModInstrument->pTuning) { //Behavior: Param tells number of finesteps(or 'fullsteps'(notes) with glissando) //to slide per row(not per tick). const int32 old_PortamentoTickSlide = (m_PlayState.m_nTickCount != 0) ? pChn->m_PortamentoTickSlide : 0; if(param) pChn->nPortamentoSlide = param; else if(pChn->nPortamentoSlide == 0) return; if((pChn->nPortamentoDest > 0 && pChn->nPortamentoSlide < 0) || (pChn->nPortamentoDest < 0 && pChn->nPortamentoSlide > 0)) pChn->nPortamentoSlide = -pChn->nPortamentoSlide; pChn->m_PortamentoTickSlide = static_cast((m_PlayState.m_nTickCount + 1.0) * pChn->nPortamentoSlide / m_PlayState.m_nMusicSpeed); if(pChn->dwFlags[CHN_GLISSANDO]) { pChn->m_PortamentoTickSlide *= pChn->pModInstrument->pTuning->GetFineStepCount() + 1; //With glissando interpreting param as notes instead of finesteps. } const int32 slide = pChn->m_PortamentoTickSlide - old_PortamentoTickSlide; if(mpt::abs(pChn->nPortamentoDest) <= mpt::abs(slide)) { if(pChn->nPortamentoDest != 0) { pChn->m_PortamentoFineSteps += pChn->nPortamentoDest; pChn->nPortamentoDest = 0; pChn->m_CalculateFreq = true; } } else { pChn->m_PortamentoFineSteps += slide; pChn->nPortamentoDest -= slide; pChn->m_CalculateFreq = true; } return; } //End candidate MPT behavior. bool doPorta = !pChn->isFirstTick || (GetType() & (MOD_TYPE_DBM | MOD_TYPE_669)) || (m_PlayState.m_nMusicSpeed == 1 && m_playBehaviour[kSlidesAtSpeed1]); if(GetType() == MOD_TYPE_PLM && param >= 0xF0) { param -= 0xF0; doPorta = pChn->isFirstTick; } if(param) { if(GetType() == MOD_TYPE_669) { param *= 10; } pChn->nPortamentoSlide = param * 4; } if(pChn->nPeriod && pChn->nPortamentoDest && doPorta) { if (pChn->nPeriod < pChn->nPortamentoDest) { int32 delta = pChn->nPortamentoSlide; if(m_SongFlags[SONG_LINEARSLIDES] && GetType() != MOD_TYPE_XM) { uint32 n = pChn->nPortamentoSlide / 4; if (n > 255) n = 255; // Return (a*b+c/2)/c - no divide error // Table is 65536*2(n/192) delta = Util::muldivr(pChn->nPeriod, LinearSlideUpTable[n], 65536) - pChn->nPeriod; if (delta < 1) delta = 1; } pChn->nPeriod += delta; if (pChn->nPeriod > pChn->nPortamentoDest) pChn->nPeriod = pChn->nPortamentoDest; } else if (pChn->nPeriod > pChn->nPortamentoDest) { int32 delta = -pChn->nPortamentoSlide; if(m_SongFlags[SONG_LINEARSLIDES] && GetType() != MOD_TYPE_XM) { uint32 n = pChn->nPortamentoSlide / 4; if (n > 255) n = 255; delta = Util::muldivr(pChn->nPeriod, LinearSlideDownTable[n], 65536) - pChn->nPeriod; if (delta > -1) delta = -1; } pChn->nPeriod += delta; if (pChn->nPeriod < pChn->nPortamentoDest) pChn->nPeriod = pChn->nPortamentoDest; } } // IT compatibility 23. Portamento with no note // ProTracker also disables portamento once the target is reached. // Test case: PortaTarget.mod if(pChn->nPeriod == pChn->nPortamentoDest && (m_playBehaviour[kITPortaTargetReached] || GetType() == MOD_TYPE_MOD)) pChn->nPortamentoDest = 0; } void CSoundFile::Vibrato(ModChannel *p, uint32 param) const { if (param & 0x0F) p->nVibratoDepth = (param & 0x0F) * 4; if (param & 0xF0) p->nVibratoSpeed = (param >> 4) & 0x0F; p->dwFlags.set(CHN_VIBRATO); } void CSoundFile::FineVibrato(ModChannel *p, uint32 param) const { if (param & 0x0F) p->nVibratoDepth = param & 0x0F; if (param & 0xF0) p->nVibratoSpeed = (param >> 4) & 0x0F; p->dwFlags.set(CHN_VIBRATO); // ST3 compatibility: Do not distinguish between vibrato types in effect memory // Test case: VibratoTypeChange.s3m if(m_playBehaviour[kST3VibratoMemory] && (param & 0x0F)) { p->nVibratoDepth *= 4u; } } void CSoundFile::Panbrello(ModChannel *p, uint32 param) const { if (param & 0x0F) p->nPanbrelloDepth = param & 0x0F; if (param & 0xF0) p->nPanbrelloSpeed = (param >> 4) & 0x0F; } void CSoundFile::Panning(ModChannel *pChn, uint32 param, PanningType panBits) const { // No panning in ProTracker mode if(m_playBehaviour[kMODIgnorePanning]) { return; } // IT Compatibility (and other trackers as well): panning disables surround (unless panning in rear channels is enabled, which is not supported by the original trackers anyway) if (!m_SongFlags[SONG_SURROUNDPAN] && (panBits == Pan8bit || m_playBehaviour[kPanOverride])) { pChn->dwFlags.reset(CHN_SURROUND); } if(panBits == Pan4bit) { // 0...15 panning pChn->nPan = (param * 256 + 8) / 15; } else if(panBits == Pan6bit) { // 0...64 panning if(param > 64) param = 64; pChn->nPan = param * 4; } else { if(!(GetType() & (MOD_TYPE_S3M | MOD_TYPE_DSM | MOD_TYPE_AMF | MOD_TYPE_MTM))) { // Real 8-bit panning pChn->nPan = param; } else { // 7-bit panning + surround if(param <= 0x80) { pChn->nPan = param << 1; } else if(param == 0xA4) { pChn->dwFlags.set(CHN_SURROUND); pChn->nPan = 0x80; } } } pChn->dwFlags.set(CHN_FASTVOLRAMP); pChn->nRestorePanOnNewNote = 0; //IT compatibility 20. Set pan overrides random pan if(m_playBehaviour[kPanOverride]) { pChn->nPanSwing = 0; pChn->nPanbrelloOffset = 0; } } void CSoundFile::VolumeSlide(ModChannel *pChn, ModCommand::PARAM param) { if (param) pChn->nOldVolumeSlide = param; else param = pChn->nOldVolumeSlide; if((GetType() & (MOD_TYPE_MOD | MOD_TYPE_XM | MOD_TYPE_MT2 | MOD_TYPE_MED | MOD_TYPE_DIGI | MOD_TYPE_STP | MOD_TYPE_DTM))) { // MOD / XM nibble priority if((param & 0xF0) != 0) { param &= 0xF0; } else { param &= 0x0F; } } int newvolume = pChn->nVolume; if(!(GetType() & (MOD_TYPE_MOD | MOD_TYPE_XM | MOD_TYPE_AMF0 | MOD_TYPE_MED | MOD_TYPE_DIGI))) { if ((param & 0x0F) == 0x0F) //Fine upslide or slide -15 { if (param & 0xF0) //Fine upslide { FineVolumeUp(pChn, (param >> 4), false); return; } else //Slide -15 { if(pChn->isFirstTick && !m_SongFlags[SONG_FASTVOLSLIDES]) { newvolume -= 0x0F * 4; } } } else if ((param & 0xF0) == 0xF0) //Fine downslide or slide +15 { if (param & 0x0F) //Fine downslide { FineVolumeDown(pChn, (param & 0x0F), false); return; } else //Slide +15 { if(pChn->isFirstTick && !m_SongFlags[SONG_FASTVOLSLIDES]) { newvolume += 0x0F * 4; } } } } if(!pChn->isFirstTick || m_SongFlags[SONG_FASTVOLSLIDES] || (m_PlayState.m_nMusicSpeed == 1 && GetType() == MOD_TYPE_DBM)) { // IT compatibility: Ignore slide commands with both nibbles set. if (param & 0x0F) { if(!(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) || (param & 0xF0) == 0) newvolume -= (int)((param & 0x0F) * 4); } else { newvolume += (int)((param & 0xF0) >> 2); } if (GetType() == MOD_TYPE_MOD) pChn->dwFlags.set(CHN_FASTVOLRAMP); } newvolume = Clamp(newvolume, 0, 256); pChn->nVolume = newvolume; } void CSoundFile::PanningSlide(ModChannel *pChn, ModCommand::PARAM param, bool memory) { if(memory) { // FT2 compatibility: Use effect memory (lxx and rxx in XM shouldn't use effect memory). // Test case: PanSlideMem.xm if(param) pChn->nOldPanSlide = param; else param = pChn->nOldPanSlide; } if((GetType() & (MOD_TYPE_XM | MOD_TYPE_MT2))) { // XM nibble priority if((param & 0xF0) != 0) { param &= 0xF0; } else { param &= 0x0F; } } int32 nPanSlide = 0; if(!(GetType() & (MOD_TYPE_XM | MOD_TYPE_MT2))) { if (((param & 0x0F) == 0x0F) && (param & 0xF0)) { if(m_SongFlags[SONG_FIRSTTICK]) { param = (param & 0xF0) / 4u; nPanSlide = - (int)param; } } else if (((param & 0xF0) == 0xF0) && (param & 0x0F)) { if(m_SongFlags[SONG_FIRSTTICK]) { nPanSlide = (param & 0x0F) * 4u; } } else if(!m_SongFlags[SONG_FIRSTTICK]) { if (param & 0x0F) { // IT compatibility: Ignore slide commands with both nibbles set. if(!(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) || (param & 0xF0) == 0) nPanSlide = (int)((param & 0x0F) * 4u); } else { nPanSlide = -(int)((param & 0xF0) / 4u); } } } else { if(!m_SongFlags[SONG_FIRSTTICK]) { if (param & 0xF0) { nPanSlide = (int)((param & 0xF0) / 4u); } else { nPanSlide = -(int)((param & 0x0F) * 4u); } // FT2 compatibility: FT2's panning slide is like IT's fine panning slide (not as deep) if(m_playBehaviour[kFT2PanSlide]) nPanSlide /= 4; } } if (nPanSlide) { nPanSlide += pChn->nPan; nPanSlide = Clamp(nPanSlide, 0, 256); pChn->nPan = nPanSlide; pChn->nRestorePanOnNewNote = 0; } } void CSoundFile::FineVolumeUp(ModChannel *pChn, ModCommand::PARAM param, bool volCol) const { if(GetType() == MOD_TYPE_XM) { // FT2 compatibility: EAx / EBx memory is not linked // Test case: FineVol-LinkMem.xm if(param) pChn->nOldFineVolUpDown = (param << 4) | (pChn->nOldFineVolUpDown & 0x0F); else param = (pChn->nOldFineVolUpDown >> 4); } else if(volCol) { if(param) pChn->nOldVolParam = param; else param = pChn->nOldVolParam; } else { if(param) pChn->nOldFineVolUpDown = param; else param = pChn->nOldFineVolUpDown; } if(pChn->isFirstTick) { pChn->nVolume += param * 4; if(pChn->nVolume > 256) pChn->nVolume = 256; if(GetType() & MOD_TYPE_MOD) pChn->dwFlags.set(CHN_FASTVOLRAMP); } } void CSoundFile::FineVolumeDown(ModChannel *pChn, ModCommand::PARAM param, bool volCol) const { if(GetType() == MOD_TYPE_XM) { // FT2 compatibility: EAx / EBx memory is not linked // Test case: FineVol-LinkMem.xm if(param) pChn->nOldFineVolUpDown = param | (pChn->nOldFineVolUpDown & 0xF0); else param = (pChn->nOldFineVolUpDown & 0x0F); } else if(volCol) { if(param) pChn->nOldVolParam = param; else param = pChn->nOldVolParam; } else { if(param) pChn->nOldFineVolUpDown = param; else param = pChn->nOldFineVolUpDown; } if(pChn->isFirstTick) { pChn->nVolume -= param * 4; if(pChn->nVolume < 0) pChn->nVolume = 0; if(GetType() & MOD_TYPE_MOD) pChn->dwFlags.set(CHN_FASTVOLRAMP); } } void CSoundFile::Tremolo(ModChannel *pChn, uint32 param) const { if (param & 0x0F) pChn->nTremoloDepth = (param & 0x0F) << 2; if (param & 0xF0) pChn->nTremoloSpeed = (param >> 4) & 0x0F; pChn->dwFlags.set(CHN_TREMOLO); } void CSoundFile::ChannelVolSlide(ModChannel *pChn, ModCommand::PARAM param) const { int32 nChnSlide = 0; if (param) pChn->nOldChnVolSlide = param; else param = pChn->nOldChnVolSlide; if (((param & 0x0F) == 0x0F) && (param & 0xF0)) { if(m_SongFlags[SONG_FIRSTTICK]) nChnSlide = param >> 4; } else if (((param & 0xF0) == 0xF0) && (param & 0x0F)) { if(m_SongFlags[SONG_FIRSTTICK]) nChnSlide = - (int)(param & 0x0F); } else { if(!m_SongFlags[SONG_FIRSTTICK]) { if (param & 0x0F) { if(!(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT | MOD_TYPE_J2B | MOD_TYPE_DBM)) || (param & 0xF0) == 0) nChnSlide = -(int)(param & 0x0F); } else { nChnSlide = (int)((param & 0xF0) >> 4); } } } if (nChnSlide) { nChnSlide += pChn->nGlobalVol; nChnSlide = Clamp(nChnSlide, 0, 64); pChn->nGlobalVol = nChnSlide; } } void CSoundFile::ExtendedMODCommands(CHANNELINDEX nChn, ModCommand::PARAM param) { ModChannel *pChn = &m_PlayState.Chn[nChn]; uint8 command = param & 0xF0; param &= 0x0F; switch(command) { // E0x: Set Filter case 0x00: for(CHANNELINDEX chn = 0; chn < GetNumChannels(); chn++) { m_PlayState.Chn[chn].dwFlags.set(CHN_AMIGAFILTER, !(param & 1)); } break; // E1x: Fine Portamento Up case 0x10: if ((param) || (GetType() & (MOD_TYPE_XM|MOD_TYPE_MT2))) FinePortamentoUp(pChn, param); break; // E2x: Fine Portamento Down case 0x20: if ((param) || (GetType() & (MOD_TYPE_XM|MOD_TYPE_MT2))) FinePortamentoDown(pChn, param); break; // E3x: Set Glissando Control case 0x30: pChn->dwFlags.set(CHN_GLISSANDO, param != 0); break; // E4x: Set Vibrato WaveForm case 0x40: pChn->nVibratoType = param & 0x07; break; // E5x: Set FineTune case 0x50: if(!m_SongFlags[SONG_FIRSTTICK]) { break; } if(GetType() & (MOD_TYPE_MOD | MOD_TYPE_DIGI | MOD_TYPE_AMF0 | MOD_TYPE_MED)) { pChn->nFineTune = MOD2XMFineTune(param); if(pChn->nPeriod && pChn->rowCommand.IsNote()) pChn->nPeriod = GetPeriodFromNote(pChn->nNote, pChn->nFineTune, pChn->nC5Speed); } else if(pChn->rowCommand.IsNote()) { pChn->nFineTune = MOD2XMFineTune(param - 8); if(pChn->nPeriod) pChn->nPeriod = GetPeriodFromNote(pChn->nNote, pChn->nFineTune, pChn->nC5Speed); } break; // E6x: Pattern Loop // E7x: Set Tremolo WaveForm case 0x70: pChn->nTremoloType = param & 0x07; break; // E8x: Set 4-bit Panning case 0x80: if(m_SongFlags[SONG_FIRSTTICK]) { Panning(pChn, param, Pan4bit); } break; // E9x: Retrig case 0x90: RetrigNote(nChn, param); break; // EAx: Fine Volume Up case 0xA0: if ((param) || (GetType() & (MOD_TYPE_XM|MOD_TYPE_MT2))) FineVolumeUp(pChn, param, false); break; // EBx: Fine Volume Down case 0xB0: if ((param) || (GetType() & (MOD_TYPE_XM|MOD_TYPE_MT2))) FineVolumeDown(pChn, param, false); break; // ECx: Note Cut case 0xC0: NoteCut(nChn, param, false); break; // EDx: Note Delay // EEx: Pattern Delay case 0xF0: if(GetType() == MOD_TYPE_MOD) // MOD: Invert Loop { pChn->nEFxSpeed = param; if(m_SongFlags[SONG_FIRSTTICK]) InvertLoop(pChn); } else // XM: Set Active Midi Macro { pChn->nActiveMacro = param; } break; } } void CSoundFile::ExtendedS3MCommands(CHANNELINDEX nChn, ModCommand::PARAM param) { ModChannel *pChn = &m_PlayState.Chn[nChn]; uint8 command = param & 0xF0; param &= 0x0F; switch(command) { // S0x: Set Filter // S1x: Set Glissando Control case 0x10: pChn->dwFlags.set(CHN_GLISSANDO, param != 0); break; // S2x: Set FineTune case 0x20: if(!m_SongFlags[SONG_FIRSTTICK]) break; if(GetType() != MOD_TYPE_669) { pChn->nC5Speed = S3MFineTuneTable[param]; pChn->nFineTune = MOD2XMFineTune(param); if (pChn->nPeriod) pChn->nPeriod = GetPeriodFromNote(pChn->nNote, pChn->nFineTune, pChn->nC5Speed); } else if(pChn->pModSample != nullptr) { pChn->nC5Speed = pChn->pModSample->nC5Speed + param * 80; } break; // S3x: Set Vibrato Waveform case 0x30: if(GetType() == MOD_TYPE_S3M) { pChn->nVibratoType = param & 0x03; } else { // IT compatibility: Ignore waveform types > 3 if(m_playBehaviour[kITVibratoTremoloPanbrello]) pChn->nVibratoType = (param < 0x04) ? param : 0; else pChn->nVibratoType = param & 0x07; } break; // S4x: Set Tremolo Waveform case 0x40: if(GetType() == MOD_TYPE_S3M) { pChn->nTremoloType = param & 0x03; } else { // IT compatibility: Ignore waveform types > 3 if(m_playBehaviour[kITVibratoTremoloPanbrello]) pChn->nTremoloType = (param < 0x04) ? param : 0; else pChn->nTremoloType = param & 0x07; } break; // S5x: Set Panbrello Waveform case 0x50: // IT compatibility: Ignore waveform types > 3 if(m_playBehaviour[kITVibratoTremoloPanbrello]) { pChn->nPanbrelloType = (param < 0x04) ? param : 0; pChn->nPanbrelloPos = 0; } else { pChn->nPanbrelloType = param & 0x07; } break; // S6x: Pattern Delay for x frames case 0x60: if(m_SongFlags[SONG_FIRSTTICK] && m_PlayState.m_nTickCount == 0) { // Tick delays are added up. // Scream Tracker 3 does actually not support this command. // We'll use the same behaviour as for Impulse Tracker, as we can assume that // most S3Ms that make use of this command were made with Impulse Tracker. // MPT added this command to the XM format through the X6x effect, so we will use // the same behaviour here as well. // Test cases: PatternDelays.it, PatternDelays.s3m, PatternDelays.xm m_PlayState.m_nFrameDelay += param; } break; // S7x: Envelope Control / Instrument Control case 0x70: if(!m_SongFlags[SONG_FIRSTTICK]) break; switch(param) { case 0: case 1: case 2: { ModChannel *bkp = &m_PlayState.Chn[m_nChannels]; for (CHANNELINDEX i=m_nChannels; inMasterChn == nChn+1) { if (param == 1) { KeyOff(bkp); } else if (param == 2) { bkp->dwFlags.set(CHN_NOTEFADE); } else { bkp->dwFlags.set(CHN_NOTEFADE); bkp->nFadeOutVol = 0; } #ifndef NO_PLUGINS const ModInstrument *pIns = bkp->pModInstrument; IMixPlugin *pPlugin; if(pIns != nullptr && pIns->nMixPlug && (pPlugin = m_MixPlugins[pIns->nMixPlug - 1].pMixPlugin) != nullptr) { pPlugin->MidiCommand(GetBestMidiChannel(nChn), pIns->nMidiProgram, pIns->wMidiBank, bkp->nNote + NOTE_MAX_SPECIAL, 0, nChn); } #endif // NO_PLUGINS } } } break; case 3: pChn->nNNA = NNA_NOTECUT; break; case 4: pChn->nNNA = NNA_CONTINUE; break; case 5: pChn->nNNA = NNA_NOTEOFF; break; case 6: pChn->nNNA = NNA_NOTEFADE; break; case 7: pChn->VolEnv.flags.reset(ENV_ENABLED); break; case 8: pChn->VolEnv.flags.set(ENV_ENABLED); break; case 9: pChn->PanEnv.flags.reset(ENV_ENABLED); break; case 10: pChn->PanEnv.flags.set(ENV_ENABLED); break; case 11: pChn->PitchEnv.flags.reset(ENV_ENABLED); break; case 12: pChn->PitchEnv.flags.set(ENV_ENABLED); break; case 13: // S7D: Enable pitch envelope, force to play as pitch envelope case 14: // S7E: Enable pitch envelope, force to play as filter envelope if(GetType() == MOD_TYPE_MPT) { pChn->PitchEnv.flags.set(ENV_ENABLED); pChn->PitchEnv.flags.set(ENV_FILTER, param != 13); } break; } break; // S8x: Set 4-bit Panning case 0x80: if(m_SongFlags[SONG_FIRSTTICK]) { Panning(pChn, param, Pan4bit); } break; // S9x: Sound Control case 0x90: ExtendedChannelEffect(pChn, param); break; // SAx: Set 64k Offset case 0xA0: if(m_SongFlags[SONG_FIRSTTICK]) { pChn->nOldHiOffset = static_cast(param); if (!m_playBehaviour[kITHighOffsetNoRetrig] && pChn->rowCommand.IsNote()) { SmpLength pos = param << 16; if (pos < pChn->nLength) pChn->position.SetInt(pos); } } break; // SBx: Pattern Loop // SCx: Note Cut case 0xC0: if(param == 0) { //IT compatibility 22. SC0 == SC1 if(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) param = 1; // ST3 doesn't cut notes with SC0 else if(GetType() == MOD_TYPE_S3M) return; } // S3M/IT compatibility: Note Cut really cuts notes and does not just mute them (so that following volume commands could restore the sample) // Test case: scx.it NoteCut(nChn, param, m_playBehaviour[kITSCxStopsSample] || GetType() == MOD_TYPE_S3M); break; // SDx: Note Delay // SEx: Pattern Delay for x rows // SFx: S3M: Not used, IT: Set Active Midi Macro case 0xF0: if(GetType() != MOD_TYPE_S3M) { pChn->nActiveMacro = static_cast(param); } break; } } void CSoundFile::ExtendedChannelEffect(ModChannel *pChn, uint32 param) { // S9x and X9x commands (S3M/XM/IT only) if(!m_SongFlags[SONG_FIRSTTICK]) return; switch(param & 0x0F) { // S90: Surround Off case 0x00: pChn->dwFlags.reset(CHN_SURROUND); break; // S91: Surround On case 0x01: pChn->dwFlags.set(CHN_SURROUND); pChn->nPan = 128; break; //////////////////////////////////////////////////////////// // ModPlug Extensions // S98: Reverb Off case 0x08: pChn->dwFlags.reset(CHN_REVERB); pChn->dwFlags.set(CHN_NOREVERB); break; // S99: Reverb On case 0x09: pChn->dwFlags.reset(CHN_NOREVERB); pChn->dwFlags.set(CHN_REVERB); break; // S9A: 2-Channels surround mode case 0x0A: m_SongFlags.reset(SONG_SURROUNDPAN); break; // S9B: 4-Channels surround mode case 0x0B: m_SongFlags.set(SONG_SURROUNDPAN); break; // S9C: IT Filter Mode case 0x0C: m_SongFlags.reset(SONG_MPTFILTERMODE); break; // S9D: MPT Filter Mode case 0x0D: m_SongFlags.set(SONG_MPTFILTERMODE); break; // S9E: Go forward case 0x0E: pChn->dwFlags.reset(CHN_PINGPONGFLAG); break; // S9F: Go backward (and set playback position to the end if sample just started) case 0x0F: if(pChn->position.IsZero() && pChn->nLength && (pChn->rowCommand.IsNote() || !pChn->dwFlags[CHN_LOOP])) { pChn->position.Set(pChn->nLength - 1, SamplePosition::fractMax); } pChn->dwFlags.set(CHN_PINGPONGFLAG); break; } } void CSoundFile::InvertLoop(ModChannel *pChn) { // EFx implementation for MOD files (PT 1.1A and up: Invert Loop) // This effect trashes samples. Thanks to 8bitbubsy for making this work. :) if(GetType() != MOD_TYPE_MOD || pChn->nEFxSpeed == 0) return; // we obviously also need a sample for this ModSample *pModSample = const_cast(pChn->pModSample); if(pModSample == nullptr || pModSample->pSample == nullptr || !pModSample->uFlags[CHN_LOOP] || pModSample->uFlags[CHN_16BIT]) return; pChn->nEFxDelay += ModEFxTable[pChn->nEFxSpeed & 0x0F]; if((pChn->nEFxDelay & 0x80) == 0) return; // only applied if the "delay" reaches 128 pChn->nEFxDelay = 0; if (++pChn->nEFxOffset >= pModSample->nLoopEnd - pModSample->nLoopStart) pChn->nEFxOffset = 0; // TRASH IT!!! (Yes, the sample!) uint8 &sample = static_cast(pModSample->pSample)[pModSample->nLoopStart + pChn->nEFxOffset]; sample = ~sample; ctrlSmp::PrecomputeLoops(*pModSample, *this, false); } // Process a MIDI Macro. // Parameters: // [in] nChn: Mod channel to apply macro on // [in] isSmooth: If true, internal macros are interpolated between two rows // [in] macro: Actual MIDI Macro string // [in] param: Parameter for parametric macros (Z00 - Z7F) // [in] plugin: Plugin to send MIDI message to (if not specified but needed, it is autodetected) void CSoundFile::ProcessMIDIMacro(CHANNELINDEX nChn, bool isSmooth, const char *macro, uint8 param, PLUGINDEX plugin) { ModChannel &chn = m_PlayState.Chn[nChn]; const ModInstrument *pIns = GetNumInstruments() ? chn.pModInstrument : nullptr; unsigned char out[MACRO_LENGTH]; uint32 outPos = 0; // output buffer position, which also equals the number of complete bytes const uint8 lastZxxParam = chn.lastZxxParam; bool firstNibble = true; for(uint32 pos = 0; pos < (MACRO_LENGTH - 1) && macro[pos]; pos++) { bool isNibble = false; // did we parse a nibble or a byte value? unsigned char data = 0; // data that has just been parsed // Parse next macro byte... See Impulse Tracker's MIDI.TXT for detailed information on each possible character. if(macro[pos] >= '0' && macro[pos] <= '9') { isNibble = true; data = (unsigned char)macro[pos] - '0'; } else if(macro[pos] >= 'A' && macro[pos] <= 'F') { isNibble = true; data = (unsigned char)macro[pos] - 'A' + 0x0A; } else if(macro[pos] == 'c') // c: MIDI channel { isNibble = true; data = (unsigned char)GetBestMidiChannel(nChn); } else if(macro[pos] == 'n') // n: note value (last triggered note) { if(ModCommand::IsNote(chn.nLastNote)) { data = (unsigned char)(chn.nLastNote - NOTE_MIN); } } else if(macro[pos] == 'v') // v: velocity { // This is "almost" how IT does it - apparently, IT seems to lag one row behind on global volume or channel volume changes. const int swing = (m_playBehaviour[kITSwingBehaviour] || m_playBehaviour[kMPTOldSwingBehaviour]) ? chn.nVolSwing : 0; const int vol = Util::muldiv((chn.nVolume + swing) * m_PlayState.m_nGlobalVolume, chn.nGlobalVol * chn.nInsVol, 1 << 20); data = (unsigned char)Clamp(vol / 2, 1, 127); //data = (unsigned char)MIN((chn.nVolume * chn.nGlobalVol * m_nGlobalVolume) >> (1 + 6 + 8), 127); } else if(macro[pos] == 'u') // u: volume (calculated) { // Same note as with velocity applies here, but apparently also for instrument / sample volumes? const int vol = Util::muldiv(chn.nCalcVolume * m_PlayState.m_nGlobalVolume, chn.nGlobalVol * chn.nInsVol, 1 << 26); data = (unsigned char)Clamp(vol / 2, 1, 127); //data = (unsigned char)MIN((chn.nCalcVolume * chn.nGlobalVol * m_nGlobalVolume) >> (7 + 6 + 8), 127); } else if(macro[pos] == 'x') // x: pan set { data = (unsigned char)std::min(chn.nPan / 2, 127); } else if(macro[pos] == 'y') // y: calculated pan { data = (unsigned char)std::min(chn.nRealPan / 2, 127); } else if(macro[pos] == 'a') // a: high byte of bank select { if(pIns && pIns->wMidiBank) { data = (unsigned char)(((pIns->wMidiBank - 1) >> 7) & 0x7F); } } else if(macro[pos] == 'b') // b: low byte of bank select { if(pIns && pIns->wMidiBank) { data = (unsigned char)((pIns->wMidiBank - 1) & 0x7F); } } else if(macro[pos] == 'p') // p: program select { if(pIns && pIns->nMidiProgram) { data = (unsigned char)((pIns->nMidiProgram - 1) & 0x7F); } } else if(macro[pos] == 'z') // z: macro data { data = param & 0x7F; if(isSmooth && chn.lastZxxParam < 0x80 && (outPos < 3 || out[outPos - 3] != 0xF0 || out[outPos - 2] < 0xF0)) { // Interpolation for external MIDI messages - interpolation for internal messages // is handled separately to allow for more than 7-bit granularity where it's possible data = (uint8)CalculateSmoothParamChange((float)lastZxxParam, (float)data); } chn.lastZxxParam = data; } else // unrecognized byte (e.g. space char) { continue; } // Append parsed data if(isNibble) // parsed a nibble (constant or 'c' variable) { if(firstNibble) { out[outPos] = data; } else { out[outPos] = (out[outPos] << 4) | data; outPos++; } firstNibble = !firstNibble; } else // parsed a byte (variable) { if(!firstNibble) // From MIDI.TXT: '9n' is exactly the same as '09 n' or '9 n' -- so finish current byte first { outPos++; } out[outPos++] = data; firstNibble = true; } } if(!firstNibble) { // Finish current byte outPos++; } if(outPos == 0) { // Nothing there to send! return; } // Macro string has been parsed and translated, now send the message(s)... uint32 sendPos = 0; while(sendPos < outPos) { uint32 sendLen = 0; if(out[sendPos] == 0xF0) { // SysEx start if((outPos - sendPos >= 4) && (out[sendPos + 1] == 0xF0 || out[sendPos + 1] == 0xF1)) { // Internal macro (normal (F0F0) or extended (F0F1)), 4 bytes long sendLen = 4; } else { // SysEx message, find end of message for(uint32 i = sendPos + 1; i < outPos; i++) { if(out[i] == 0xF7) { // Found end of SysEx message sendLen = i - sendPos + 1; break; } } if(sendLen == 0) { // Didn't find end, so "invent" end of SysEx message out[outPos++] = 0xF7; sendLen = outPos - sendPos; } } } else { // Other MIDI messages, find beginning of next message while(sendPos + (++sendLen) < outPos) { if((out[sendPos + sendLen] & 0x80) != 0) { // Next message begins here. break; } } } if(sendLen == 0) { break; } uint32 bytesSent = SendMIDIData(nChn, isSmooth, out + sendPos, sendLen, plugin); // Ideally (if there's no error in the macro data), we should have sendLen == bytesSent. if(bytesSent > 0) { sendPos += bytesSent; } else { sendPos += sendLen; } } } // Calculate smooth MIDI macro slide parameter for current tick. float CSoundFile::CalculateSmoothParamChange(float currentValue, float param) const { MPT_ASSERT(GetNumTicksOnCurrentRow() > m_PlayState.m_nTickCount); const uint32 ticksLeft = GetNumTicksOnCurrentRow() - m_PlayState.m_nTickCount; if(ticksLeft > 1) { // Slide param const float step = (param - currentValue) / (float)ticksLeft; return (currentValue + step); } else { // On last tick, set exact value. return param; } } // Process MIDI macro data parsed by ProcessMIDIMacro... return bytes sent on success, 0 on (parse) failure. uint32 CSoundFile::SendMIDIData(CHANNELINDEX nChn, bool isSmooth, const unsigned char *macro, uint32 macroLen, PLUGINDEX plugin) { if(macroLen < 1) { return 0; } ModChannel *pChn = &m_PlayState.Chn[nChn]; if(macro[0] == 0xF0 && (macro[1] == 0xF0 || macro[1] == 0xF1)) { // Internal device. if(macroLen < 4) { return 0; } const bool isExtended = (macro[1] == 0xF1); const uint8 macroCode = macro[2]; const uint8 param = macro[3]; if(macroCode == 0x00 && !isExtended) { // F0.F0.00.xx: Set CutOff int oldcutoff = pChn->nCutOff; if(param < 0x80) { if(!isSmooth) { pChn->nCutOff = param; } else { pChn->nCutOff = (uint8)CalculateSmoothParamChange((float)pChn->nCutOff, (float)param); } pChn->nRestoreCutoffOnNewNote = 0; } oldcutoff -= pChn->nCutOff; if(oldcutoff < 0) oldcutoff = -oldcutoff; if((pChn->nVolume > 0) || (oldcutoff < 0x10) || !pChn->dwFlags[CHN_FILTER] || (!(pChn->rightVol | pChn->leftVol))) SetupChannelFilter(pChn, !pChn->dwFlags[CHN_FILTER]); return 4; } else if(macroCode == 0x01 && !isExtended) { // F0.F0.01.xx: Set Resonance if(param < 0x80) { pChn->nRestoreResonanceOnNewNote = 0; if(!isSmooth) { pChn->nResonance = param; } else { pChn->nResonance = (uint8)CalculateSmoothParamChange((float)pChn->nResonance, (float)param); } } SetupChannelFilter(pChn, !pChn->dwFlags[CHN_FILTER]); return 4; } else if(macroCode == 0x02 && !isExtended) { // F0.F0.02.xx: Set filter mode (high nibble determines filter mode) if(param < 0x20) { pChn->nFilterMode = (param >> 4); SetupChannelFilter(pChn, !pChn->dwFlags[CHN_FILTER]); } return 4; #ifndef NO_PLUGINS } else if(macroCode == 0x03 && !isExtended) { // F0.F0.03.xx: Set plug dry/wet const PLUGINDEX nPlug = (plugin != 0) ? plugin : GetBestPlugin(nChn, PrioritiseChannel, EvenIfMuted); if ((nPlug) && (nPlug <= MAX_MIXPLUGINS) && param < 0x80) { const float newRatio = 1.0f - (static_cast(param & 0x7F) / 127.0f); if(!isSmooth) { m_MixPlugins[nPlug - 1].fDryRatio = newRatio; } else { m_MixPlugins[nPlug - 1].fDryRatio = CalculateSmoothParamChange(m_MixPlugins[nPlug - 1].fDryRatio, newRatio); } } return 4; } else if((macroCode & 0x80) || isExtended) { // F0.F0.{80|n}.xx / F0.F1.n.xx: Set VST effect parameter n to xx const PLUGINDEX nPlug = (plugin != 0) ? plugin : GetBestPlugin(nChn, PrioritiseChannel, EvenIfMuted); const uint32 plugParam = isExtended ? (0x80 + macroCode) : (macroCode & 0x7F); if((nPlug) && (nPlug <= MAX_MIXPLUGINS)) { IMixPlugin *pPlugin = m_MixPlugins[nPlug - 1].pMixPlugin; if(pPlugin && param < 0x80) { const float fParam = param / 127.0f; if(!isSmooth) { pPlugin->SetParameter(plugParam, fParam); } else { pPlugin->SetParameter(plugParam, CalculateSmoothParamChange(pPlugin->GetParameter(plugParam), fParam)); } } } return 4; #endif // NO_PLUGINS } // If we reach this point, the internal macro was invalid. } else { #ifndef NO_PLUGINS // Not an internal device. Pass on to appropriate plugin. const CHANNELINDEX plugChannel = (nChn < GetNumChannels()) ? nChn + 1 : pChn->nMasterChn; if(plugChannel > 0 && plugChannel <= GetNumChannels()) // XXX do we need this? I guess it might be relevant for previewing notes in the pattern... Or when using this mechanism for volume/panning! { PLUGINDEX nPlug = 0; if(!pChn->dwFlags[CHN_NOFX]) { nPlug = (plugin != 0) ? plugin : GetBestPlugin(nChn, PrioritiseChannel, EvenIfMuted); } if(nPlug > 0 && nPlug <= MAX_MIXPLUGINS) { IMixPlugin *pPlugin = m_MixPlugins[nPlug - 1].pMixPlugin; if (pPlugin != nullptr) { if(macro[0] == 0xF0) { pPlugin->MidiSysexSend(macro, macroLen); } else { for(uint32 pos = 0; pos < macroLen;) { uint32 len = std::min(MIDIEvents::GetEventLength(macro[pos]), macroLen - pos); uint32 curData = 0; memcpy(&curData, macro + pos, len); pPlugin->MidiSend(curData); pos += len; } } } } } #else MPT_UNREFERENCED_PARAMETER(plugin); #endif // NO_PLUGINS return macroLen; } return 0; } void CSoundFile::SendMIDINote(CHANNELINDEX chn, uint16 note, uint16 volume) { #ifndef NO_PLUGINS auto &channel = m_PlayState.Chn[chn]; const ModInstrument *pIns = channel.pModInstrument; // instro sends to a midi chan if (pIns && pIns->HasValidMIDIChannel()) { PLUGINDEX nPlug = pIns->nMixPlug; if ((nPlug) && (nPlug <= MAX_MIXPLUGINS)) { IMixPlugin *pPlug = m_MixPlugins[nPlug-1].pMixPlugin; if (pPlug != nullptr) { pPlug->MidiCommand(GetBestMidiChannel(chn), pIns->nMidiProgram, pIns->wMidiBank, note, volume, chn); if(note < NOTE_MIN_SPECIAL) channel.nLeftVU = channel.nRightVU = 0xFF; } } } #endif // NO_PLUGINS } void CSoundFile::SampleOffset(ModChannel &chn, SmpLength param) const { chn.proTrackerOffset += param; if(param >= chn.nLoopEnd && GetType() == MOD_TYPE_MTM && chn.dwFlags[CHN_LOOP] && chn.nLoopEnd > 0) { // Offset wrap-around param = (param - chn.nLoopStart) % (chn.nLoopEnd - chn.nLoopStart) + chn.nLoopStart; } if(GetType() == MOD_TYPE_MDL && chn.dwFlags[CHN_16BIT]) { // Digitrakker really uses byte offsets, not sample offsets. WTF! param /= 2u; } if(chn.rowCommand.IsNote()) { // IT compatibility: If this note is not mapped to a sample, ignore it. // Test case: empty_sample_offset.it if(chn.pModInstrument != nullptr) { SAMPLEINDEX smp = chn.pModInstrument->Keyboard[chn.rowCommand.note - NOTE_MIN]; if(smp == 0 || smp > GetNumSamples()) return; } if(m_SongFlags[SONG_PT_MODE]) { // ProTracker compatbility: PT1/2-style funky 9xx offset command // Test case: ptoffset.mod chn.position.Set(chn.proTrackerOffset); chn.proTrackerOffset += param; } else { chn.position.Set(param); } if (chn.position.GetUInt() >= chn.nLength || (chn.dwFlags[CHN_LOOP] && chn.position.GetUInt() >= chn.nLoopEnd)) { // Offset beyond sample size if (!(GetType() & (MOD_TYPE_XM | MOD_TYPE_MT2 | MOD_TYPE_MOD | MOD_TYPE_MTM))) { // IT Compatibility: Offset if(m_playBehaviour[kITOffset]) { if(m_SongFlags[SONG_ITOLDEFFECTS]) chn.position.Set(chn.nLength); // Old FX: Clip to end of sample else chn.position.Set(0); // Reset to beginning of sample } else { chn.position.Set(chn.nLoopStart); if(m_SongFlags[SONG_ITOLDEFFECTS] && chn.nLength > 4) { chn.position.Set(chn.nLength - 2); } } } else if(m_playBehaviour[kFT2OffsetOutOfRange] || GetType() == MOD_TYPE_MTM) { // FT2 Compatibility: Don't play note if offset is beyond sample length // Test case: 3xx-no-old-samp.xm chn.dwFlags.set(CHN_FASTVOLRAMP); chn.nPeriod = 0; } else if(GetType() == MOD_TYPE_MOD && chn.dwFlags[CHN_LOOP]) { chn.position.Set(chn.nLoopStart); } } } else if ((param < chn.nLength) && (GetType() & (MOD_TYPE_MTM | MOD_TYPE_DMF | MOD_TYPE_MDL | MOD_TYPE_PLM))) { // Some trackers can also call offset effects without notes next to them... chn.position.Set(param); } } // void CSoundFile::ReverseSampleOffset(ModChannel &chn, ModCommand::PARAM param) const { if(chn.pModSample != nullptr) { chn.dwFlags.set(CHN_PINGPONGFLAG); chn.dwFlags.reset(CHN_LOOP); chn.nLength = chn.pModSample->nLength; // If there was a loop, extend sample to whole length. chn.position.Set((chn.nLength - 1) - std::min(SmpLength(param) << 8, chn.nLength - 1), 0); } } void CSoundFile::RetrigNote(CHANNELINDEX nChn, int param, int offset) { // Retrig: bit 8 is set if it's the new XM retrig ModChannel &chn = m_PlayState.Chn[nChn]; int retrigSpeed = param & 0x0F; int16 retrigCount = chn.nRetrigCount; bool doRetrig = false; // IT compatibility 15. Retrigger if(m_playBehaviour[kITRetrigger]) { if(m_PlayState.m_nTickCount == 0 && chn.rowCommand.note) { chn.nRetrigCount = param & 0xf; } else if(!chn.nRetrigCount || !--chn.nRetrigCount) { chn.nRetrigCount = param & 0xf; doRetrig = true; } } else if(m_playBehaviour[kFT2Retrigger] && (param & 0x100)) { // Buggy-like-hell FT2 Rxy retrig! // Test case: retrig.xm if(m_SongFlags[SONG_FIRSTTICK]) { // Here are some really stupid things FT2 does on the first tick. // Test case: RetrigTick0.xm if(chn.rowCommand.instr > 0 && chn.rowCommand.IsNoteOrEmpty()) retrigCount = 1; if(chn.rowCommand.volcmd == VOLCMD_VOLUME && chn.rowCommand.vol != 0) { // I guess this condition simply checked if the volume byte was != 0 in FT2. chn.nRetrigCount = retrigCount; return; } } if(retrigCount >= retrigSpeed) { if(!m_SongFlags[SONG_FIRSTTICK] || !chn.rowCommand.IsNote()) { doRetrig = true; retrigCount = 0; } } } else { // old routines if (GetType() & (MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_MPT)) { if (!retrigSpeed) retrigSpeed = 1; if ((retrigCount) && (!(retrigCount % retrigSpeed))) doRetrig = true; retrigCount++; } else if(GetType() == MOD_TYPE_MTM) { // In MultiTracker, E9x retriggers the last note at exactly the x-th tick of the row doRetrig = m_PlayState.m_nTickCount == static_cast(param & 0x0F) && retrigSpeed != 0; } else { int realspeed = retrigSpeed; // FT2 bug: if a retrig (Rxy) occurs together with a volume command, the first retrig interval is increased by one tick if ((param & 0x100) && (chn.rowCommand.volcmd == VOLCMD_VOLUME) && (chn.rowCommand.param & 0xF0)) realspeed++; if(!m_SongFlags[SONG_FIRSTTICK] || (param & 0x100)) { if (!realspeed) realspeed = 1; if ((!(param & 0x100)) && (m_PlayState.m_nMusicSpeed) && (!(m_PlayState.m_nTickCount % realspeed))) doRetrig = true; retrigCount++; } else if (GetType() & (MOD_TYPE_XM|MOD_TYPE_MT2)) retrigCount = 0; if (retrigCount >= realspeed) { if ((m_PlayState.m_nTickCount) || ((param & 0x100) && (!chn.rowCommand.note))) doRetrig = true; } if(m_playBehaviour[kFT2Retrigger] && param == 0) { // E90 = Retrig instantly, and only once doRetrig = (m_PlayState.m_nTickCount == 0); } } } // IT compatibility: If a sample is shorter than the retrig time (i.e. it stops before the retrig counter hits zero), it is not retriggered. // Test case: retrig-short.it if(chn.nLength == 0 && m_playBehaviour[kITShortSampleRetrig] && !chn.HasMIDIOutput()) { return; } if(doRetrig) { uint32 dv = (param >> 4) & 0x0F; int vol = chn.nVolume; if (dv) { // FT2 compatibility: Retrig + volume will not change volume of retrigged notes if(!m_playBehaviour[kFT2Retrigger] || !(chn.rowCommand.volcmd == VOLCMD_VOLUME)) { if (retrigTable1[dv]) vol = (vol * retrigTable1[dv]) >> 4; else vol += ((int)retrigTable2[dv]) << 2; } Limit(vol, 0, 256); chn.dwFlags.set(CHN_FASTVOLRAMP); } uint32 note = chn.nNewNote; int32 oldPeriod = chn.nPeriod; if (note >= NOTE_MIN && note <= NOTE_MAX && chn.nLength) CheckNNA(nChn, 0, note, true); bool resetEnv = false; if(GetType() & (MOD_TYPE_XM | MOD_TYPE_MT2)) { if((chn.rowCommand.instr) && (param < 0x100)) { InstrumentChange(&chn, chn.rowCommand.instr, false, false); resetEnv = true; } if (param < 0x100) resetEnv = true; } bool fading = chn.dwFlags[CHN_NOTEFADE]; // IT compatibility: Really weird combination of envelopes and retrigger (see Storlek's q.it testcase) // Test case: retrig.it NoteChange(&chn, note, m_playBehaviour[kITRetrigger], resetEnv); // XM compatibility: Prevent NoteChange from resetting the fade flag in case an instrument number + note-off is present. // Test case: RetrigFade.xm if(fading && GetType() == MOD_TYPE_XM) chn.dwFlags.set(CHN_NOTEFADE); chn.nVolume = vol; if(m_nInstruments) { chn.rowCommand.note = static_cast(note); // No retrig without note... #ifndef NO_PLUGINS ProcessMidiOut(nChn); //Send retrig to Midi #endif // NO_PLUGINS } if ((GetType() & (MOD_TYPE_IT|MOD_TYPE_MPT)) && (!chn.rowCommand.note) && (oldPeriod)) chn.nPeriod = oldPeriod; if (!(GetType() & (MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_MPT))) retrigCount = 0; // IT compatibility: see previous IT compatibility comment =) if(m_playBehaviour[kITRetrigger]) chn.position.Set(0); offset--; if(offset >= 0 && offset <= static_cast(CountOf(chn.pModSample->cues)) && chn.pModSample != nullptr) { if(offset == 0) offset = chn.oldOffset; else offset = chn.oldOffset = chn.pModSample->cues[offset - 1]; SampleOffset(chn, offset); } } // buggy-like-hell FT2 Rxy retrig! if(m_playBehaviour[kFT2Retrigger] && (param & 0x100)) retrigCount++; // Now we can also store the retrig value for IT... if(!m_playBehaviour[kITRetrigger]) chn.nRetrigCount = retrigCount; } void CSoundFile::DoFreqSlide(ModChannel *pChn, int32 nFreqSlide) const { if(!pChn->nPeriod) return; if(GetType() == MOD_TYPE_669) { // Like other oldskool trackers, Composer 669 doesn't have linear slides... // But the slides are done in Hertz rather than periods, meaning that they // are more effective in the lower notes (rather than the higher notes). nFreqSlide *= -20; } if(m_SongFlags[SONG_LINEARSLIDES] && GetType() != MOD_TYPE_XM) { // IT Linear slides const auto nOldPeriod = pChn->nPeriod; uint32 n = mpt::abs(nFreqSlide) / 4u; LimitMax(n, 255u); if(n != 0) { pChn->nPeriod = Util::muldivr(pChn->nPeriod, nFreqSlide < 0 ? GetLinearSlideUpTable(this, n) : GetLinearSlideDownTable(this, n), 65536); if(pChn->nPeriod == nOldPeriod) { const bool incPeriod = m_playBehaviour[kHertzInLinearMode] == (nFreqSlide < 0); if(incPeriod && pChn->nPeriod < Util::MaxValueOfType(pChn->nPeriod)) pChn->nPeriod++; else if(!incPeriod && pChn->nPeriod > 1) pChn->nPeriod--; } } } else { pChn->nPeriod += nFreqSlide; } if (pChn->nPeriod < 1) { pChn->nPeriod = 1; if(GetType() == MOD_TYPE_S3M) { pChn->nFadeOutVol = 0; pChn->dwFlags.set(CHN_NOTEFADE | CHN_FASTVOLRAMP); } } } void CSoundFile::NoteCut(CHANNELINDEX nChn, uint32 nTick, bool cutSample) { if (m_PlayState.m_nTickCount == nTick) { ModChannel *pChn = &m_PlayState.Chn[nChn]; if(cutSample) { pChn->increment.Set(0); pChn->nFadeOutVol = 0; pChn->dwFlags.set(CHN_NOTEFADE); } else { pChn->nVolume = 0; } pChn->dwFlags.set(CHN_FASTVOLRAMP); // instro sends to a midi chan SendMIDINote(nChn, /*pChn->nNote+*/NOTE_MAX_SPECIAL, 0); } } void CSoundFile::KeyOff(ModChannel *pChn) const { const bool bKeyOn = !pChn->dwFlags[CHN_KEYOFF]; pChn->dwFlags.set(CHN_KEYOFF); if(pChn->pModInstrument != nullptr && !pChn->VolEnv.flags[ENV_ENABLED]) { pChn->dwFlags.set(CHN_NOTEFADE); } if (!pChn->nLength) return; if (pChn->dwFlags[CHN_SUSTAINLOOP] && pChn->pModSample && bKeyOn) { const ModSample *pSmp = pChn->pModSample; if(pSmp->uFlags[CHN_LOOP]) { if (pSmp->uFlags[CHN_PINGPONGLOOP]) pChn->dwFlags.set(CHN_PINGPONGLOOP); else pChn->dwFlags.reset(CHN_PINGPONGLOOP | CHN_PINGPONGFLAG); pChn->dwFlags.set(CHN_LOOP); pChn->nLength = pSmp->nLength; pChn->nLoopStart = pSmp->nLoopStart; pChn->nLoopEnd = pSmp->nLoopEnd; if (pChn->nLength > pChn->nLoopEnd) pChn->nLength = pChn->nLoopEnd; if(pChn->position.GetUInt() > pChn->nLength) { // Test case: SusAfterLoop.it pChn->position.Set(pChn->position.GetInt() - pChn->nLength + pChn->nLoopStart); } } else { pChn->dwFlags.reset(CHN_LOOP | CHN_PINGPONGLOOP | CHN_PINGPONGFLAG); pChn->nLength = pSmp->nLength; } } if (pChn->pModInstrument) { const ModInstrument *pIns = pChn->pModInstrument; if((pIns->VolEnv.dwFlags[ENV_LOOP] || (GetType() & (MOD_TYPE_XM | MOD_TYPE_MT2 | MOD_TYPE_MDL))) && pIns->nFadeOut != 0) { pChn->dwFlags.set(CHN_NOTEFADE); } if (pIns->VolEnv.nReleaseNode != ENV_RELEASE_NODE_UNSET) { pChn->VolEnv.nEnvValueAtReleaseJump = pIns->VolEnv.GetValueFromPosition(pChn->VolEnv.nEnvPosition, 256); pChn->VolEnv.nEnvPosition = pIns->VolEnv[pIns->VolEnv.nReleaseNode].tick; } } } ////////////////////////////////////////////////////////// // CSoundFile: Global Effects void CSoundFile::SetSpeed(PlayState &playState, uint32 param) const { #ifdef MODPLUG_TRACKER // FT2 appears to be decrementing the tick count before checking for zero, // so it effectively counts down 65536 ticks with speed = 0 (song speed is a 16-bit variable in FT2) if(GetType() == MOD_TYPE_XM && !param) { playState.m_nMusicSpeed = uint16_max; } #endif // MODPLUG_TRACKER if(param > 0) playState.m_nMusicSpeed = param; if(GetType() == MOD_TYPE_STM && param > 0) { playState.m_nMusicSpeed = std::max(param >> 4u, 1); playState.m_nMusicTempo = ConvertST2Tempo(static_cast(param)); } } // Convert a ST2 tempo byte to classic tempo and speed combination TEMPO CSoundFile::ConvertST2Tempo(uint8 tempo) { static const uint8 ST2TempoFactor[] = { 140, 50, 25, 15, 10, 7, 6, 4, 3, 3, 2, 2, 2, 2, 1, 1 }; static const uint32 st2MixingRate = 23863; // Highest possible setting in ST2 // This underflows at tempo 06...0F, and the resulting tick lengths depend on the mixing rate. int32 samplesPerTick = st2MixingRate / (49 - ((ST2TempoFactor[tempo >> 4u] * (tempo & 0x0F)) >> 4u)); if(samplesPerTick <= 0) samplesPerTick += 65536; return TEMPO().SetRaw(Util::muldivrfloor(st2MixingRate, 5 * TEMPO::fractFact, samplesPerTick * 2)); } void CSoundFile::SetTempo(TEMPO param, bool setFromUI) { const CModSpecifications &specs = GetModSpecifications(); // Anything lower than the minimum tempo is considered to be a tempo slide const TEMPO minTempo = (GetType() == MOD_TYPE_MDL) ? TEMPO(1, 0) : TEMPO(32, 0); if(setFromUI) { // Set tempo from UI - ignore slide commands and such. m_PlayState.m_nMusicTempo = Clamp(param, specs.GetTempoMin(), specs.GetTempoMax()); } else if(param >= minTempo && m_SongFlags[SONG_FIRSTTICK] == !m_playBehaviour[kMODTempoOnSecondTick]) { // ProTracker sets the tempo after the first tick. // Note: The case of one tick per row is handled in ProcessRow() instead. // Test case: TempoChange.mod m_PlayState.m_nMusicTempo = std::min(param, specs.GetTempoMax()); } else if(param < minTempo && !m_SongFlags[SONG_FIRSTTICK]) { // Tempo Slide TEMPO tempDiff(param.GetInt() & 0x0F, 0); if((param.GetInt() & 0xF0) == 0x10) m_PlayState.m_nMusicTempo += tempDiff; else m_PlayState.m_nMusicTempo -= tempDiff; TEMPO tempoMin = specs.GetTempoMin(), tempoMax = specs.GetTempoMax(); if(m_playBehaviour[kTempoClamp]) // clamp tempo correctly in compatible mode { tempoMax.Set(255); } Limit(m_PlayState.m_nMusicTempo, tempoMin, tempoMax); } } ROWINDEX CSoundFile::PatternLoop(ModChannel *pChn, uint32 param) { if (param) { // Loop Repeat if(pChn->nPatternLoopCount) { // There's a loop left pChn->nPatternLoopCount--; if(!pChn->nPatternLoopCount) { // IT compatibility 10. Pattern loops (+ same fix for S3M files) // When finishing a pattern loop, the next loop without a dedicated SB0 starts on the first row after the previous loop. if(m_playBehaviour[kITPatternLoopTargetReset] || (GetType() == MOD_TYPE_S3M)) { pChn->nPatternLoop = m_PlayState.m_nRow + 1; } return ROWINDEX_INVALID; } } else { // First time we get into the loop => Set loop count. // IT compatibility 10. Pattern loops (+ same fix for XM / MOD / S3M files) if(!m_playBehaviour[kITFT2PatternLoop] && !(GetType() & (MOD_TYPE_MOD | MOD_TYPE_S3M))) { ModChannel *p = m_PlayState.Chn; for(CHANNELINDEX i = 0; i < GetNumChannels(); i++, p++) if (p != pChn) { // Loop on other channel if(p->nPatternLoopCount) return ROWINDEX_INVALID; } } pChn->nPatternLoopCount = static_cast(param); } m_PlayState.m_nNextPatStartRow = pChn->nPatternLoop; // Nasty FT2 E60 bug emulation! return pChn->nPatternLoop; } else { // Loop Start pChn->nPatternLoop = m_PlayState.m_nRow; } return ROWINDEX_INVALID; } void CSoundFile::GlobalVolSlide(ModCommand::PARAM param, uint8 &nOldGlobalVolSlide) { int32 nGlbSlide = 0; if (param) nOldGlobalVolSlide = param; else param = nOldGlobalVolSlide; if((GetType() & (MOD_TYPE_XM | MOD_TYPE_MT2))) { // XM nibble priority if((param & 0xF0) != 0) { param &= 0xF0; } else { param &= 0x0F; } } if (((param & 0x0F) == 0x0F) && (param & 0xF0)) { if(m_SongFlags[SONG_FIRSTTICK]) nGlbSlide = (param >> 4) * 2; } else if (((param & 0xF0) == 0xF0) && (param & 0x0F)) { if(m_SongFlags[SONG_FIRSTTICK]) nGlbSlide = - (int)((param & 0x0F) * 2); } else { if(!m_SongFlags[SONG_FIRSTTICK]) { if (param & 0xF0) { // IT compatibility: Ignore slide commands with both nibbles set. if(!(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT | MOD_TYPE_IMF | MOD_TYPE_J2B | MOD_TYPE_MID | MOD_TYPE_AMS | MOD_TYPE_AMS2 | MOD_TYPE_DBM)) || (param & 0x0F) == 0) nGlbSlide = (int)((param & 0xF0) >> 4) * 2; } else { nGlbSlide = -(int)((param & 0x0F) * 2); } } } if (nGlbSlide) { if(!(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT | MOD_TYPE_IMF | MOD_TYPE_J2B | MOD_TYPE_MID | MOD_TYPE_AMS | MOD_TYPE_AMS2 | MOD_TYPE_DBM))) nGlbSlide *= 2; nGlbSlide += m_PlayState.m_nGlobalVolume; Limit(nGlbSlide, 0, 256); m_PlayState.m_nGlobalVolume = nGlbSlide; } } ////////////////////////////////////////////////////// // Note/Period/Frequency functions // Find lowest note which has same or lower period as a given period (i.e. the note has the same or higher frequency) uint32 CSoundFile::GetNoteFromPeriod(uint32 period, int32 nFineTune, uint32 nC5Speed) const { if(!period) return 0; if(m_playBehaviour[kFT2Periods]) { // FT2's "RelocateTon" function actually rounds up and down, while GetNoteFromPeriod normally just truncates. nFineTune += 64; } // This essentially implements std::lower_bound, with the difference that we don't need an iterable container. uint32 minNote = NOTE_MIN, maxNote = NOTE_MAX, count = maxNote - minNote + 1; const bool periodIsFreq = PeriodsAreFrequencies(); while(count > 0) { const uint32 step = count / 2, midNote = minNote + step; uint32 n = GetPeriodFromNote(midNote, nFineTune, nC5Speed); if((n > period && !periodIsFreq) || (n < period && periodIsFreq) || !n) { minNote = midNote + 1; count -= step + 1; } else { count = step; } } return minNote; } uint32 CSoundFile::GetPeriodFromNote(uint32 note, int32 nFineTune, uint32 nC5Speed) const { if (note == NOTE_NONE || (note >= NOTE_MIN_SPECIAL)) return 0; note -= NOTE_MIN; if (!UseFinetuneAndTranspose()) { if(GetType() & (MOD_TYPE_MDL | MOD_TYPE_DTM)) { // MDL uses non-linear slides, but their effectiveness does not depend on the middle-C frequency. return (FreqS3MTable[note % 12u] << 4) >> (note / 12); } if(m_SongFlags[SONG_LINEARSLIDES] || GetType() == MOD_TYPE_669) { // In IT linear slide mode, directly use frequency in Hertz rather than periods. if(m_playBehaviour[kHertzInLinearMode] || GetType() == MOD_TYPE_669) return Util::muldiv_unsigned(nC5Speed, LinearSlideUpTable[(note % 12u) * 16u] << (note / 12u), 65536 << 5); else return (FreqS3MTable[note % 12u] << 5) >> (note / 12); } else { if (!nC5Speed) nC5Speed = 8363; LimitMax(nC5Speed, uint32_max >> (note / 12u)); //(a*b)/c return Util::muldiv_unsigned(8363, (FreqS3MTable[note % 12u] << 5), nC5Speed << (note / 12u)); //8363 * freq[note%12] / nC5Speed * 2^(5-note/12) } } else if (GetType() == MOD_TYPE_XM) { if (note < 12) note = 12; note -= 12; // FT2 Compatibility: The lower three bits of the finetune are truncated. // Test case: Finetune-Precision.xm if(m_playBehaviour[kFT2FinetunePrecision]) { nFineTune &= ~7; } if(m_SongFlags[SONG_LINEARSLIDES]) { int l = ((NOTE_MAX - note) << 6) - (nFineTune / 2); if (l < 1) l = 1; return static_cast(l); } else { int finetune = nFineTune; uint32 rnote = (note % 12) << 3; uint32 roct = note / 12; int rfine = finetune / 16; int i = rnote + rfine + 8; Limit(i , 0, 103); uint32 per1 = XMPeriodTable[i]; if(finetune < 0) { rfine--; finetune = -finetune; } else rfine++; i = rnote+rfine+8; if (i < 0) i = 0; if (i >= 104) i = 103; uint32 per2 = XMPeriodTable[i]; rfine = finetune & 0x0F; per1 *= 16-rfine; per2 *= rfine; return ((per1 + per2) << 1) >> roct; } } else { nFineTune = XM2MODFineTune(nFineTune); if ((nFineTune) || (note < 36) || (note >= 36 + 6 * 12)) return (ProTrackerTunedPeriods[nFineTune * 12u + note % 12u] << 5) >> (note / 12u); else return (ProTrackerPeriodTable[note - 36] << 2); } } // Converts period value to sample frequency. Return value is fixed point, with FREQ_FRACBITS fractional bits. uint32 CSoundFile::GetFreqFromPeriod(uint32 period, uint32 c5speed, int32 nPeriodFrac) const { if (!period) return 0; if (GetType() == MOD_TYPE_XM) { if(m_playBehaviour[kFT2Periods]) { // FT2 compatibility: Period is a 16-bit value in FT2, and it overflows happily. // Test case: FreqWraparound.xm period &= 0xFFFF; } if(m_SongFlags[SONG_LINEARSLIDES]) { uint32 octave; if(m_playBehaviour[kFT2Periods]) { // Under normal circumstances, this calculation returns the same values as the non-compatible one. // However, once the 12 octaves are exceeded (through portamento slides), the octave shift goes // crazy in FT2, meaning that the frequency wraps around randomly... // The entries in FT2's conversion table are four times as big, hence we have to do an additional shift by two bits. // Test case: FreqWraparound.xm // 12 octaves * (12 * 64) LUT entries = 9216, add 767 for rounding uint32 div = ((9216u + 767u - period) / 768); octave = ((14 - div) & 0x1F); } else { octave = (period / 768) + 2; } return (XMLinearTable[period % 768] << (FREQ_FRACBITS + 2)) >> octave; } else { if(!period) period = 1; return ((8363 * 1712L) << FREQ_FRACBITS) / period; } } else if (UseFinetuneAndTranspose()) { return ((3546895L * 4) << FREQ_FRACBITS) / period; } else if(GetType() == MOD_TYPE_669) { // We only really use c5speed for the finetune pattern command. All samples in 669 files have the same middle-C speed (imported as 8363 Hz). return (period + c5speed - 8363) << FREQ_FRACBITS; } else if(GetType() & (MOD_TYPE_MDL | MOD_TYPE_DTM)) { LimitMax(period, Util::MaxValueOfType(period) >> 8); if (!c5speed) c5speed = 8363; return Util::muldiv_unsigned(c5speed, (1712L << 7) << FREQ_FRACBITS, (period << 8) + nPeriodFrac); } else { LimitMax(period, Util::MaxValueOfType(period) >> 8); if(m_SongFlags[SONG_LINEARSLIDES]) { if(m_playBehaviour[kHertzInLinearMode]) { // IT linear slides already use frequencies instead of periods. static_assert(FREQ_FRACBITS <= 8, "Check this shift operator"); return uint32(((uint64(period) << 8) + nPeriodFrac) >> (8 - FREQ_FRACBITS)); } else { if (!c5speed) c5speed = 8363; return Util::muldiv_unsigned(c5speed, (1712L << 8) << FREQ_FRACBITS, (period << 8) + nPeriodFrac); } } else { return Util::muldiv_unsigned(8363, (1712L << 8) << FREQ_FRACBITS, (period << 8) + nPeriodFrac); } } } PLUGINDEX CSoundFile::GetBestPlugin(CHANNELINDEX nChn, PluginPriority priority, PluginMutePriority respectMutes) const { if (nChn >= MAX_CHANNELS) //Check valid channel number { return 0; } //Define search source order PLUGINDEX nPlugin = 0; switch (priority) { case ChannelOnly: nPlugin = GetChannelPlugin(nChn, respectMutes); break; case InstrumentOnly: nPlugin = GetActiveInstrumentPlugin(nChn, respectMutes); break; case PrioritiseInstrument: nPlugin = GetActiveInstrumentPlugin(nChn, respectMutes); if ((!nPlugin) || (nPlugin > MAX_MIXPLUGINS)) { nPlugin = GetChannelPlugin(nChn, respectMutes); } break; case PrioritiseChannel: nPlugin = GetChannelPlugin(nChn, respectMutes); if ((!nPlugin) || (nPlugin > MAX_MIXPLUGINS)) { nPlugin = GetActiveInstrumentPlugin(nChn, respectMutes); } break; } return nPlugin; // 0 Means no plugin found. } PLUGINDEX CSoundFile::GetChannelPlugin(CHANNELINDEX nChn, PluginMutePriority respectMutes) const { const ModChannel &channel = m_PlayState.Chn[nChn]; PLUGINDEX nPlugin; if((respectMutes == RespectMutes && channel.dwFlags[CHN_MUTE]) || channel.dwFlags[CHN_NOFX]) { nPlugin = 0; } else { // If it looks like this is an NNA channel, we need to find the master channel. // This ensures we pick up the right ChnSettings. // NB: nMasterChn == 0 means no master channel, so we need to -1 to get correct index. if (nChn >= m_nChannels && channel.nMasterChn > 0) { nChn = channel.nMasterChn - 1; } if(nChn < MAX_BASECHANNELS) { nPlugin = ChnSettings[nChn].nMixPlugin; } else { nPlugin = 0; } } return nPlugin; } PLUGINDEX CSoundFile::GetActiveInstrumentPlugin(CHANNELINDEX nChn, PluginMutePriority respectMutes) const { // Unlike channel settings, pModInstrument is copied from the original chan to the NNA chan, // so we don't need to worry about finding the master chan. PLUGINDEX plug = 0; if(m_PlayState.Chn[nChn].pModInstrument != nullptr) { if(respectMutes == RespectMutes && m_PlayState.Chn[nChn].pModSample && m_PlayState.Chn[nChn].pModSample->uFlags[CHN_MUTE]) { plug = 0; } else { plug = m_PlayState.Chn[nChn].pModInstrument->nMixPlug; } } return plug; } // Retrieve the plugin that is associated with the channel's current instrument. // No plugin is returned if the channel is muted or if the instrument doesn't have a MIDI channel set up, // As this is meant to be used with instrument plugins. IMixPlugin *CSoundFile::GetChannelInstrumentPlugin(CHANNELINDEX chn) const { #ifndef NO_PLUGINS if(m_PlayState.Chn[chn].dwFlags[CHN_MUTE | CHN_SYNCMUTE]) { // Don't process portamento on muted channels. Note that this might have a side-effect // on other channels which trigger notes on the same MIDI channel of the same plugin, // as those won't be pitch-bent anymore. return nullptr; } if(m_PlayState.Chn[chn].HasMIDIOutput()) { const ModInstrument *pIns = m_PlayState.Chn[chn].pModInstrument; // Instrument sends to a MIDI channel if(pIns->nMixPlug != 0 && pIns->nMixPlug <= MAX_MIXPLUGINS) { return m_MixPlugins[pIns->nMixPlug - 1].pMixPlugin; } } #else MPT_UNREFERENCED_PARAMETER(chn); #endif // NO_PLUGINS return nullptr; } // Get the MIDI channel currently associated with a given tracker channel uint8 CSoundFile::GetBestMidiChannel(CHANNELINDEX nChn) const { if(nChn >= MAX_CHANNELS) { return 0; } const ModInstrument *ins = m_PlayState.Chn[nChn].pModInstrument; if(ins != nullptr) { if(ins->nMidiChannel == MidiMappedChannel) { // For mapped channels, return their pattern channel, modulo 16 (because there are only 16 MIDI channels) return (m_PlayState.Chn[nChn].nMasterChn ? (m_PlayState.Chn[nChn].nMasterChn - 1) : nChn) % 16; } else if(ins->HasValidMIDIChannel()) { return (ins->nMidiChannel - 1) & 0x0F; } } return 0; } #ifdef MODPLUG_TRACKER void CSoundFile::HandlePatternTransitionEvents() { // MPT sequence override if(m_PlayState.m_nSeqOverride != ORDERINDEX_INVALID && m_PlayState.m_nSeqOverride < Order().size()) { if(m_SongFlags[SONG_PATTERNLOOP]) { m_PlayState.m_nPattern = Order()[m_PlayState.m_nSeqOverride]; } m_PlayState.m_nCurrentOrder = m_PlayState.m_nSeqOverride; m_PlayState.m_nSeqOverride = ORDERINDEX_INVALID; } // Channel mutes for (CHANNELINDEX chan = 0; chan < GetNumChannels(); chan++) { if (m_bChannelMuteTogglePending[chan]) { if(GetpModDoc()) { GetpModDoc()->MuteChannel(chan, !GetpModDoc()->IsChannelMuted(chan)); } m_bChannelMuteTogglePending[chan] = false; } } } #endif // MODPLUG_TRACKER // Update time signatures (global or pattern-specific). Don't forget to call this when changing the RPB/RPM settings anywhere! void CSoundFile::UpdateTimeSignature() { if(!Patterns.IsValidIndex(m_PlayState.m_nPattern) || !Patterns[m_PlayState.m_nPattern].GetOverrideSignature()) { m_PlayState.m_nCurrentRowsPerBeat = m_nDefaultRowsPerBeat; m_PlayState.m_nCurrentRowsPerMeasure = m_nDefaultRowsPerMeasure; } else { m_PlayState.m_nCurrentRowsPerBeat = Patterns[m_PlayState.m_nPattern].GetRowsPerBeat(); m_PlayState.m_nCurrentRowsPerMeasure = Patterns[m_PlayState.m_nPattern].GetRowsPerMeasure(); } } void CSoundFile::PortamentoMPT(ModChannel* pChn, int param) { //Behavior: Modifies portamento by param-steps on every tick. //Note that step meaning depends on tuning. pChn->m_PortamentoFineSteps += param; pChn->m_CalculateFreq = true; } void CSoundFile::PortamentoFineMPT(ModChannel* pChn, int param) { //Behavior: Divides portamento change between ticks/row. For example //if Ticks/row == 6, and param == +-6, portamento goes up/down by one tuning-dependent //fine step every tick. if(m_PlayState.m_nTickCount == 0) pChn->nOldFinePortaUpDown = 0; const int tickParam = static_cast((m_PlayState.m_nTickCount + 1.0) * param / m_PlayState.m_nMusicSpeed); pChn->m_PortamentoFineSteps += (param >= 0) ? tickParam - pChn->nOldFinePortaUpDown : tickParam + pChn->nOldFinePortaUpDown; if(m_PlayState.m_nTickCount + 1 == m_PlayState.m_nMusicSpeed) pChn->nOldFinePortaUpDown = static_cast(mpt::abs(param)); else pChn->nOldFinePortaUpDown = static_cast(mpt::abs(tickParam)); pChn->m_CalculateFreq = true; } void CSoundFile::PortamentoExtraFineMPT(ModChannel* pChn, int param) { // This kinda behaves like regular fine portamento. // It changes the pitch by n finetune steps on the first tick. if(pChn->isFirstTick) { pChn->m_PortamentoFineSteps += param; pChn->m_CalculateFreq = true; } } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/ContainerXPK.cpp0000644000372100037210000001706213161656666021134 00000000000000/* * ContainerXPK.cpp * ---------------- * Purpose: Handling of XPK compressed modules * Notes : (currently none) * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "../common/FileReader.h" #include "Container.h" #include "Sndfile.h" #include OPENMPT_NAMESPACE_BEGIN //#define MMCMP_LOG struct XPKFILEHEADER { char XPKF[4]; uint32be SrcLen; char SQSH[4]; uint32be DstLen; char Name[16]; uint32be Reserved; }; MPT_BINARY_STRUCT(XPKFILEHEADER, 36) struct XPK_error : public std::range_error { XPK_error() : std::range_error("invalid XPK data") { } }; struct XPK_BufferBounds { const uint8 *pSrcBeg; std::size_t SrcSize; uint8 *pDstBeg; std::size_t DstSize; inline uint8 SrcRead(std::size_t index) { if(index >= SrcSize) throw XPK_error(); return pSrcBeg[index]; } inline void DstWrite(std::size_t index, uint8 value) { if(index >= DstSize) throw XPK_error(); pDstBeg[index] = value; } inline uint8 DstRead(std::size_t index) { if(index >= DstSize) throw XPK_error(); return pDstBeg[index]; } }; static int32 bfextu(std::size_t p, int32 bo, int32 bc, XPK_BufferBounds &bufs) { int32 r; p += bo / 8; r = bufs.SrcRead(p); p++; r <<= 8; r |= bufs.SrcRead(p); p++; r <<= 8; r |= bufs.SrcRead(p); r <<= bo % 8; r &= 0xffffff; r >>= 24 - bc; return r; } static int32 bfexts(std::size_t p, int32 bo, int32 bc, XPK_BufferBounds &bufs) { int32 r; p += bo / 8; r = bufs.SrcRead(p); p++; r <<= 8; r |= bufs.SrcRead(p); p++; r <<= 8; r |= bufs.SrcRead(p); r <<= (bo % 8) + 8; r >>= 32 - bc; return r; } static uint8 XPK_ReadTable(int32 index) { static const uint8 xpk_table[] = { 2,3,4,5,6,7,8,0,3,2,4,5,6,7,8,0,4,3,5,2,6,7,8,0,5,4,6,2,3,7,8,0,6,5,7,2,3,4,8,0,7,6,8,2,3,4,5,0,8,7,6,2,3,4,5,0 }; if(index < 0) throw XPK_error(); if(static_cast(index) >= mpt::size(xpk_table)) throw XPK_error(); return xpk_table[index]; } static bool XPK_DoUnpack(const uint8 *src_, uint32 srcLen, std::vector &unpackedData, int32 len) { if(len <= 0) return false; int32 d0,d1,d2,d3,d4,d5,d6,a2,a5; int32 cp, cup1, type; std::size_t c; std::size_t src; std::size_t dst; std::size_t phist = 0; std::size_t dstmax = len; unpackedData.resize(len); XPK_BufferBounds bufs; bufs.pSrcBeg = src_; bufs.SrcSize = srcLen; bufs.pDstBeg = mpt::byte_cast(unpackedData.data()); bufs.DstSize = len; src = 0; dst = 0; c = src; while (len > 0) { type = bufs.SrcRead(c+0); cp = (bufs.SrcRead(c+4)<<8) | (bufs.SrcRead(c+5)); // packed cup1 = (bufs.SrcRead(c+6)<<8) | (bufs.SrcRead(c+7)); // unpacked //Log(" packed=%6d unpacked=%6d bytes left=%d dst=%08X(%d)\n", cp, cup1, len, dst, dst); c += 8; src = c+2; if (type == 0) { // RAW chunk if(cp < 0) throw XPK_error(); for(int32 i = 0; i < cp; ++i) { bufs.DstWrite(dst + i, bufs.SrcRead(c + i)); } dst+=cp; c+=cp; len -= cp; continue; } if (type != 1) { #ifdef MMCMP_LOG Log("Invalid XPK type! (%d bytes left)\n", len); #endif break; } len -= cup1; cp = (cp + 3) & 0xfffc; c += cp; d0 = d1 = d2 = a2 = 0; d3 = bufs.SrcRead(src); src++; bufs.DstWrite(dst, (uint8)d3); if (dst < dstmax) dst++; cup1--; while (cup1 > 0) { if (d1 >= 8) goto l6dc; if (bfextu(src,d0,1,bufs)) goto l75a; d0 += 1; d5 = 0; d6 = 8; goto l734; l6dc: if (bfextu(src,d0,1,bufs)) goto l726; d0 += 1; if (! bfextu(src,d0,1,bufs)) goto l75a; d0 += 1; if (bfextu(src,d0,1,bufs)) goto l6f6; d6 = 2; goto l708; l6f6: d0 += 1; if (!bfextu(src,d0,1,bufs)) goto l706; d6 = bfextu(src,d0,3,bufs); d0 += 3; goto l70a; l706: d6 = 3; l708: d0 += 1; l70a: d6 = XPK_ReadTable((8*a2) + d6 -17); if (d6 != 8) goto l730; l718: if (d2 >= 20) { d5 = 1; goto l732; } d5 = 0; goto l734; l726: d0 += 1; d6 = 8; if (d6 == a2) goto l718; d6 = a2; l730: d5 = 4; l732: d2 += 8; l734: while ((d5 >= 0) && (cup1 > 0)) { d4 = bfexts(src,d0,d6,bufs); d0 += d6; d3 -= d4; bufs.DstWrite(dst, (uint8)d3); if (dst < dstmax) dst++; cup1--; d5--; } if (d1 != 31) d1++; a2 = d6; l74c: d6 = d2; d6 >>= 3; d2 -= d6; } } unpackedData.resize(bufs.DstSize - len); return !unpackedData.empty(); l75a: d0 += 1; if (bfextu(src,d0,1,bufs)) goto l766; d4 = 2; goto l79e; l766: d0 += 1; if (bfextu(src,d0,1,bufs)) goto l772; d4 = 4; goto l79e; l772: d0 += 1; if (bfextu(src,d0,1,bufs)) goto l77e; d4 = 6; goto l79e; l77e: d0 += 1; if (bfextu(src,d0,1,bufs)) goto l792; d0 += 1; d6 = bfextu(src,d0,3,bufs); d0 += 3; d6 += 8; goto l7a8; l792: d0 += 1; d6 = bfextu(src,d0,5,bufs); d0 += 5; d4 = 16; goto l7a6; l79e: d0 += 1; d6 = bfextu(src,d0,1,bufs); d0 += 1; l7a6: d6 += d4; l7a8: if (bfextu(src,d0,1,bufs)) goto l7c4; d0 += 1; if (bfextu(src,d0,1,bufs)) goto l7bc; d5 = 8; a5 = 0; goto l7ca; l7bc: d5 = 14; a5 = -0x1100; goto l7ca; l7c4: d5 = 12; a5 = -0x100; l7ca: d0 += 1; d4 = bfextu(src,d0,d5,bufs); d0 += d5; d6 -= 3; if (d6 >= 0) { if (d6 > 0) d1 -= 1; d1 -= 1; if (d1 < 0) d1 = 0; } d6 += 2; phist = dst + a5 - d4 - 1; while ((d6 >= 0) && (cup1 > 0)) { d3 = bufs.DstRead(phist); phist++; bufs.DstWrite(dst, (uint8)d3); if (dst < dstmax) dst++; cup1--; d6--; } goto l74c; } static bool ValidateHeader(const XPKFILEHEADER &header) { if(std::memcmp(header.XPKF, "XPKF", 4) != 0) { return false; } if(std::memcmp(header.SQSH, "SQSH", 4) != 0) { return false; } if(header.SrcLen == 0) { return false; } if(header.DstLen == 0) { return false; } MPT_STATIC_ASSERT(sizeof(XPKFILEHEADER) >= 8); if(header.SrcLen < (sizeof(XPKFILEHEADER) - 8)) { return false; } return true; } static bool ValidateHeaderFileSize(const XPKFILEHEADER &header, uint64 filesize) { if(filesize < header.SrcLen - 8) { return false; } return true; } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderXPK(MemoryFileReader file, const uint64 *pfilesize) { XPKFILEHEADER header; if(!file.ReadStruct(header)) { return ProbeWantMoreData; } if(!ValidateHeader(header)) { return ProbeFailure; } if(pfilesize) { if(!ValidateHeaderFileSize(header, *pfilesize)) { return ProbeFailure; } } return ProbeSuccess; } bool UnpackXPK(std::vector &containerItems, FileReader &file, ContainerLoadingFlags loadFlags) { file.Rewind(); containerItems.clear(); XPKFILEHEADER header; if(!file.ReadStruct(header)) { return false; } if(!ValidateHeader(header)) { return false; } if(loadFlags == ContainerOnlyVerifyHeader) { return true; } if(!file.CanRead(header.SrcLen - (sizeof(XPKFILEHEADER) - 8))) { return false; } containerItems.emplace_back(); containerItems.back().data_cache = mpt::make_unique >(); std::vector & unpackedData = *(containerItems.back().data_cache); #ifdef MMCMP_LOG Log("XPK detected (SrcLen=%d DstLen=%d) filesize=%d\n", header.SrcLen, header.DstLen, file.GetLength()); #endif bool result = false; try { result = XPK_DoUnpack(file.GetRawData(), header.SrcLen - (sizeof(XPKFILEHEADER) - 8), unpackedData, header.DstLen); } MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e) { MPT_EXCEPTION_DELETE_OUT_OF_MEMORY(e); return false; } catch(const XPK_error &) { return false; } if(result) { containerItems.back().file = FileReader(mpt::byte_cast(mpt::as_span(unpackedData))); } return result; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Load_ams.cpp0000644000372100037210000007130313161656666020344 00000000000000/* * Load_ams.cpp * ------------ * Purpose: AMS (Extreme's Tracker / Velvet Studio) module loader * Notes : Extreme was renamed to Velvet Development at some point, * and thus they also renamed their tracker from * "Extreme's Tracker" to "Velvet Studio". * While the two programs look rather similiar, the structure of both * programs' "AMS" format is significantly different in some places - * Velvet Studio is a rather advanced tracker in comparison to Extreme's Tracker. * The source code of Velvet Studio has been released into the * public domain in 2013: https://github.com/Patosc/VelvetStudio/commits/master * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" OPENMPT_NAMESPACE_BEGIN // Read AMS or AMS2 (newVersion = true) pattern. At least this part of the format is more or less identical between the two trackers... static void ReadAMSPattern(CPattern &pattern, bool newVersion, FileReader &patternChunk) { enum { emptyRow = 0xFF, // No commands on row endOfRowMask = 0x80, // If set, no more commands on this row noteMask = 0x40, // If set, no note+instr in this command channelMask = 0x1F, // Mask for extracting channel // Note flags readNextCmd = 0x80, // One more command follows noteDataMask = 0x7F, // Extract note // Command flags volCommand = 0x40, // Effect is compressed volume command commandMask = 0x3F, // Command or volume mask }; // Effect translation table for extended (non-Protracker) effects static const ModCommand::COMMAND effTrans[] = { CMD_S3MCMDEX, // Forward / Backward CMD_PORTAMENTOUP, // Extra fine slide up CMD_PORTAMENTODOWN, // Extra fine slide up CMD_RETRIG, // Retrigger CMD_NONE, CMD_TONEPORTAVOL, // Toneporta with fine volume slide CMD_VIBRATOVOL, // Vibrato with fine volume slide CMD_NONE, CMD_PANNINGSLIDE, CMD_NONE, CMD_VOLUMESLIDE, // Two times finder volume slide than Axx CMD_NONE, CMD_CHANNELVOLUME, // Channel volume (0...127) CMD_PATTERNBREAK, // Long pattern break (in hex) CMD_S3MCMDEX, // Fine slide commands CMD_NONE, // Fractional BPM CMD_KEYOFF, // Key off at tick xx CMD_PORTAMENTOUP, // Porta up, but uses all octaves (?) CMD_PORTAMENTODOWN, // Porta down, but uses all octaves (?) CMD_NONE, CMD_NONE, CMD_NONE, CMD_NONE, CMD_NONE, CMD_NONE, CMD_NONE, CMD_GLOBALVOLSLIDE, // Global volume slide CMD_NONE, CMD_GLOBALVOLUME, // Global volume (0... 127) }; ModCommand dummy = ModCommand::Empty(); for(ROWINDEX row = 0; row < pattern.GetNumRows(); row++) { PatternRow baseRow = pattern.GetRow(row); while(patternChunk.CanRead(1)) { const uint8 flags = patternChunk.ReadUint8(); if(flags == emptyRow) { break; } const CHANNELINDEX chn = (flags & channelMask); ModCommand &m = chn < pattern.GetNumChannels() ? baseRow[chn] : dummy; bool moreCommands = true; if(!(flags & noteMask)) { // Read note + instr uint8 note = patternChunk.ReadUint8(); moreCommands = (note & readNextCmd) != 0; note &= noteDataMask; if(note == 1) { m.note = NOTE_KEYOFF; } else if(note >= 2 && note <= 121 && newVersion) { m.note = note - 2 + NOTE_MIN; } else if(note >= 12 && note <= 108 && !newVersion) { m.note = note + 12 + NOTE_MIN; } m.instr = patternChunk.ReadUint8(); } while(moreCommands) { // Read one more effect command ModCommand origCmd = m; const uint8 command = patternChunk.ReadUint8(), effect = (command & commandMask); moreCommands = (command & readNextCmd) != 0; if(command & volCommand) { m.volcmd = VOLCMD_VOLUME; m.vol = effect; } else { m.param = patternChunk.ReadUint8(); if(effect < 0x10) { // PT commands m.command = effect; CSoundFile::ConvertModCommand(m); // Post-fix some commands switch(m.command) { case CMD_PANNING8: // 4-Bit panning m.command = CMD_PANNING8; m.param = (m.param & 0x0F) * 0x11; break; case CMD_VOLUME: m.command = CMD_NONE; m.volcmd = VOLCMD_VOLUME; m.vol = static_cast(std::min((m.param + 1) / 2, 64)); break; case CMD_MODCMDEX: if(m.param == 0x80) { // Break sample loop (cut after loop) m.command = CMD_NONE; } else { m.ExtendedMODtoS3MEffect(); } break; } } else if(effect - 0x10 < (int)CountOf(effTrans)) { // Extended commands m.command = effTrans[effect - 0x10]; // Post-fix some commands switch(effect) { case 0x10: // Play sample forwards / backwards if(m.param <= 0x01) { m.param |= 0x9E; } else { m.command = CMD_NONE; } break; case 0x11: case 0x12: // Extra fine slides m.param = static_cast(std::min(uint8(0x0F), m.param) | 0xE0); break; case 0x15: case 0x16: // Fine slides m.param = static_cast((std::min(0x10, m.param + 1) / 2) | 0xF0); break; case 0x1E: // More fine slides switch(m.param >> 4) { case 0x1: // Fine porta up m.command = CMD_PORTAMENTOUP; m.param |= 0xF0; break; case 0x2: // Fine porta down m.command = CMD_PORTAMENTODOWN; m.param |= 0xF0; break; case 0xA: // Extra fine volume slide up m.command = CMD_VOLUMESLIDE; m.param = ((((m.param & 0x0F) + 1) / 2) << 4) | 0x0F; break; case 0xB: // Extra fine volume slide down m.command = CMD_VOLUMESLIDE; m.param = (((m.param & 0x0F) + 1) / 2) | 0xF0; break; default: m.command = CMD_NONE; break; } break; case 0x1C: // Adjust channel volume range m.param = static_cast(std::min((m.param + 1) / 2, 64)); break; } } // Try merging commands first ModCommand::CombineEffects(m.command, m.param, origCmd.command, origCmd.param); if(ModCommand::GetEffectWeight(origCmd.command) > ModCommand::GetEffectWeight(m.command)) { if(m.volcmd == VOLCMD_NONE && ModCommand::ConvertVolEffect(m.command, m.param, true)) { // Volume column to the rescue! m.volcmd = m.command; m.vol = m.param; } m.command = origCmd.command; m.param = origCmd.param; } } } if(flags & endOfRowMask) { // End of row break; } } } } ///////////////////////////////////////////////////////////////////// // AMS (Extreme's Tracker) 1.x loader // AMS File Header struct AMSFileHeader { uint8le versionLow; uint8le versionHigh; uint8le channelConfig; uint8le numSamps; uint16le numPats; uint16le numOrds; uint8le midiChannels; uint16le extraSize; }; MPT_BINARY_STRUCT(AMSFileHeader, 11) // AMS Sample Header struct AMSSampleHeader { enum SampleFlags { smp16BitOld = 0x04, // AMS 1.0 (at least according to docs, I yet have to find such a file) smp16Bit = 0x80, // AMS 1.1+ smpPacked = 0x03, }; uint32le length; uint32le loopStart; uint32le loopEnd; uint8le panFinetune; // High nibble = pan position, low nibble = finetune value uint16le sampleRate; uint8le volume; // 0...127 uint8le flags; // See SampleFlags // Convert sample header to OpenMPT's internal format. void ConvertToMPT(ModSample &mptSmp) const { mptSmp.Initialize(); mptSmp.nLength = length; mptSmp.nLoopStart = std::min(loopStart, length); mptSmp.nLoopEnd = std::min(loopEnd, length); mptSmp.nVolume = (std::min(127, volume) * 256 + 64) / 127; if(panFinetune & 0xF0) { mptSmp.nPan = (panFinetune & 0xF0); mptSmp.uFlags = CHN_PANNING; } mptSmp.nC5Speed = 2 * sampleRate; if(sampleRate == 0) { mptSmp.nC5Speed = 2 * 8363; } uint32 newC4speed = ModSample::TransposeToFrequency(0, MOD2XMFineTune(panFinetune & 0x0F)); mptSmp.nC5Speed = (mptSmp.nC5Speed * newC4speed) / 8363; if(mptSmp.nLoopStart < mptSmp.nLoopEnd) { mptSmp.uFlags.set(CHN_LOOP); } if(flags & (smp16Bit | smp16BitOld)) { mptSmp.uFlags.set(CHN_16BIT); } } }; MPT_BINARY_STRUCT(AMSSampleHeader, 17) static bool ValidateHeader(const AMSFileHeader &fileHeader) { if(fileHeader.versionHigh != 0x01) { return false; } return true; } static uint64 GetHeaderMinimumAdditionalSize(const AMSFileHeader &fileHeader) { return fileHeader.extraSize + 3u + fileHeader.numSamps * (1u + sizeof(AMSSampleHeader)) + fileHeader.numOrds * 2u + fileHeader.numPats * 4u; } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderAMS(MemoryFileReader file, const uint64 *pfilesize) { if(!file.CanRead(7)) { return ProbeWantMoreData; } if(!file.ReadMagic("Extreme")) { return ProbeFailure; } AMSFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return ProbeWantMoreData; } if(!ValidateHeader(fileHeader)) { return ProbeFailure; } return ProbeAdditionalSize(file, pfilesize, GetHeaderMinimumAdditionalSize(fileHeader)); } bool CSoundFile::ReadAMS(FileReader &file, ModLoadingFlags loadFlags) { file.Rewind(); if(!file.ReadMagic("Extreme")) { return false; } AMSFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return false; } if(!ValidateHeader(fileHeader)) { return false; } if(!file.CanRead(mpt::saturate_cast(GetHeaderMinimumAdditionalSize(fileHeader)))) { return false; } if(!file.Skip(fileHeader.extraSize)) { return false; } if(loadFlags == onlyVerifyHeader) { return true; } InitializeGlobals(MOD_TYPE_AMS); m_SongFlags = SONG_ITCOMPATGXX | SONG_ITOLDEFFECTS; m_nChannels = (fileHeader.channelConfig & 0x1F) + 1; m_nSamples = fileHeader.numSamps; SetupMODPanning(true); m_madeWithTracker = mpt::format(MPT_USTRING("Extreme's Tracker %1.%2"))(fileHeader.versionHigh, fileHeader.versionLow); std::vector packSample(fileHeader.numSamps); STATIC_ASSERT(MAX_SAMPLES > 255); for(SAMPLEINDEX smp = 1; smp <= GetNumSamples(); smp++) { AMSSampleHeader sampleHeader; file.ReadStruct(sampleHeader); sampleHeader.ConvertToMPT(Samples[smp]); packSample[smp - 1] = (sampleHeader.flags & AMSSampleHeader::smpPacked) != 0; } // Texts file.ReadSizedString(m_songName); // Read sample names for(SAMPLEINDEX smp = 1; smp <= GetNumSamples(); smp++) { file.ReadSizedString(m_szNames[smp]); } // Read channel names for(CHANNELINDEX chn = 0; chn < GetNumChannels(); chn++) { ChnSettings[chn].Reset(); file.ReadSizedString(ChnSettings[chn].szName); } // Read pattern names Patterns.ResizeArray(fileHeader.numPats); for(PATTERNINDEX pat = 0; pat < fileHeader.numPats; pat++) { char name[11]; file.ReadSizedString(name); // Create pattern now, so name won't be reset later. if(Patterns.Insert(pat, 64)) { Patterns[pat].SetName(name); } } // Read packed song message const uint16 packedLength = file.ReadUint16LE(); if(packedLength && file.CanRead(packedLength)) { std::vector textIn; file.ReadVector(textIn, packedLength); std::string textOut; textOut.reserve(packedLength); for(auto c : textIn) { if(c & 0x80) { textOut.insert(textOut.end(), (c & 0x7F), ' '); } else { textOut.push_back(c); } } textOut = mpt::ToCharset(mpt::CharsetCP437, mpt::CharsetCP437AMS, textOut); // Packed text doesn't include any line breaks! m_songMessage.ReadFixedLineLength(mpt::byte_cast(textOut.c_str()), textOut.length(), 76, 0); } // Read Order List ReadOrderFromFile(Order(), file, fileHeader.numOrds); // Read patterns for(PATTERNINDEX pat = 0; pat < fileHeader.numPats; pat++) { uint32 patLength = file.ReadUint32LE(); FileReader patternChunk = file.ReadChunk(patLength); if(loadFlags & loadPatternData) { ReadAMSPattern(Patterns[pat], false, patternChunk); } } if(loadFlags & loadSampleData) { // Read Samples for(SAMPLEINDEX smp = 1; smp <= GetNumSamples(); smp++) { SampleIO( Samples[smp].uFlags[CHN_16BIT] ? SampleIO::_16bit : SampleIO::_8bit, SampleIO::mono, SampleIO::littleEndian, packSample[smp - 1] ? SampleIO::AMS : SampleIO::signedPCM) .ReadSample(Samples[smp], file); } } return true; } ///////////////////////////////////////////////////////////////////// // AMS (Velvet Studio) 2.0 - 2.02 loader // AMS2 File Header struct AMS2FileHeader { enum FileFlags { linearSlides = 0x40, }; uint8le versionLow; // Version of format (Hi = MainVer, Low = SubVer e.g. 0202 = 2.02) uint8le versionHigh; // ditto uint8le numIns; // Nr of Instruments (0-255) uint16le numPats; // Nr of Patterns (1-1024) uint16le numOrds; // Nr of Positions (1-65535) // Rest of header differs between format revision 2.01 and 2.02 }; MPT_BINARY_STRUCT(AMS2FileHeader, 7) // AMS2 Instument Envelope struct AMS2Envelope { uint8 speed; // Envelope speed (currently not supported, always the same as current BPM) uint8 sustainPoint; // Envelope sustain point uint8 loopStart; // Envelope loop Start uint8 loopEnd; // Envelope loop End uint8 numPoints; // Envelope length // Read envelope and do partial conversion. void ConvertToMPT(InstrumentEnvelope &mptEnv, FileReader &file) { file.ReadStruct(*this); // Read envelope points uint8 data[64][3]; file.ReadStructPartial(data, numPoints * 3); if(numPoints <= 1) { // This is not an envelope. return; } STATIC_ASSERT(MAX_ENVPOINTS >= CountOf(data)); mptEnv.resize(std::min(numPoints, uint8(CountOf(data)))); mptEnv.nLoopStart = loopStart; mptEnv.nLoopEnd = loopEnd; mptEnv.nSustainStart = mptEnv.nSustainEnd = sustainPoint; for(uint32 i = 0; i < mptEnv.size(); i++) { if(i != 0) { mptEnv[i].tick = mptEnv[i - 1].tick + static_cast(std::max(1, data[i][0] | ((data[i][1] & 0x01) << 8))); } mptEnv[i].value = data[i][2]; } } }; MPT_BINARY_STRUCT(AMS2Envelope, 5) // AMS2 Instrument Data struct AMS2Instrument { enum EnvelopeFlags { envLoop = 0x01, envSustain = 0x02, envEnabled = 0x04, // Flag shift amounts volEnvShift = 0, panEnvShift = 1, vibEnvShift = 2, vibAmpMask = 0x3000, vibAmpShift = 12, fadeOutMask = 0xFFF, }; uint8le shadowInstr; // Shadow Instrument. If non-zero, the value=the shadowed inst. uint16le vibampFadeout; // Vib.Amplify + Volume fadeout in one variable! uint16le envFlags; // See EnvelopeFlags void ApplyFlags(InstrumentEnvelope &mptEnv, EnvelopeFlags shift) const { const int flags = envFlags >> (shift * 3); mptEnv.dwFlags.set(ENV_ENABLED, (flags & envEnabled) != 0); mptEnv.dwFlags.set(ENV_LOOP, (flags & envLoop) != 0); mptEnv.dwFlags.set(ENV_SUSTAIN, (flags & envSustain) != 0); // "Break envelope" should stop the envelope loop when encountering a note-off... We can only use the sustain loop to emulate this behaviour. if(!(flags & envSustain) && (flags & envLoop) != 0 && (flags & (1 << (9 - shift * 2))) != 0) { mptEnv.nSustainStart = mptEnv.nLoopStart; mptEnv.nSustainEnd = mptEnv.nLoopEnd; mptEnv.dwFlags.set(ENV_SUSTAIN); mptEnv.dwFlags.reset(ENV_LOOP); } } }; MPT_BINARY_STRUCT(AMS2Instrument, 5) // AMS2 Sample Header struct AMS2SampleHeader { enum SampleFlags { smpPacked = 0x03, smp16Bit = 0x04, smpLoop = 0x08, smpBidiLoop = 0x10, smpReverse = 0x40, }; uint32le length; uint32le loopStart; uint32le loopEnd; uint16le sampledRate; // Whyyyy? uint8le panFinetune; // High nibble = pan position, low nibble = finetune value uint16le c4speed; // Why is all of this so redundant? int8le relativeTone; // q.e.d. uint8le volume; // 0...127 uint8le flags; // See SampleFlags // Convert sample header to OpenMPT's internal format. void ConvertToMPT(ModSample &mptSmp) const { mptSmp.Initialize(); mptSmp.nLength = length; mptSmp.nLoopStart = std::min(loopStart, length); mptSmp.nLoopEnd = std::min(loopEnd, length); mptSmp.nC5Speed = c4speed * 2; if(c4speed == 0) { mptSmp.nC5Speed = 8363 * 2; } // Why, oh why, does this format need a c5speed and transpose/finetune at the same time... uint32 newC4speed = ModSample::TransposeToFrequency(relativeTone, MOD2XMFineTune(panFinetune & 0x0F)); mptSmp.nC5Speed = (mptSmp.nC5Speed * newC4speed) / 8363; mptSmp.nVolume = (std::min(volume, 127) * 256 + 64) / 127; if(panFinetune & 0xF0) { mptSmp.nPan = (panFinetune & 0xF0); mptSmp.uFlags = CHN_PANNING; } if(flags & smp16Bit) mptSmp.uFlags.set(CHN_16BIT); if((flags & smpLoop) && mptSmp.nLoopStart < mptSmp.nLoopEnd) { mptSmp.uFlags.set(CHN_LOOP); if(flags & smpBidiLoop) mptSmp.uFlags.set(CHN_PINGPONGLOOP); if(flags & smpReverse) mptSmp.uFlags.set(CHN_REVERSE); } } }; MPT_BINARY_STRUCT(AMS2SampleHeader, 20) // AMS2 Song Description Header struct AMS2Description { uint32le packedLen; // Including header uint32le unpackedLen; uint8le packRoutine; // 01 uint8le preProcessing; // None! uint8le packingMethod; // RLE }; MPT_BINARY_STRUCT(AMS2Description, 11) static bool ValidateHeader(const AMS2FileHeader &fileHeader) { if(fileHeader.versionHigh != 2 || fileHeader.versionLow > 2) { return false; } return true; } static uint64 GetHeaderMinimumAdditionalSize(const AMS2FileHeader &fileHeader) { return 36u + sizeof(AMS2Description) + fileHeader.numIns * 2u + fileHeader.numOrds * 2u + fileHeader.numPats * 4u; } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderAMS2(MemoryFileReader file, const uint64 *pfilesize) { if(!file.CanRead(7)) { return ProbeWantMoreData; } if(!file.ReadMagic("AMShdr\x1A")) { return ProbeFailure; } if(!file.CanRead(1)) { return ProbeWantMoreData; } const uint8 songNameLength = file.ReadUint8(); if(!file.Skip(songNameLength)) { return ProbeWantMoreData; } AMS2FileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return ProbeWantMoreData; } if(!ValidateHeader(fileHeader)) { return ProbeFailure; } return ProbeAdditionalSize(file, pfilesize, GetHeaderMinimumAdditionalSize(fileHeader)); } bool CSoundFile::ReadAMS2(FileReader &file, ModLoadingFlags loadFlags) { file.Rewind(); if(!file.ReadMagic("AMShdr\x1A")) { return false; } std::string songName; if(!file.ReadSizedString(songName)) { return false; } AMS2FileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return false; } if(!ValidateHeader(fileHeader)) { return false; } if(!file.CanRead(mpt::saturate_cast(GetHeaderMinimumAdditionalSize(fileHeader)))) { return false; } if(loadFlags == onlyVerifyHeader) { return true; } InitializeGlobals(MOD_TYPE_AMS2); m_songName = songName; m_nInstruments = fileHeader.numIns; m_nChannels = 32; SetupMODPanning(true); m_madeWithTracker = mpt::format(MPT_USTRING("Velvet Studio %1.%2"))(fileHeader.versionHigh.get(), mpt::ufmt::dec0<2>(fileHeader.versionLow.get())); uint16 headerFlags; if(fileHeader.versionLow >= 2) { uint16 tempo = std::max(uint16(32 << 8), file.ReadUint16LE()); // 8.8 tempo m_nDefaultTempo.SetRaw((tempo * TEMPO::fractFact) >> 8); m_nDefaultSpeed = std::max(uint8(1), file.ReadUint8()); file.Skip(3); // Default values for pattern editor headerFlags = file.ReadUint16LE(); } else { m_nDefaultTempo.Set(std::max(uint8(32), file.ReadUint8())); m_nDefaultSpeed = std::max(uint8(1), file.ReadUint8()); headerFlags = file.ReadUint8(); } m_SongFlags = SONG_ITCOMPATGXX | SONG_ITOLDEFFECTS | ((headerFlags & AMS2FileHeader::linearSlides) ? SONG_LINEARSLIDES : SongFlags(0)); // Instruments std::vector firstSample; // First sample of instrument std::vector sampleSettings; // Shadow sample map... Lo byte = Instrument, Hi byte, lo nibble = Sample index in instrument, Hi byte, hi nibble = Sample pack status enum { instrIndexMask = 0xFF, // Shadow instrument sampleIndexMask = 0x7F00, // Sample index in instrument sampleIndexShift = 8, packStatusMask = 0x8000, // If bit is set, sample is packed }; STATIC_ASSERT(MAX_INSTRUMENTS > 255); for(INSTRUMENTINDEX ins = 1; ins <= m_nInstruments; ins++) { ModInstrument *instrument = AllocateInstrument(ins); if(instrument == nullptr || !file.ReadSizedString(instrument->name)) { break; } uint8 numSamples = file.ReadUint8(); uint8 sampleAssignment[120]; MemsetZero(sampleAssignment); // Only really needed for v2.0, where the lowest and highest octave aren't cleared. if(numSamples == 0 || (fileHeader.versionLow > 0 && !file.ReadArray(sampleAssignment)) // v2.01+: 120 Notes || (fileHeader.versionLow == 0 && !file.ReadRaw(sampleAssignment + 12, 96))) // v2.0: 96 Notes { continue; } STATIC_ASSERT(CountOf(instrument->Keyboard) >= CountOf(sampleAssignment)); for(size_t i = 0; i < 120; i++) { instrument->Keyboard[i] = sampleAssignment[i] + GetNumSamples() + 1; } AMS2Envelope volEnv, panEnv, vibratoEnv; volEnv.ConvertToMPT(instrument->VolEnv, file); panEnv.ConvertToMPT(instrument->PanEnv, file); vibratoEnv.ConvertToMPT(instrument->PitchEnv, file); AMS2Instrument instrHeader; file.ReadStruct(instrHeader); instrument->nFadeOut = (instrHeader.vibampFadeout & AMS2Instrument::fadeOutMask); const int16 vibAmp = 1 << ((instrHeader.vibampFadeout & AMS2Instrument::vibAmpMask) >> AMS2Instrument::vibAmpShift); instrHeader.ApplyFlags(instrument->VolEnv, AMS2Instrument::volEnvShift); instrHeader.ApplyFlags(instrument->PanEnv, AMS2Instrument::panEnvShift); instrHeader.ApplyFlags(instrument->PitchEnv, AMS2Instrument::vibEnvShift); // Scale envelopes to correct range for(auto &p : instrument->VolEnv) { p.value = std::min(uint8(ENVELOPE_MAX), static_cast((p.value * ENVELOPE_MAX + 64u) / 127u)); } for(auto &p : instrument->PanEnv) { p.value = std::min(uint8(ENVELOPE_MAX), static_cast((p.value * ENVELOPE_MAX + 128u) / 255u)); } for(auto &p : instrument->PitchEnv) { #ifdef MODPLUG_TRACKER p.value = std::min(uint8(ENVELOPE_MAX), static_cast(32 + Util::muldivrfloor(static_cast(p.value - 128), vibAmp, 255))); #else // Try to keep as much precision as possible... divide by 8 since that's the highest possible vibAmp factor. p.value = static_cast(128 + Util::muldivrfloor(static_cast(p.value - 128), vibAmp, 8)); #endif } // Sample headers - we will have to read them even for shadow samples, and we will have to load them several times, // as it is possible that shadow samples use different sample settings like base frequency or panning. const SAMPLEINDEX firstSmp = GetNumSamples() + 1; for(SAMPLEINDEX smp = 0; smp < numSamples; smp++) { if(firstSmp + smp >= MAX_SAMPLES) { file.Skip(sizeof(AMS2SampleHeader)); break; } file.ReadSizedString(m_szNames[firstSmp + smp]); AMS2SampleHeader sampleHeader; file.ReadStruct(sampleHeader); sampleHeader.ConvertToMPT(Samples[firstSmp + smp]); uint16 settings = (instrHeader.shadowInstr & instrIndexMask) | ((smp << sampleIndexShift) & sampleIndexMask) | ((sampleHeader.flags & AMS2SampleHeader::smpPacked) ? packStatusMask : 0); sampleSettings.push_back(settings); } firstSample.push_back(firstSmp); m_nSamples = static_cast(std::min(MAX_SAMPLES - 1, GetNumSamples() + numSamples)); } // Text // Read composer name uint8 composerLength = file.ReadUint8(); if(composerLength) { std::string str; file.ReadString(str, composerLength); m_songArtist = mpt::ToUnicode(mpt::CharsetCP437AMS2, str); } // Channel names for(CHANNELINDEX chn = 0; chn < 32; chn++) { ChnSettings[chn].Reset(); file.ReadSizedString(ChnSettings[chn].szName); } // RLE-Packed description text AMS2Description descriptionHeader; if(!file.ReadStruct(descriptionHeader)) { return true; } if(descriptionHeader.packedLen > sizeof(descriptionHeader) && file.CanRead(descriptionHeader.packedLen - sizeof(descriptionHeader))) { const size_t textLength = descriptionHeader.packedLen - sizeof(descriptionHeader); std::vector textIn; file.ReadVector(textIn, textLength); std::string textOut; textOut.reserve(descriptionHeader.unpackedLen); size_t readLen = 0; while(readLen < textLength) { uint8 c = textIn[readLen++]; if(c == 0xFF && textLength - readLen >= 2) { c = textIn[readLen++]; uint32 count = textIn[readLen++]; textOut.insert(textOut.end(), count, c); } else { textOut.push_back(c); } } textOut = mpt::ToCharset(mpt::CharsetCP437, mpt::CharsetCP437AMS2, textOut); // Packed text doesn't include any line breaks! m_songMessage.ReadFixedLineLength(mpt::byte_cast(textOut.c_str()), textOut.length(), 74, 0); } // Read Order List ReadOrderFromFile(Order(), file, fileHeader.numOrds); // Read Patterns if(loadFlags & loadPatternData) Patterns.ResizeArray(fileHeader.numPats); for(PATTERNINDEX pat = 0; pat < fileHeader.numPats; pat++) { uint32 patLength = file.ReadUint32LE(); FileReader patternChunk = file.ReadChunk(patLength); if(loadFlags & loadPatternData) { const ROWINDEX numRows = patternChunk.ReadUint8() + 1; // We don't need to know the number of channels or commands. patternChunk.Skip(1); if(!Patterns.Insert(pat, numRows)) { continue; } char patternName[11]; patternChunk.ReadSizedString(patternName); Patterns[pat].SetName(patternName); ReadAMSPattern(Patterns[pat], true, patternChunk); } } if(!(loadFlags & loadSampleData)) { return true; } // Read Samples for(SAMPLEINDEX smp = 0; smp < GetNumSamples(); smp++) { if((sampleSettings[smp] & instrIndexMask) == 0) { // Only load samples that aren't part of a shadow instrument SampleIO( (Samples[smp + 1].uFlags & CHN_16BIT) ? SampleIO::_16bit : SampleIO::_8bit, SampleIO::mono, SampleIO::littleEndian, (sampleSettings[smp] & packStatusMask) ? SampleIO::AMS : SampleIO::signedPCM) .ReadSample(Samples[smp + 1], file); } } // Copy shadow samples for(SAMPLEINDEX smp = 0; smp < GetNumSamples(); smp++) { INSTRUMENTINDEX sourceInstr = (sampleSettings[smp] & instrIndexMask); if(sourceInstr == 0 || --sourceInstr >= firstSample.size()) { continue; } SAMPLEINDEX sourceSample = ((sampleSettings[smp] & sampleIndexMask) >> sampleIndexShift) + firstSample[sourceInstr]; if(sourceSample > GetNumSamples() || Samples[sourceSample].pSample == nullptr) { continue; } // Copy over original sample ModSample &sample = Samples[smp + 1]; ModSample &source = Samples[sourceSample]; sample.uFlags.set(CHN_16BIT, source.uFlags[CHN_16BIT]); sample.nLength = source.nLength; if(sample.AllocateSample()) { memcpy(sample.pSample, source.pSample, source.GetSampleSizeInBytes()); } } return true; } ///////////////////////////////////////////////////////////////////// // AMS Sample unpacking void AMSUnpack(const int8 * const source, size_t sourceSize, void * const dest, const size_t destSize, char packCharacter) { std::vector tempBuf(destSize, 0); size_t depackSize = destSize; // Unpack Loop { const int8 *in = source; int8 *out = tempBuf.data(); size_t i = sourceSize, j = destSize; while(i != 0 && j != 0) { int8 ch = *(in++); if(--i != 0 && ch == packCharacter) { uint8 repCount = *(in++); repCount = static_cast(std::min(static_cast(repCount), j)); if(--i != 0 && repCount) { ch = *(in++); i--; while(repCount-- != 0) { *(out++) = ch; j--; } } else { *(out++) = packCharacter; j--; } } else { *(out++) = ch; j--; } } // j should only be non-zero for truncated samples depackSize -= j; } // Bit Unpack Loop { int8 *out = tempBuf.data(); uint16 bitcount = 0x80; size_t k = 0; uint8 *dst = static_cast(dest); for(size_t i = 0; i < depackSize; i++) { uint8 al = *out++; uint16 dh = 0; for(uint16 count = 0; count < 8; count++) { uint16 bl = al & bitcount; bl = ((bl | (bl << 8)) >> ((dh + 8 - count) & 7)) & 0xFF; bitcount = ((bitcount | (bitcount << 8)) >> 1) & 0xFF; dst[k++] |= bl; if(k >= destSize) { k = 0; dh++; } } bitcount = ((bitcount | (bitcount << 8)) >> dh) & 0xFF; } } // Delta Unpack { int8 old = 0; int8 *out = static_cast(dest); for(size_t i = depackSize; i != 0; i--) { int pos = *reinterpret_cast(out); if(pos != 128 && (pos & 0x80) != 0) { pos = -(pos & 0x7F); } old -= static_cast(pos); *(out++) = old; } } } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Load_mo3.cpp0000644000372100037210000015663413226427473020267 00000000000000/* * Load_mo3.cpp * ------------ * Purpose: MO3 module loader. * Notes : (currently none) * Authors: Johannes Schultz / OpenMPT Devs * Based on documentation and the decompression routines from the * open-source UNMO3 project (https://github.com/lclevy/unmo3). * The modified decompression code has been relicensed to the BSD * license with permission from Laurent Clévy. * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" #include "../common/ComponentManager.h" #include "Tables.h" #include "../common/version.h" #include "MPEGFrame.h" #include "OggStream.h" #if defined(MPT_WITH_VORBIS) && defined(MPT_WITH_VORBISFILE) #include "../common/mptBufferIO.h" #endif #if defined(MPT_WITH_VORBIS) #include #endif #if defined(MPT_WITH_VORBISFILE) #include #include "../soundbase/SampleFormatConverters.h" #include "../soundbase/SampleFormatCopy.h" #endif #ifdef MPT_WITH_STBVORBIS #include #include "../soundbase/SampleFormatConverters.h" #include "../soundbase/SampleFormatCopy.h" #endif // MPT_WITH_STBVORBIS OPENMPT_NAMESPACE_BEGIN struct MO3FileHeader { enum MO3HeaderFlags { linearSlides = 0x0001, isS3M = 0x0002, s3mFastSlides = 0x0004, isMTM = 0x0008, // Actually this is simply "not XM". But if none of the S3M, MOD and IT flags are set, it's an MTM. s3mAmigaLimits = 0x0010, // 0x20 and 0x40 have been used in old versions for things that can be inferred from the file format anyway. // The official UNMO3 ignores them. isMOD = 0x0080, isIT = 0x0100, instrumentMode = 0x0200, itCompatGxx = 0x0400, itOldFX = 0x0800, modplugMode = 0x10000, unknown = 0x20000, // Always set modVBlank = 0x80000, hasPlugins = 0x100000, extFilterRange = 0x200000, }; uint8le numChannels; // 1...64 (limited by channel panning and volume) uint16le numOrders; uint16le restartPos; uint16le numPatterns; uint16le numTracks; uint16le numInstruments; uint16le numSamples; uint8le defaultSpeed; uint8le defaultTempo; uint32le flags; // See MO3HeaderFlags uint8le globalVol; // 0...128 in IT, 0...64 in S3M uint8le panSeparation; // 0...128 in IT int8le sampleVolume; // Only used in IT uint8le chnVolume[64]; // 0...64 uint8le chnPan[64]; // 0...256, 127 = surround uint8le sfxMacros[16]; uint8le fixedMacros[128][2]; }; MPT_BINARY_STRUCT(MO3FileHeader, 422) struct MO3Envelope { enum MO3EnvelopeFlags { envEnabled = 0x01, envSustain = 0x02, envLoop = 0x04, envFilter = 0x10, envCarry = 0x20, }; uint8le flags; // See MO3EnvelopeFlags uint8le numNodes; uint8le sustainStart; uint8le sustainEnd; uint8le loopStart; uint8le loopEnd; int16le points[25][2]; // Convert MO3 envelope data into OpenMPT's internal envelope format void ConvertToMPT(InstrumentEnvelope &mptEnv, uint8 envShift) const { if(flags & envEnabled) mptEnv.dwFlags.set(ENV_ENABLED); if(flags & envSustain) mptEnv.dwFlags.set(ENV_SUSTAIN); if(flags & envLoop) mptEnv.dwFlags.set(ENV_LOOP); if(flags & envFilter) mptEnv.dwFlags.set(ENV_FILTER); if(flags & envCarry) mptEnv.dwFlags.set(ENV_CARRY); mptEnv.resize(std::min(numNodes, 25)); mptEnv.nSustainStart = sustainStart; mptEnv.nSustainEnd = sustainEnd; mptEnv.nLoopStart = loopStart; mptEnv.nLoopEnd = loopEnd; for(uint32 ev = 0; ev < mptEnv.size(); ev++) { mptEnv[ev].tick = points[ev][0]; if(ev > 0 && mptEnv[ev].tick < mptEnv[ev - 1].tick) mptEnv[ev].tick = mptEnv[ev - 1].tick + 1; mptEnv[ev].value = static_cast(Clamp(points[ev][1] >> envShift, 0, 64)); } } }; MPT_BINARY_STRUCT(MO3Envelope, 106) struct MO3Instrument { enum MO3InstrumentFlags { playOnMIDI = 0x01, mute = 0x02, }; uint32le flags; // See MO3InstrumentFlags uint16le sampleMap[120][2]; MO3Envelope volEnv; MO3Envelope panEnv; MO3Envelope pitchEnv; struct XMVibratoSettings { uint8le type; uint8le sweep; uint8le depth; uint8le rate; } vibrato; // Applies to all samples of this instrument (XM) uint16le fadeOut; uint8le midiChannel; uint8le midiBank; uint8le midiPatch; uint8le midiBend; uint8le globalVol; // 0...128 uint16le panning; // 0...256 if enabled, 0xFFFF otherwise uint8le nna; uint8le pps; uint8le ppc; uint8le dct; uint8le dca; uint16le volSwing; // 0...100 uint16le panSwing; // 0...256 uint8le cutoff; // 0...127, + 128 if enabled uint8le resonance; // 0...127, + 128 if enabled // Convert MO3 instrument data into OpenMPT's internal instrument format void ConvertToMPT(ModInstrument &mptIns, MODTYPE type) const { if(type == MOD_TYPE_XM) { for(size_t i = 0; i < 96; i++) { mptIns.Keyboard[i + 12] = sampleMap[i][1] + 1; } } else { for(size_t i = 0; i < 120; i++) { mptIns.NoteMap[i] = static_cast(sampleMap[i][0] + NOTE_MIN); mptIns.Keyboard[i] = sampleMap[i][1] + 1; } } volEnv.ConvertToMPT(mptIns.VolEnv, 0); panEnv.ConvertToMPT(mptIns.PanEnv, 0); pitchEnv.ConvertToMPT(mptIns.PitchEnv, 5); mptIns.nFadeOut = fadeOut; if(midiChannel >= 128) { // Plugin mptIns.nMixPlug = midiChannel - 127; } else if(midiChannel < 17 && (flags & playOnMIDI)) { // XM / IT with recent encoder mptIns.nMidiChannel = midiChannel + MidiFirstChannel; } else if(midiChannel > 0 && midiChannel < 17) { // IT encoded with MO3 version prior to 2.4.1 (yes, channel 0 is represented the same way as "no channel") mptIns.nMidiChannel = midiChannel + MidiFirstChannel; } mptIns.wMidiBank = midiBank; mptIns.nMidiProgram = midiPatch; mptIns.midiPWD = midiBend; if(type == MOD_TYPE_IT) mptIns.nGlobalVol = std::min(globalVol, 128) / 2u; if(panning <= 256) { mptIns.nPan = panning; mptIns.dwFlags.set(INS_SETPANNING); } mptIns.nNNA = nna; mptIns.nPPS = pps; mptIns.nPPC = ppc; mptIns.nDCT = dct; mptIns.nDNA = dca; mptIns.nVolSwing = static_cast(std::min(volSwing, 100)); mptIns.nPanSwing = static_cast(std::min(panSwing, 256) / 4u); mptIns.SetCutoff(cutoff & 0x7F, (cutoff & 0x80) != 0); mptIns.SetResonance(resonance & 0x7F, (resonance & 0x80) != 0); } }; MPT_BINARY_STRUCT(MO3Instrument, 826) struct MO3Sample { enum MO3SampleFlags { smp16Bit = 0x01, smpLoop = 0x10, smpPingPongLoop = 0x20, smpSustain = 0x100, smpSustainPingPong = 0x200, smpStereo = 0x400, smpCompressionMPEG = 0x1000, // MPEG 1.0 / 2.0 / 2.5 sample smpCompressionOgg = 0x1000 | 0x2000, // Ogg sample smpSharedOgg = 0x1000 | 0x2000 | 0x4000, // Ogg sample with shared vorbis header smpDeltaCompression = 0x2000, // Deltas + compression smpDeltaPrediction = 0x4000, // Delta prediction + compression smpCompressionMask = 0x1000 | 0x2000 | 0x4000 }; int32le freqFinetune; // Frequency in S3M and IT, finetune (0...255) in MOD, MTM, XM int8le transpose; uint8le defaultVolume; // 0...64 uint16le panning; // 0...256 if enabled, 0xFFFF otherwise uint32le length; uint32le loopStart; uint32le loopEnd; uint16le flags; // See MO3SampleFlags uint8le vibType; uint8le vibSweep; uint8le vibDepth; uint8le vibRate; uint8le globalVol; // 0...64 in IT, in XM it represents the instrument number uint32le sustainStart; uint32le sustainEnd; int32le compressedSize; uint16le encoderDelay; // MP3: Ignore first n bytes of decoded output. Ogg: Shared Ogg header size // Convert MO3 sample data into OpenMPT's internal instrument format void ConvertToMPT(ModSample &mptSmp, MODTYPE type, bool frequencyIsHertz) const { mptSmp.Initialize(); if(type & (MOD_TYPE_IT | MOD_TYPE_S3M)) { if(frequencyIsHertz) mptSmp.nC5Speed = static_cast(freqFinetune); else mptSmp.nC5Speed = Util::Round(8363.0 * std::pow(2.0, (freqFinetune + 1408) / 1536.0)); } else { mptSmp.nFineTune = static_cast(freqFinetune); if(type != MOD_TYPE_MTM) mptSmp.nFineTune -= 128; mptSmp.RelativeTone = transpose; } mptSmp.nVolume = std::min(defaultVolume, 64) * 4u; if(panning <= 256) { mptSmp.nPan = panning; mptSmp.uFlags.set(CHN_PANNING); } mptSmp.nLength = length; mptSmp.nLoopStart = loopStart; mptSmp.nLoopEnd = loopEnd; if(flags & smpLoop) mptSmp.uFlags.set(CHN_LOOP); if(flags & smpPingPongLoop) mptSmp.uFlags.set(CHN_PINGPONGLOOP); if(flags & smpSustain) mptSmp.uFlags.set(CHN_SUSTAINLOOP); if(flags & smpSustainPingPong) mptSmp.uFlags.set(CHN_PINGPONGSUSTAIN); mptSmp.nVibType = AutoVibratoIT2XM[vibType & 7]; mptSmp.nVibSweep = vibSweep; mptSmp.nVibDepth = vibDepth; mptSmp.nVibRate = vibRate; if(type == MOD_TYPE_IT) mptSmp.nGlobalVol = std::min(globalVol, 64); mptSmp.nSustainStart = sustainStart; mptSmp.nSustainEnd = sustainEnd; } }; MPT_BINARY_STRUCT(MO3Sample, 41) // We need all this information for Ogg-compressed samples with shared headers: // A shared header can be taken from a sample that has not been read yet, so // we first need to read all headers, and then load the Ogg samples afterwards. struct MO3SampleChunk { FileReader chunk; uint16 headerSize; int16 sharedHeader; MO3SampleChunk(const FileReader &chunk_ = FileReader(), uint16 headerSize_ = 0, int16 sharedHeader_ = 0) : chunk(chunk_), headerSize(headerSize_), sharedHeader(sharedHeader_) { } }; // Unpack macros // shift control bits until it is empty: // a 0 bit means literal : the next data byte is copied // a 1 means compressed data // then the next 2 bits determines what is the LZ ptr // ('00' same as previous, else stored in stream) #define READ_CTRL_BIT \ data <<= 1; \ carry = (data > 0xFF); \ data &= 0xFF; \ if(data == 0) \ { \ data = file.ReadUint8(); \ data = (data << 1) + 1; \ carry = (data > 0xFF); \ data &= 0xFF; \ } // length coded within control stream: // most significant bit is 1 // then the first bit of each bits pair (noted n1), // until second bit is 0 (noted n0) #define DECODE_CTRL_BITS \ { \ strLen++; \ do { \ READ_CTRL_BIT; \ strLen = (strLen << 1) + carry; \ READ_CTRL_BIT; \ } while(carry); \ } static bool UnpackMO3Data(FileReader &file, uint8 *dst, uint32 size) { if(!size) { return false; } uint16 data = 0; int8 carry = 0; // x86 carry (used to propagate the most significant bit from one byte to another) int32 strLen = 0; // length of previous string int32 strOffset; // string offset uint8 *initDst = dst; uint32 ebp, previousPtr = 0; uint32 initSize = size; // Read first uncompressed byte *dst++ = file.ReadUint8(); size--; while(size > 0) { READ_CTRL_BIT; if(!carry) { // a 0 ctrl bit means 'copy', not compressed byte *dst++ = file.ReadUint8(); size--; } else { // a 1 ctrl bit means compressed bytes are following ebp = 0; // length adjustment DECODE_CTRL_BITS; // read length, and if strLen > 3 (coded using more than 1 bits pair) also part of the offset value strLen -=3; if(strLen < 0) { // means LZ ptr with same previous relative LZ ptr (saved one) strOffset = previousPtr; // restore previous Ptr strLen++; } else { // LZ ptr in ctrl stream strOffset = (strLen << 8) | file.ReadUint8(); // read less significant offset byte from stream strLen = 0; strOffset = ~strOffset; if(strOffset < -1280) ebp++; ebp++; // length is always at least 1 if(strOffset < -32000) ebp++; previousPtr = strOffset; // save current Ptr } // read the next 2 bits as part of strLen READ_CTRL_BIT; strLen = (strLen << 1) + carry; READ_CTRL_BIT; strLen = (strLen << 1) + carry; if(strLen == 0) { // length does not fit in 2 bits DECODE_CTRL_BITS; // decode length: 1 is the most significant bit, strLen += 2; // then first bit of each bits pairs (noted n1), until n0. } strLen += ebp; // length adjustment if(size >= static_cast(strLen) && strLen > 0) { // Copy previous string if(strOffset >= 0 || static_cast(dst - initDst) + strOffset < 0) { break; } size -= strLen; const uint8 *string = dst + strOffset; while(strLen > 0) { *dst++ = *string++; strLen--; } } else { break; } } } #ifdef MPT_BUILD_FUZZER // When using a fuzzer, we should not care if the decompressed buffer has the correct size. // This makes finding new interesting test cases much easier. while(size-- > 0) { *dst++ = 0; } #endif // MPT_BUILD_FUZZER return (dst - initDst) == static_cast(initSize); } struct MO3Delta8BitParams { typedef int8 sample_t; typedef uint8 unsigned_t; static const int shift = 7; static const uint8 dhInit = 4; static inline void Decode(FileReader &file, int8 &carry, uint16 &data, uint8 &/*dh*/, unsigned_t &val) { do { READ_CTRL_BIT; val = (val << 1) + carry; READ_CTRL_BIT; } while(carry); } }; struct MO3Delta16BitParams { typedef int16 sample_t; typedef uint16 unsigned_t; static const int shift = 15; static const uint8 dhInit = 8; static inline void Decode(FileReader &file, int8 &carry, uint16 &data, uint8 &dh, unsigned_t &val) { if(dh < 5) { do { READ_CTRL_BIT; val = (val << 1) + carry; READ_CTRL_BIT; val = (val << 1) + carry; READ_CTRL_BIT; \ } while(carry); } else { do { READ_CTRL_BIT; val = (val << 1) + carry; READ_CTRL_BIT; } while(carry); } } }; template static void UnpackMO3DeltaSample(FileReader &file, typename Properties::sample_t *dst, uint32 length, uint8 numChannels) { uint8 dh = Properties::dhInit, cl = 0; int8 carry = 0; uint16 data = 0; typename Properties::unsigned_t val; typename Properties::sample_t previous = 0; for(uint8 chn = 0; chn < numChannels; chn++) { typename Properties::sample_t *p = dst + chn; const typename Properties::sample_t * const pEnd = p + length * numChannels; while(p < pEnd) { val = 0; Properties::Decode(file, carry, data, dh, val); cl = dh; while(cl > 0) { READ_CTRL_BIT; val = (val << 1) + carry; cl--; } cl = 1; if(val >= 4) { cl = Properties::shift; while(((1 << cl) & val) == 0 && cl > 1) cl--; } dh = dh + cl; dh >>= 1; // next length in bits of encoded delta second part carry = val & 1; // sign of delta 1=+, 0=not val >>= 1; if(carry == 0) val = ~val; // negative delta val += previous; // previous value + delta *p = val; p += numChannels; previous = val; } } } template static void UnpackMO3DeltaPredictionSample(FileReader &file, typename Properties::sample_t *dst, uint32 length, uint8 numChannels) { uint8 dh = Properties::dhInit, cl = 0; int8 carry; uint16 data = 0; int32 next = 0; typename Properties::unsigned_t val = 0; typename Properties::sample_t sval = 0, delta = 0, previous = 0; for(uint8 chn = 0; chn < numChannels; chn++) { typename Properties::sample_t *p = dst + chn; const typename Properties::sample_t * const pEnd = p + length * numChannels; while(p < pEnd) { val = 0; Properties::Decode(file, carry, data, dh, val); cl = dh; // length in bits of: delta second part (right most bits of delta) and sign bit while(cl > 0) { READ_CTRL_BIT; val = (val << 1) + carry; cl--; } cl = 1; if(val >= 4) { cl = Properties::shift; while(((1 << cl) & val) == 0 && cl > 1) cl--; } dh = dh + cl; dh >>= 1; // next length in bits of encoded delta second part carry = val & 1; // sign of delta 1=+, 0=not val >>= 1; if(carry == 0) val = ~val; // negative delta delta = static_cast(val); val = val + static_cast(next); // predicted value + delta *p = val; p += numChannels; sval = static_cast(val); next = (sval * (1<<1)) + (delta >> 1) - previous; // corrected next value Limit(next, std::numeric_limits::min(), std::numeric_limits::max()); previous = sval; } } } #undef READ_CTRL_BIT #undef DECODE_CTRL_BITS #if defined(MPT_WITH_VORBIS) && defined(MPT_WITH_VORBISFILE) static size_t VorbisfileFilereaderRead(void *ptr, size_t size, size_t nmemb, void *datasource) { FileReader &file = *reinterpret_cast(datasource); return file.ReadRaw(mpt::void_cast(ptr), size * nmemb) / size; } static int VorbisfileFilereaderSeek(void *datasource, ogg_int64_t offset, int whence) { FileReader &file = *reinterpret_cast(datasource); switch(whence) { case SEEK_SET: { if(!Util::TypeCanHoldValue(offset)) { return -1; } return file.Seek(mpt::saturate_cast(offset)) ? 0 : -1; } break; case SEEK_CUR: { if(offset < 0) { if(offset == std::numeric_limits::min()) { return -1; } if(!Util::TypeCanHoldValue(0-offset)) { return -1; } return file.SkipBack(mpt::saturate_cast(0 - offset)) ? 0 : -1; } else { if(!Util::TypeCanHoldValue(offset)) { return -1; } return file.Skip(mpt::saturate_cast(offset)) ? 0 : -1; } } break; case SEEK_END: { if(!Util::TypeCanHoldValue(offset)) { return -1; } if(!Util::TypeCanHoldValue(file.GetLength() + offset)) { return -1; } return file.Seek(mpt::saturate_cast(file.GetLength() + offset)) ? 0 : -1; } break; default: return -1; } } static long VorbisfileFilereaderTell(void *datasource) { FileReader &file = *reinterpret_cast(datasource); FileReader::off_t result = file.GetPosition(); if(!Util::TypeCanHoldValue(result)) { return -1; } return static_cast(result); } #endif // MPT_WITH_VORBIS && MPT_WITH_VORBISFILE struct MO3ContainerHeader { char magic[3]; // MO3 uint8le version; uint32le musicSize; }; MPT_BINARY_STRUCT(MO3ContainerHeader, 8) static bool ValidateHeader(const MO3ContainerHeader &containerHeader) { if(std::memcmp(containerHeader.magic, "MO3", 3)) { return false; } if(containerHeader.musicSize <= sizeof(MO3FileHeader)) { return false; } if(containerHeader.version > 5) { return false; } return true; } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderMO3(MemoryFileReader file, const uint64 *pfilesize) { MO3ContainerHeader containerHeader; if(!file.ReadStruct(containerHeader)) { return ProbeWantMoreData; } if(!ValidateHeader(containerHeader)) { return ProbeFailure; } MPT_UNREFERENCED_PARAMETER(pfilesize); return ProbeSuccess; } bool CSoundFile::ReadMO3(FileReader &file, ModLoadingFlags loadFlags) { file.Rewind(); MO3ContainerHeader containerHeader; if(!file.ReadStruct(containerHeader)) { return false; } if(!ValidateHeader(containerHeader)) { return false; } if(loadFlags == onlyVerifyHeader) { return true; } const uint8 version = containerHeader.version; const uint32 musicSize = containerHeader.musicSize; uint32 compressedSize = uint32_max; if(version >= 5) { // Size of compressed music chunk compressedSize = file.ReadUint32LE(); #ifndef MPT_BUILD_FUZZER if(!file.CanRead(compressedSize)) { return false; } #endif // !MPT_BUILD_FUZZER } std::vector musicData(musicSize); if(!UnpackMO3Data(file, musicData.data(), musicSize)) { return false; } if(version >= 5) { file.Seek(12 + compressedSize); } InitializeGlobals(); InitializeChannels(); FileReader musicChunk(mpt::as_span(musicData)); musicChunk.ReadNullString(m_songName); musicChunk.ReadNullString(m_songMessage); MO3FileHeader fileHeader; if(!musicChunk.ReadStruct(fileHeader) || fileHeader.numChannels == 0 || fileHeader.numChannels > MAX_BASECHANNELS || fileHeader.numInstruments >= MAX_INSTRUMENTS || fileHeader.numSamples >= MAX_SAMPLES) { return false; } m_nChannels = fileHeader.numChannels; Order().SetRestartPos(fileHeader.restartPos); m_nInstruments = fileHeader.numInstruments; m_nSamples = fileHeader.numSamples; m_nDefaultSpeed = fileHeader.defaultSpeed ? fileHeader.defaultSpeed : 6; m_nDefaultTempo.Set(fileHeader.defaultTempo ? fileHeader.defaultTempo : 125, 0); m_ContainerType = MOD_CONTAINERTYPE_MO3; if(fileHeader.flags & MO3FileHeader::isIT) SetType(MOD_TYPE_IT); else if(fileHeader.flags & MO3FileHeader::isS3M) SetType(MOD_TYPE_S3M); else if(fileHeader.flags & MO3FileHeader::isMOD) SetType(MOD_TYPE_MOD); else if(fileHeader.flags & MO3FileHeader::isMTM) SetType(MOD_TYPE_MTM); else SetType(MOD_TYPE_XM); if(fileHeader.flags & MO3FileHeader::linearSlides) m_SongFlags.set(SONG_LINEARSLIDES); if((fileHeader.flags & MO3FileHeader::s3mAmigaLimits) && m_nType == MOD_TYPE_S3M) m_SongFlags.set(SONG_AMIGALIMITS); if((fileHeader.flags & MO3FileHeader::s3mFastSlides) && m_nType == MOD_TYPE_S3M) m_SongFlags.set(SONG_FASTVOLSLIDES); if(!(fileHeader.flags & MO3FileHeader::itOldFX) && m_nType == MOD_TYPE_IT) m_SongFlags.set(SONG_ITOLDEFFECTS); if(!(fileHeader.flags & MO3FileHeader::itCompatGxx) && m_nType == MOD_TYPE_IT) m_SongFlags.set(SONG_ITCOMPATGXX); if(fileHeader.flags & MO3FileHeader::extFilterRange) m_SongFlags.set(SONG_EXFILTERRANGE); if(fileHeader.flags & MO3FileHeader::modVBlank) m_playBehaviour.set(kMODVBlankTiming); if(m_nType == MOD_TYPE_IT) m_nDefaultGlobalVolume = std::min(fileHeader.globalVol, 128) * 2; else if(m_nType == MOD_TYPE_S3M) m_nDefaultGlobalVolume = std::min(fileHeader.globalVol, 64) * 4; if(fileHeader.sampleVolume < 0) m_nSamplePreAmp = fileHeader.sampleVolume + 52; else m_nSamplePreAmp = static_cast(std::exp(fileHeader.sampleVolume * 3.1 / 20.0)) + 51; // Header only has room for 64 channels, like in IT const CHANNELINDEX headerChannels = std::min(m_nChannels, CHANNELINDEX(64)); for(CHANNELINDEX i = 0; i < headerChannels; i++) { if(m_nType == MOD_TYPE_IT) ChnSettings[i].nVolume = std::min(fileHeader.chnVolume[i], 64); if(m_nType != MOD_TYPE_XM) { if(fileHeader.chnPan[i] == 127) ChnSettings[i].dwFlags = CHN_SURROUND; else if(fileHeader.chnPan[i] == 255) ChnSettings[i].nPan = 256; else ChnSettings[i].nPan = fileHeader.chnPan[i]; } } bool anyMacros = false; for(uint32 i = 0; i < 16; i++) { if(fileHeader.sfxMacros[i]) anyMacros = true; } for(uint32 i = 0; i < 128; i++) { if(fileHeader.fixedMacros[i][1]) anyMacros = true; } if(anyMacros) { for(uint32 i = 0; i < 16; i++) { if(fileHeader.sfxMacros[i]) sprintf(m_MidiCfg.szMidiSFXExt[i], "F0F0%02Xz", fileHeader.sfxMacros[i] - 1); else strcpy(m_MidiCfg.szMidiSFXExt[i], ""); } for(uint32 i = 0; i < 128; i++) { if(fileHeader.fixedMacros[i][1]) sprintf(m_MidiCfg.szMidiZXXExt[i], "F0F0%02X%02X", fileHeader.fixedMacros[i][1] - 1, fileHeader.fixedMacros[i][0].get()); else strcpy(m_MidiCfg.szMidiZXXExt[i], ""); } } ReadOrderFromFile(Order(), musicChunk, fileHeader.numOrders, 0xFF, 0xFE); // Track assignments for all patterns FileReader trackChunk = musicChunk.ReadChunk(fileHeader.numPatterns * fileHeader.numChannels * sizeof(uint16)); FileReader patLengthChunk = musicChunk.ReadChunk(fileHeader.numPatterns * sizeof(uint16)); std::vector tracks(fileHeader.numTracks); for(auto &track : tracks) { uint32 len = musicChunk.ReadUint32LE(); track = musicChunk.ReadChunk(len); } /* MO3 pattern commands: 01 = Note 02 = Instrument 03 = CMD_ARPEGGIO (IT, XM, S3M, MOD, MTM) 04 = CMD_PORTAMENTOUP (XM, MOD, MTM) [for formats with separate fine slides] 05 = CMD_PORTAMENTODOWN (XM, MOD, MTM) [for formats with separate fine slides] 06 = CMD_TONEPORTAMENTO (IT, XM, S3M, MOD, MTM) / VOLCMD_TONEPORTA (IT, XM) 07 = CMD_VIBRATO (IT, XM, S3M, MOD, MTM) / VOLCMD_VIBRATODEPTH (IT) 08 = CMD_TONEPORTAVOL (XM, MOD, MTM) 09 = CMD_VIBRATOVOL (XM, MOD, MTM) 0A = CMD_TREMOLO (IT, XM, S3M, MOD, MTM) 0B = CMD_PANNING8 (IT, XM, S3M, MOD, MTM) / VOLCMD_PANNING (IT, XM) 0C = CMD_OFFSET (IT, XM, S3M, MOD, MTM) 0D = CMD_VOLUMESLIDE (XM, MOD, MTM) 0E = CMD_POSITIONJUMP (IT, XM, S3M, MOD, MTM) 0F = CMD_VOLUME (XM, MOD, MTM) / VOLCMD_VOLUME (IT, XM, S3M) 10 = CMD_PATTERNBREAK (IT, XM, MOD, MTM) - BCD-encoded in MOD/XM/S3M/MTM! 11 = CMD_MODCMDEX (XM, MOD, MTM) 12 = CMD_TEMPO (XM, MOD, MTM) / CMD_SPEED (XM, MOD, MTM) 13 = CMD_TREMOR (XM) 14 = VOLCMD_VOLSLIDEUP x=X0 (XM) / VOLCMD_VOLSLIDEDOWN x=0X (XM) 15 = VOLCMD_FINEVOLUP x=X0 (XM) / VOLCMD_FINEVOLDOWN x=0X (XM) 16 = CMD_GLOBALVOLUME (IT, XM, S3M) 17 = CMD_GLOBALVOLSLIDE (XM) 18 = CMD_KEYOFF (XM) 19 = CMD_SETENVPOSITION (XM) 1A = CMD_PANNINGSLIDE (XM) 1B = VOLCMD_PANSLIDELEFT x=0X (XM) / VOLCMD_PANSLIDERIGHT x=X0 (XM) 1C = CMD_RETRIG (XM) 1D = CMD_XFINEPORTAUPDOWN X1x (XM) 1E = CMD_XFINEPORTAUPDOWN X2x (XM) 1F = VOLCMD_VIBRATOSPEED (XM) 20 = VOLCMD_VIBRATODEPTH (XM) 21 = CMD_SPEED (IT, S3M) 22 = CMD_VOLUMESLIDE (IT, S3M) 23 = CMD_PORTAMENTODOWN (IT, S3M) [for formats without separate fine slides] 24 = CMD_PORTAMENTOUP (IT, S3M) [for formats without separate fine slides] 25 = CMD_TREMOR (IT, S3M) 26 = CMD_RETRIG (IT, S3M) 27 = CMD_FINEVIBRATO (IT, S3M) 28 = CMD_CHANNELVOLUME (IT, S3M) 29 = CMD_CHANNELVOLSLIDE (IT, S3M) 2A = CMD_PANNINGSLIDE (IT, S3M) 2B = CMD_S3MCMDEX (IT, S3M) 2C = CMD_TEMPO (IT, S3M) 2D = CMD_GLOBALVOLSLIDE (IT, S3M) 2E = CMD_PANBRELLO (IT, XM, S3M) 2F = CMD_MIDI (IT, XM, S3M) 30 = VOLCMD_FINEVOLUP x=0...9 (IT) / VOLCMD_FINEVOLDOWN x=10...19 (IT) / VOLCMD_VOLSLIDEUP x=20...29 (IT) / VOLCMD_VOLSLIDEDOWN x=30...39 (IT) 31 = VOLCMD_PORTADOWN (IT) 32 = VOLCMD_PORTAUP (IT) 33 = Unused XM command "W" (XM) 34 = Any other IT volume column command to support OpenMPT extensions (IT) 35 = CMD_XPARAM (IT) 36 = CMD_SMOOTHMIDI (IT) 37 = CMD_DELAYCUT (IT) Note: S3M/IT CMD_TONEPORTAVOL / CMD_VIBRATOVOL are encoded as two commands: K= 07 00 22 x L= 06 00 22 x */ static const ModCommand::COMMAND effTrans[] = { CMD_NONE, CMD_NONE, CMD_NONE, CMD_ARPEGGIO, CMD_PORTAMENTOUP, CMD_PORTAMENTODOWN, CMD_TONEPORTAMENTO, CMD_VIBRATO, CMD_TONEPORTAVOL, CMD_VIBRATOVOL, CMD_TREMOLO, CMD_PANNING8, CMD_OFFSET, CMD_VOLUMESLIDE, CMD_POSITIONJUMP, CMD_VOLUME, CMD_PATTERNBREAK, CMD_MODCMDEX, CMD_TEMPO, CMD_TREMOR, VOLCMD_VOLSLIDEUP, VOLCMD_FINEVOLUP, CMD_GLOBALVOLUME, CMD_GLOBALVOLSLIDE, CMD_KEYOFF, CMD_SETENVPOSITION, CMD_PANNINGSLIDE, VOLCMD_PANSLIDELEFT, CMD_RETRIG, CMD_XFINEPORTAUPDOWN, CMD_XFINEPORTAUPDOWN, VOLCMD_VIBRATOSPEED, VOLCMD_VIBRATODEPTH, CMD_SPEED, CMD_VOLUMESLIDE, CMD_PORTAMENTODOWN, CMD_PORTAMENTOUP, CMD_TREMOR, CMD_RETRIG, CMD_FINEVIBRATO, CMD_CHANNELVOLUME, CMD_CHANNELVOLSLIDE, CMD_PANNINGSLIDE, CMD_S3MCMDEX, CMD_TEMPO, CMD_GLOBALVOLSLIDE, CMD_PANBRELLO, CMD_MIDI, VOLCMD_FINEVOLUP, VOLCMD_PORTADOWN, VOLCMD_PORTAUP, CMD_NONE, VOLCMD_OFFSET, CMD_XPARAM, CMD_SMOOTHMIDI, CMD_DELAYCUT }; uint8 noteOffset = NOTE_MIN; if(m_nType == MOD_TYPE_MTM) noteOffset = 13 + NOTE_MIN; else if(m_nType != MOD_TYPE_IT) noteOffset = 12 + NOTE_MIN; bool onlyAmigaNotes = true; if(loadFlags & loadPatternData) Patterns.ResizeArray(fileHeader.numPatterns); for(PATTERNINDEX pat = 0; pat < fileHeader.numPatterns; pat++) { const ROWINDEX numRows = patLengthChunk.ReadUint16LE(); if(!(loadFlags & loadPatternData) || !Patterns.Insert(pat, numRows)) continue; for(CHANNELINDEX chn = 0; chn < fileHeader.numChannels; chn++) { uint16 trackIndex = trackChunk.ReadUint16LE(); if(trackIndex >= tracks.size()) continue; FileReader &track = tracks[trackIndex]; track.Rewind(); ROWINDEX row = 0; ModCommand *patData = Patterns[pat].GetpModCommand(0, chn); while(row < numRows) { const uint8 b = track.ReadUint8(); if(!b) break; const uint8 numCommands = (b & 0x0F), rep = (b >> 4); ModCommand m = ModCommand::Empty(); for(uint8 c = 0; c < numCommands; c++) { uint8 cmd[2]; track.ReadArray(cmd); // Import pattern commands switch(cmd[0]) { case 0x01: // Note m.note = cmd[1]; if(m.note < 120) m.note += noteOffset; else if(m.note == 0xFF) m.note = NOTE_KEYOFF; else if(m.note == 0xFE) m.note = NOTE_NOTECUT; else m.note = NOTE_FADE; if(!m.IsAmigaNote()) onlyAmigaNotes = false; break; case 0x02: // Instrument m.instr = cmd[1] + 1; break; case 0x06: // Tone portamento if(m.volcmd == VOLCMD_NONE && m_nType == MOD_TYPE_XM && !(cmd[1] & 0x0F)) { m.volcmd = VOLCMD_TONEPORTAMENTO; m.vol = cmd[1] >> 4; break; } else if(m.volcmd == VOLCMD_NONE && m_nType == MOD_TYPE_IT) { for(uint8 i = 0; i < 10; i++) { if(ImpulseTrackerPortaVolCmd[i] == cmd[1]) { m.volcmd = VOLCMD_TONEPORTAMENTO; m.vol = i; break; } } if(m.volcmd != VOLCMD_NONE) break; } m.command = CMD_TONEPORTAMENTO; m.param = cmd[1]; break; case 0x07: // Vibrato if(m.volcmd == VOLCMD_NONE && cmd[1] < 10 && m_nType == MOD_TYPE_IT) { m.volcmd = VOLCMD_VIBRATODEPTH; m.vol = cmd[1]; } else { m.command = CMD_VIBRATO; m.param = cmd[1]; } break; case 0x0B: // Panning if(m.volcmd == VOLCMD_NONE) { if(m_nType == MOD_TYPE_IT && cmd[1] == 0xFF) { m.volcmd = VOLCMD_PANNING; m.vol = 64; break; } if((m_nType == MOD_TYPE_IT && !(cmd[1] & 0x03)) || (m_nType == MOD_TYPE_XM && !(cmd[1] & 0x0F))) { m.volcmd = VOLCMD_PANNING; m.vol = cmd[1] / 4; break; } } m.command = CMD_PANNING8; m.param = cmd[1]; break; case 0x0F: // Volume if(m_nType != MOD_TYPE_MOD && m.volcmd == VOLCMD_NONE && cmd[1] <= 64) { m.volcmd = VOLCMD_VOLUME; m.vol = cmd[1]; } else { m.command = CMD_VOLUME; m.param = cmd[1]; } break; case 0x10: // Pattern break m.command = CMD_PATTERNBREAK; m.param = cmd[1]; if(m_nType != MOD_TYPE_IT) m.param = ((m.param >> 4) * 10) + (m.param & 0x0F); break; case 0x12: // Combined Tempo / Speed command m.param = cmd[1]; if(m.param < 0x20) m.command = CMD_SPEED; else m.command = CMD_TEMPO; break; case 0x14: case 0x15: // XM volume column volume slides if(cmd[1] & 0xF0) { m.volcmd = static_cast((cmd[0] == 0x14) ? VOLCMD_VOLSLIDEUP : VOLCMD_FINEVOLUP); m.vol = cmd[1] >> 4; } else { m.volcmd = static_cast((cmd[0] == 0x14) ? VOLCMD_VOLSLIDEDOWN : VOLCMD_FINEVOLDOWN); m.vol = cmd[1] & 0x0F; } break; case 0x1B: // XM volume column panning slides if(cmd[1] & 0xF0) { m.volcmd = VOLCMD_PANSLIDERIGHT; m.vol = cmd[1] >> 4; } else { m.volcmd = VOLCMD_PANSLIDELEFT; m.vol = cmd[1] & 0x0F; } break; case 0x1D: // XM extra fine porta up m.command = CMD_XFINEPORTAUPDOWN; m.param = 0x10 | cmd[1]; break; case 0x1E: // XM extra fine porta down m.command = CMD_XFINEPORTAUPDOWN; m.param = 0x20 | cmd[1]; break; case 0x1F: case 0x20: // XM volume column vibrato m.volcmd = effTrans[cmd[0]]; m.vol = cmd[1]; break; case 0x22: // IT / S3M volume slide if(m.command == CMD_TONEPORTAMENTO) m.command = CMD_TONEPORTAVOL; else if(m.command == CMD_VIBRATO) m.command = CMD_VIBRATOVOL; else m.command = CMD_VOLUMESLIDE; m.param = cmd[1]; break; case 0x30: // IT volume column volume slides m.vol = cmd[1] % 10; if(cmd[1] < 10) m.volcmd = VOLCMD_FINEVOLUP; else if(cmd[1] < 20) m.volcmd = VOLCMD_FINEVOLDOWN; else if(cmd[1] < 30) m.volcmd = VOLCMD_VOLSLIDEUP; else if(cmd[1] < 40) m.volcmd = VOLCMD_VOLSLIDEDOWN; break; case 0x31: case 0x32: // IT volume column portamento m.volcmd = effTrans[cmd[0]]; m.vol = cmd[1]; break; case 0x34: // Any unrecognized IT volume command if(cmd[1] >= 223 && cmd[1] <= 232) { m.volcmd = VOLCMD_OFFSET; m.vol = cmd[1] - 223; } break; default: if(cmd[0] < CountOf(effTrans)) { m.command = effTrans[cmd[0]]; m.param = cmd[1]; } break; } } #ifdef MODPLUG_TRACKER if(m_nType == MOD_TYPE_MTM) m.Convert(MOD_TYPE_MTM, MOD_TYPE_S3M, *this); #endif ROWINDEX targetRow = std::min(row + rep, numRows); while(row < targetRow) { *patData = m; patData += fileHeader.numChannels; row++; } } } } if(GetType() == MOD_TYPE_MOD && GetNumChannels() == 4 && onlyAmigaNotes) { m_SongFlags.set(SONG_AMIGALIMITS | SONG_ISAMIGA); } const bool isSampleMode = (m_nType != MOD_TYPE_XM && !(fileHeader.flags & MO3FileHeader::instrumentMode)); std::vector instrVibrato(m_nType == MOD_TYPE_XM ? m_nInstruments : 0); for(INSTRUMENTINDEX ins = 1; ins <= m_nInstruments; ins++) { ModInstrument *pIns = nullptr; if(isSampleMode || (pIns = AllocateInstrument(ins)) == nullptr) { // Even in IT sample mode, instrument headers are still stored.... while(musicChunk.ReadUint8() != 0); if(version >= 5) { while(musicChunk.ReadUint8() != 0); } musicChunk.Skip(sizeof(MO3Instrument)); continue; } std::string name; musicChunk.ReadNullString(name); mpt::String::Copy(pIns->name, name); if(version >= 5) { musicChunk.ReadNullString(name); mpt::String::Copy(pIns->filename, name); } MO3Instrument insHeader; if(!musicChunk.ReadStruct(insHeader)) break; insHeader.ConvertToMPT(*pIns, m_nType); if(m_nType == MOD_TYPE_XM) instrVibrato[ins - 1] = insHeader.vibrato; } if(isSampleMode) m_nInstruments = 0; std::vector sampleChunks(m_nSamples); const bool frequencyIsHertz = (version >= 5 || !(fileHeader.flags & MO3FileHeader::linearSlides)); bool unsupportedSamples = false; for(SAMPLEINDEX smp = 1; smp <= m_nSamples; smp++) { ModSample &sample = Samples[smp]; std::string name; musicChunk.ReadNullString(name); mpt::String::Copy(m_szNames[smp], name); if(version >= 5) { musicChunk.ReadNullString(name); mpt::String::Copy(sample.filename, name); } MO3Sample smpHeader; if(!musicChunk.ReadStruct(smpHeader)) break; smpHeader.ConvertToMPT(sample, m_nType, frequencyIsHertz); int16 sharedOggHeader = 0; if(version >= 5 && (smpHeader.flags & MO3Sample::smpCompressionMask) == MO3Sample::smpSharedOgg) { sharedOggHeader = musicChunk.ReadInt16LE(); } if(!(loadFlags & loadSampleData)) continue; const uint32 compression = (smpHeader.flags & MO3Sample::smpCompressionMask); if(!compression && smpHeader.compressedSize == 0) { // Uncompressed sample SampleIO( (smpHeader.flags & MO3Sample::smp16Bit) ? SampleIO::_16bit : SampleIO::_8bit, (smpHeader.flags & MO3Sample::smpStereo) ? SampleIO::stereoSplit : SampleIO::mono, SampleIO::littleEndian, SampleIO::signedPCM) .ReadSample(Samples[smp], file); } else if(smpHeader.compressedSize < 0 && (smp + smpHeader.compressedSize) > 0) { // Duplicate sample const ModSample &smpFrom = Samples[smp + smpHeader.compressedSize]; LimitMax(sample.nLength, smpFrom.nLength); sample.uFlags.set(CHN_16BIT, smpFrom.uFlags[CHN_16BIT]); sample.uFlags.set(CHN_STEREO, smpFrom.uFlags[CHN_STEREO]); if(smpFrom.pSample != nullptr && sample.AllocateSample()) { memcpy(sample.pSample, smpFrom.pSample, sample.GetSampleSizeInBytes()); } } else if(smpHeader.compressedSize > 0) { if(smpHeader.flags & MO3Sample::smp16Bit) sample.uFlags.set(CHN_16BIT); if(smpHeader.flags & MO3Sample::smpStereo) sample.uFlags.set(CHN_STEREO); FileReader sampleData = file.ReadChunk(smpHeader.compressedSize); const uint8 numChannels = sample.GetNumChannels(); if(compression == MO3Sample::smpDeltaCompression) { if(sample.AllocateSample()) { if(smpHeader.flags & MO3Sample::smp16Bit) UnpackMO3DeltaSample(sampleData, sample.pSample16, sample.nLength, numChannels); else UnpackMO3DeltaSample(sampleData, sample.pSample8, sample.nLength, numChannels); } } else if(compression == MO3Sample::smpDeltaPrediction) { if(sample.AllocateSample()) { if(smpHeader.flags & MO3Sample::smp16Bit) UnpackMO3DeltaPredictionSample(sampleData, sample.pSample16, sample.nLength, numChannels); else UnpackMO3DeltaPredictionSample(sampleData, sample.pSample8, sample.nLength, numChannels); } } else if(compression == MO3Sample::smpCompressionOgg || compression == MO3Sample::smpSharedOgg) { // Since shared Ogg headers can stem from a sample that has not been read yet, postpone Ogg import. sampleChunks[smp - 1] = MO3SampleChunk(sampleData, smpHeader.encoderDelay, sharedOggHeader); } else if(compression == MO3Sample::smpCompressionMPEG) { // Old MO3 encoders didn't remove LAME info frames. This is unfortunate since the encoder delay // specified in the sample header does not take the gapless information from the LAME info frame // into account. We should not depend on the MP3 decoder's capabilities to read or ignore such frames: // - libmpg123 has MPG123_IGNORE_INFOFRAME but that requires API version 31 (mpg123 v1.14) or higher // - Media Foundation does (currently) not read LAME gapless information at all // So we just play safe and remove such frames. FileReader mpegData(sampleData); MPEGFrame frame(sampleData); uint16 frameDelay = frame.numSamples * 2; if(frame.isLAME && smpHeader.encoderDelay >= frameDelay) { // The info frame does not produce any output, but still counts towards the encoder delay. smpHeader.encoderDelay -= frameDelay; sampleData.Seek(frame.frameSize); mpegData = sampleData.ReadChunk(sampleData.BytesLeft()); } if(ReadMP3Sample(smp, mpegData, true) || ReadMediaFoundationSample(smp, mpegData, true)) { if(smpHeader.encoderDelay > 0 && smpHeader.encoderDelay < sample.GetSampleSizeInBytes()) { SmpLength delay = smpHeader.encoderDelay / sample.GetBytesPerSample(); memmove(sample.pSample8, sample.pSample8 + smpHeader.encoderDelay, sample.GetSampleSizeInBytes() - smpHeader.encoderDelay); sample.nLength -= delay; } LimitMax(sample.nLength, smpHeader.length); } else { unsupportedSamples = true; } } else { unsupportedSamples = true; } } } // Now we can load Ogg samples with shared headers. if(loadFlags & loadSampleData) { for(SAMPLEINDEX smp = 1; smp <= m_nSamples; smp++) { MO3SampleChunk &sampleChunk = sampleChunks[smp - 1]; // Is this an Ogg sample? if(!sampleChunk.chunk.IsValid()) continue; SAMPLEINDEX sharedOggHeader = smp + sampleChunk.sharedHeader; // Which chunk are we going to read the header from? // Note: Every Ogg stream has a unique serial number. // stb_vorbis (currently) ignores this serial number so we can just stitch // together our sample without adjusting the shared header's serial number. const bool sharedHeader = sharedOggHeader != smp && sharedOggHeader > 0 && sharedOggHeader <= m_nSamples; #if defined(MPT_WITH_VORBIS) && defined(MPT_WITH_VORBISFILE) std::vector mergedData; if(sharedHeader) { // Prepend the shared header to the actual sample data and adjust bitstream serial numbers. // We do not handle multiple muxed logical streams as they do not exist in practice in mo3. // We assume sequence numbers are consecutive at the end of the headers. // Corrupted pages get dropped as required by Ogg spec. We cannot do any further sane parsing on them anyway. // We do not match up multiple muxed stream properly as this wold need parsing of actual packet data to determine or guess the codec. // Ogg Vorbis files may contain at least an additional Ogg Skeleton stream. It is not clear whether these actually exist in MO3. // We do not validate packet structure or logical bitstream structure (i.e. sequence numbers and granule positions). // TODO: At least handle Skeleton streams here, as they violate our stream ordering assumptions here. #if 0 // This block may still turn out to be useful as it does a more thourough validation of the stream than the optimized version below. // We copy the whole data into a single consecutive buffer in order to keep things simple when interfacing libvorbisfile. // We could in theory only adjust the header and pass 2 chunks to libvorbisfile. // Another option would be to demux both chunks on our own (or using libogg) and pass the raw packet data to libvorbis directly. mpt::ostringstream mergedStream(std::ios::binary); mergedStream.imbue(std::locale::classic()); sampleChunks[sharedOggHeader - 1].chunk.Rewind(); FileReader sharedChunk = sampleChunks[sharedOggHeader - 1].chunk.ReadChunk(sampleChunk.headerSize); sharedChunk.Rewind(); std::vector streamSerials; Ogg::PageInfo oggPageInfo; std::vector oggPageData; streamSerials.clear(); while(Ogg::ReadPageAndSkipJunk(sharedChunk, oggPageInfo, oggPageData)) { auto it = std::find(streamSerials.begin(), streamSerials.end(), oggPageInfo.header.bitstream_serial_number); if(it == streamSerials.end()) { streamSerials.push_back(oggPageInfo.header.bitstream_serial_number); it = streamSerials.begin() + (streamSerials.size() - 1); } uint32 newSerial = it - streamSerials.begin() + 1; oggPageInfo.header.bitstream_serial_number = newSerial; Ogg::UpdatePageCRC(oggPageInfo, oggPageData); Ogg::WritePage(mergedStream, oggPageInfo, oggPageData); } streamSerials.clear(); while(Ogg::ReadPageAndSkipJunk(sampleChunk.chunk, oggPageInfo, oggPageData)) { auto it = std::find(streamSerials.begin(), streamSerials.end(), oggPageInfo.header.bitstream_serial_number); if(it == streamSerials.end()) { streamSerials.push_back(oggPageInfo.header.bitstream_serial_number); it = streamSerials.begin() + (streamSerials.size() - 1); } uint32 newSerial = it - streamSerials.begin() + 1; oggPageInfo.header.bitstream_serial_number = newSerial; Ogg::UpdatePageCRC(oggPageInfo, oggPageData); Ogg::WritePage(mergedStream, oggPageInfo, oggPageData); } std::string mergedStreamData = mergedStream.str(); mergedData.insert(mergedData.end(), mergedStreamData.begin(), mergedStreamData.end()); #else // We assume same ordering of streams in both header and data if // multiple streams are present. mpt::ostringstream mergedStream(std::ios::binary); mergedStream.imbue(std::locale::classic()); sampleChunks[sharedOggHeader - 1].chunk.Rewind(); FileReader sharedChunk = sampleChunks[sharedOggHeader - 1].chunk.ReadChunk(sampleChunk.headerSize); sharedChunk.Rewind(); std::vector dataStreamSerials; std::vector headStreamSerials; Ogg::PageInfo oggPageInfo; std::vector oggPageData; // Gather bitstream serial numbers form sample data chunk dataStreamSerials.clear(); while(Ogg::ReadPageAndSkipJunk(sampleChunk.chunk, oggPageInfo, oggPageData)) { auto it = std::find(dataStreamSerials.begin(), dataStreamSerials.end(), oggPageInfo.header.bitstream_serial_number); if(it == dataStreamSerials.end()) { dataStreamSerials.push_back(oggPageInfo.header.bitstream_serial_number); } } // Apply the data bitstream serial numbers to the header headStreamSerials.clear(); while(Ogg::ReadPageAndSkipJunk(sharedChunk, oggPageInfo, oggPageData)) { auto it = std::find(headStreamSerials.begin(), headStreamSerials.end(), oggPageInfo.header.bitstream_serial_number); if(it == headStreamSerials.end()) { headStreamSerials.push_back(oggPageInfo.header.bitstream_serial_number); it = headStreamSerials.begin() + (headStreamSerials.size() - 1); } uint32 newSerial = 0; if(dataStreamSerials.size() >= static_cast(it - headStreamSerials.begin())) { // Found corresponding stream in data chunk. newSerial = dataStreamSerials[it - headStreamSerials.begin()]; } else { // No corresponding stream in data chunk. Find a free serialno. std::size_t extraIndex = (it - headStreamSerials.begin()) - dataStreamSerials.size(); for(newSerial = 1; newSerial < 0xffffffffu; ++newSerial) { auto dss = std::find(dataStreamSerials.begin(), dataStreamSerials.end(), newSerial); if(dss == dataStreamSerials.end()) { extraIndex -= 1; } if(extraIndex == 0) { break; } } } oggPageInfo.header.bitstream_serial_number = newSerial; Ogg::UpdatePageCRC(oggPageInfo, oggPageData); Ogg::WritePage(mergedStream, oggPageInfo, oggPageData); } if(headStreamSerials.size() > 1) { AddToLog(LogWarning, mpt::format(MPT_USTRING("Sample %1: Ogg Vorbis data with shared header and multiple logical bitstreams in header chunk found. This may be handled incorrectly."))(smp)); } else if(dataStreamSerials.size() > 1) { AddToLog(LogWarning, mpt::format(MPT_USTRING("Sample %1: Ogg Vorbis sample with shared header and multiple logical bitstreams found. This may be handled incorrectly."))(smp)); } else if((dataStreamSerials.size() == 1) && (headStreamSerials.size() == 1) && (dataStreamSerials[0] != headStreamSerials[0])) { AddToLog(LogInformation, mpt::format(MPT_USTRING("Sample %1: Ogg Vorbis data with shared header and different logical bitstream serials found."))(smp)); } std::string mergedStreamData = mergedStream.str(); mergedData.insert(mergedData.end(), mergedStreamData.begin(), mergedStreamData.end()); sampleChunk.chunk.Rewind(); FileReader::PinnedRawDataView sampleChunkView = sampleChunk.chunk.GetPinnedRawDataView(); mergedData.insert(mergedData.end(), sampleChunkView.begin(), sampleChunkView.end()); #endif } FileReader mergedDataChunk(mpt::byte_cast(mpt::as_span(mergedData))); FileReader &sampleData = sharedHeader ? mergedDataChunk : sampleChunk.chunk; FileReader &headerChunk = sampleData; #else // !(MPT_WITH_VORBIS && MPT_WITH_VORBISFILE) FileReader &sampleData = sampleChunk.chunk; FileReader &headerChunk = sharedHeader ? sampleChunks[sharedOggHeader - 1].chunk : sampleData; #if defined(MPT_WITH_STBVORBIS) std::size_t initialRead = sharedHeader ? sampleChunk.headerSize : headerChunk.GetLength(); #endif // MPT_WITH_STBVORBIS #endif // MPT_WITH_VORBIS && MPT_WITH_VORBISFILE headerChunk.Rewind(); if(sharedHeader && !headerChunk.CanRead(sampleChunk.headerSize)) continue; #if defined(MPT_WITH_VORBIS) && defined(MPT_WITH_VORBISFILE) ov_callbacks callbacks = { &VorbisfileFilereaderRead, &VorbisfileFilereaderSeek, NULL, &VorbisfileFilereaderTell }; OggVorbis_File vf; MemsetZero(vf); if(ov_open_callbacks(&sampleData, &vf, NULL, 0, callbacks) == 0) { if(ov_streams(&vf) == 1) { // we do not support chained vorbis samples vorbis_info *vi = ov_info(&vf, -1); if(vi && vi->rate > 0 && vi->channels > 0) { ModSample &sample = Samples[smp]; sample.AllocateSample(); SmpLength offset = 0; int channels = vi->channels; int current_section = 0; long decodedSamples = 0; bool eof = false; while(!eof && offset < sample.nLength && sample.pSample != nullptr) { float **output = nullptr; long ret = ov_read_float(&vf, &output, 1024, ¤t_section); if(ret == 0) { eof = true; } else if(ret < 0) { // stream error, just try to continue } else { decodedSamples = ret; LimitMax(decodedSamples, mpt::saturate_cast(sample.nLength - offset)); if(decodedSamples > 0 && channels == sample.GetNumChannels()) { for(int chn = 0; chn < channels; chn++) { if(sample.uFlags[CHN_16BIT]) { CopyChannelToInterleaved >(sample.pSample16 + offset * sample.GetNumChannels(), output[chn], channels, decodedSamples, chn); } else { CopyChannelToInterleaved >(sample.pSample8 + offset * sample.GetNumChannels(), output[chn], channels, decodedSamples, chn); } } } offset += decodedSamples; } } } else { unsupportedSamples = true; } } else { AddToLog(LogWarning, mpt::format(MPT_USTRING("Sample %1: Unsupported Ogg Vorbis chained stream found."))(smp)); unsupportedSamples = true; } ov_clear(&vf); } else { unsupportedSamples = true; } #elif defined(MPT_WITH_STBVORBIS) // NOTE/TODO: stb_vorbis does not handle inferred negative PCM sample // position at stream start. (See // ). // This means that, for remuxed and re-aligned/cutted (at stream start) // Vorbis files, stb_vorbis will include superfluous samples at the // beginning. MO3 files with this property are yet to be spotted in the // wild, thus, this behaviour is currently not problematic. int consumed = 0, error = 0; stb_vorbis *vorb = nullptr; if(sharedHeader) { FileReader::PinnedRawDataView headChunkView = headerChunk.GetPinnedRawDataView(initialRead); vorb = stb_vorbis_open_pushdata(headChunkView.data(), mpt::saturate_cast(headChunkView.size()), &consumed, &error, nullptr); headerChunk.Skip(consumed); } FileReader::PinnedRawDataView sampleDataView = sampleData.GetPinnedRawDataView(); const mpt::byte* data = sampleDataView.data(); std::size_t dataLeft = sampleDataView.size(); if(!sharedHeader) { vorb = stb_vorbis_open_pushdata(data, mpt::saturate_cast(dataLeft), &consumed, &error, nullptr); sampleData.Skip(consumed); data += consumed; dataLeft -= consumed; } if(vorb) { // Header has been read, proceed to reading the sample data ModSample &sample = Samples[smp]; sample.AllocateSample(); SmpLength offset = 0; while((error == VORBIS__no_error || (error == VORBIS_need_more_data && dataLeft > 0)) && offset < sample.nLength && sample.pSample != nullptr) { int channels = 0, decodedSamples = 0; float **output; consumed = stb_vorbis_decode_frame_pushdata(vorb, data, mpt::saturate_cast(dataLeft), &channels, &output, &decodedSamples); sampleData.Skip(consumed); data += consumed; dataLeft -= consumed; LimitMax(decodedSamples, mpt::saturate_cast(sample.nLength - offset)); if(decodedSamples > 0 && channels == sample.GetNumChannels()) { for(int chn = 0; chn < channels; chn++) { if(sample.uFlags[CHN_16BIT]) CopyChannelToInterleaved >(sample.pSample16 + offset * sample.GetNumChannels(), output[chn], channels, decodedSamples, chn); else CopyChannelToInterleaved >(sample.pSample8 + offset * sample.GetNumChannels(), output[chn], channels, decodedSamples, chn); } } offset += decodedSamples; error = stb_vorbis_get_error(vorb); } stb_vorbis_close(vorb); } else { unsupportedSamples = true; } #else // !VORBIS unsupportedSamples = true; #endif // VORBIS } } if(m_nType == MOD_TYPE_XM) { // Transfer XM instrument vibrato to samples for(INSTRUMENTINDEX ins = 0; ins < m_nInstruments; ins++) { PropagateXMAutoVibrato(ins + 1, instrVibrato[ins].type, instrVibrato[ins].sweep, instrVibrato[ins].depth, instrVibrato[ins].rate); } } if((fileHeader.flags & MO3FileHeader::hasPlugins) && musicChunk.CanRead(1)) { // Plugin data uint8 pluginFlags = musicChunk.ReadUint8(); if(pluginFlags & 1) { // Channel plugins for(CHANNELINDEX chn = 0; chn < m_nChannels; chn++) { ChnSettings[chn].nMixPlugin = static_cast(musicChunk.ReadUint32LE()); } } while(musicChunk.CanRead(1)) { PLUGINDEX plug = musicChunk.ReadUint8(); if(!plug) break; FileReader pluginChunk = musicChunk.ReadChunk(musicChunk.ReadUint32LE()); #ifndef NO_PLUGINS if(plug <= MAX_MIXPLUGINS) { ReadMixPluginChunk(pluginChunk, m_MixPlugins[plug - 1]); } #endif // NO_PLUGINS } } uint16 cwtv = 0; uint16 cmwt = 0; MPT_UNUSED_VARIABLE(cmwt); while(musicChunk.CanRead(8)) { uint32 id = musicChunk.ReadUint32LE(); uint32 len = musicChunk.ReadUint32LE(); FileReader chunk = musicChunk.ReadChunk(len); switch(id) { case MAGIC4LE('V','E','R','S'): // Tracker magic bytes (depending on format) switch(m_nType) { case MOD_TYPE_IT: cwtv = chunk.ReadUint16LE(); cmwt = chunk.ReadUint16LE(); /*switch(cwtv >> 12) { }*/ break; case MOD_TYPE_S3M: cwtv = chunk.ReadUint16LE(); break; case MOD_TYPE_XM: chunk.ReadString(m_madeWithTracker, mpt::CharsetCP437, std::min(FileReader::off_t(32), chunk.GetLength())); break; case MOD_TYPE_MTM: { uint8 mtmVersion = chunk.ReadUint8(); m_madeWithTracker = mpt::format(MPT_USTRING("MultiTracker %1.%2"))(mtmVersion >> 4, mtmVersion & 0x0F); } break; default: break; } break; case MAGIC4LE('M', 'I', 'D', 'I'): // Full MIDI config chunk.ReadStruct(m_MidiCfg); m_MidiCfg.Sanitize(); break; case MAGIC4LE('O', 'M', 'P', 'T'): // Read pattern names: "PNAM" if(chunk.ReadMagic("PNAM")) { FileReader patterns = chunk.ReadChunk(chunk.ReadUint32LE()); const PATTERNINDEX namedPats = std::min(static_cast(patterns.GetLength() / MAX_PATTERNNAME), Patterns.Size()); for(PATTERNINDEX pat = 0; pat < namedPats; pat++) { char patName[MAX_PATTERNNAME]; patterns.ReadString(patName, MAX_PATTERNNAME); Patterns[pat].SetName(patName); } } // Read channel names: "CNAM" if(chunk.ReadMagic("CNAM")) { FileReader channels = chunk.ReadChunk(chunk.ReadUint32LE()); const CHANNELINDEX namedChans = std::min(static_cast(channels.GetLength() / MAX_CHANNELNAME), GetNumChannels()); for(CHANNELINDEX chn = 0; chn < namedChans; chn++) { channels.ReadString(ChnSettings[chn].szName, MAX_CHANNELNAME); } } LoadExtendedInstrumentProperties(chunk); LoadExtendedSongProperties(chunk); if(cwtv > 0x0889 && cwtv <= 0x8FF) { m_nType = MOD_TYPE_MPT; LoadMPTMProperties(chunk, cwtv); } if(m_dwLastSavedWithVersion) { m_madeWithTracker = MPT_USTRING("OpenMPT ") + MptVersion::ToUString(m_dwLastSavedWithVersion); } break; } } if((GetType() == MOD_TYPE_IT && cwtv >= 0x0100 && cwtv < 0x0214) || (GetType() == MOD_TYPE_S3M && cwtv >= 0x3100 && cwtv < 0x3214) || (GetType() == MOD_TYPE_S3M && cwtv >= 0x1300 && cwtv < 0x1320)) { // Ignore MIDI data in files made with IT older than version 2.14 and old ST3 versions. m_MidiCfg.ClearZxxMacros(); } if(m_madeWithTracker.empty()) m_madeWithTracker = mpt::format(MPT_USTRING("MO3 v%1"))(version); else m_madeWithTracker = mpt::format(MPT_USTRING("MO3 v%1 (%2)"))(version, m_madeWithTracker); if(unsupportedSamples) { AddToLog(LogWarning, MPT_USTRING("Some compressed samples could not be loaded because they use an unsupported codec.")); } return true; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/ContainerPP20.cpp0000644000372100037210000001033513161656666021147 00000000000000/* * ContainerPP20.cpp * ----------------- * Purpose: Handling of PowerPack PP20 compressed modules * Notes : (currently none) * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "../common/FileReader.h" #include "Container.h" #include "Sndfile.h" #include OPENMPT_NAMESPACE_BEGIN //#define MMCMP_LOG struct PPBITBUFFER { uint32 bitcount; uint32 bitbuffer; const uint8 *pStart; const uint8 *pSrc; uint32 GetBits(uint32 n); }; uint32 PPBITBUFFER::GetBits(uint32 n) { uint32 result = 0; for (uint32 i=0; i>= 1; bitcount--; } return result; } static bool PP20_DoUnpack(const uint8 *pSrc, uint32 nSrcLen, uint8 *pDst, uint32 nDstLen) { PPBITBUFFER BitBuffer; uint32 nBytesLeft; BitBuffer.pStart = pSrc; BitBuffer.pSrc = pSrc + nSrcLen - 4; BitBuffer.bitbuffer = 0; BitBuffer.bitcount = 0; BitBuffer.GetBits(pSrc[nSrcLen-1]); nBytesLeft = nDstLen; while (nBytesLeft > 0) { if (!BitBuffer.GetBits(1)) { uint32 n = 1; while (n < nBytesLeft) { uint32 code = BitBuffer.GetBits(2); n += code; if (code != 3) break; } LimitMax(n, nBytesLeft); for (uint32 i=0; i= nSrcLen) return false; uint32 nbits = pSrc[n-1]; uint32 nofs; if (n==4) { nofs = BitBuffer.GetBits( (BitBuffer.GetBits(1)) ? nbits : 7 ); while (n < nBytesLeft) { uint32 code = BitBuffer.GetBits(3); n += code; if (code != 7) break; } } else { nofs = BitBuffer.GetBits(nbits); } LimitMax(n, nBytesLeft); for (uint32 i=0; i<=n; i++) { pDst[nBytesLeft-1] = (nBytesLeft+nofs < nDstLen) ? pDst[nBytesLeft+nofs] : 0; if (!--nBytesLeft) break; } } } return true; } struct PP20header { char magic[4]; // "PP20" uint8be efficiency[4]; }; MPT_BINARY_STRUCT(PP20header, 8) static bool ValidateHeader(const PP20header &hdr) { if(std::memcmp(hdr.magic, "PP20", 4) != 0) { return false; } if(hdr.efficiency[0] < 9 || hdr.efficiency[0] > 15 || hdr.efficiency[1] < 9 || hdr.efficiency[1] > 15 || hdr.efficiency[2] < 9 || hdr.efficiency[2] > 15 || hdr.efficiency[3] < 9 || hdr.efficiency[3] > 15) { return false; } return true; } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderPP20(MemoryFileReader file, const uint64 *pfilesize) { PP20header hdr; if(!file.ReadStruct(hdr)) { return ProbeWantMoreData; } if(!ValidateHeader(hdr)) { return ProbeFailure; } MPT_UNREFERENCED_PARAMETER(pfilesize); return ProbeSuccess; } bool UnpackPP20(std::vector &containerItems, FileReader &file, ContainerLoadingFlags loadFlags) { file.Rewind(); containerItems.clear(); PP20header hdr; if(!file.ReadStruct(hdr)) { return false; } if(!ValidateHeader(hdr)) { return false; } if(loadFlags == ContainerOnlyVerifyHeader) { return true; } if(!file.CanRead(4)) { return false; } containerItems.emplace_back(); containerItems.back().data_cache = mpt::make_unique >(); std::vector & unpackedData = *(containerItems.back().data_cache); FileReader::off_t length = file.GetLength(); if(!Util::TypeCanHoldValue(length)) return false; // Length word must be aligned if((length % 2u) != 0) return false; file.Seek(length - 4); uint32 dstLen = 0; dstLen |= file.ReadUint8() << 16; dstLen |= file.ReadUint8() << 8; dstLen |= file.ReadUint8() << 0; if(dstLen == 0) return false; try { unpackedData.resize(dstLen); } MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e) { MPT_EXCEPTION_DELETE_OUT_OF_MEMORY(e); return false; } file.Seek(4); bool result = PP20_DoUnpack(file.GetRawData(), static_cast(length - 4), mpt::byte_cast(unpackedData.data()), dstLen); if(result) { containerItems.back().file = FileReader(mpt::byte_cast(mpt::as_span(unpackedData))); } return result; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/MixerSettings.h0000644000372100037210000000250612625437350021065 00000000000000/* * MixerSettings.h * --------------- * Purpose: A struct containing settings for the mixer of soundlib. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once OPENMPT_NAMESPACE_BEGIN struct MixerSettings { int32 m_nStereoSeparation; static const int32 StereoSeparationScale = 128; uint32 m_nMaxMixChannels; uint32 DSPMask; uint32 MixerFlags; uint32 gdwMixingFreq; uint32 gnChannels; uint32 m_nPreAmp; int32 VolumeRampUpMicroseconds; int32 VolumeRampDownMicroseconds; int32 GetVolumeRampUpMicroseconds() const { return VolumeRampUpMicroseconds; } int32 GetVolumeRampDownMicroseconds() const { return VolumeRampDownMicroseconds; } void SetVolumeRampUpMicroseconds(int32 rampUpMicroseconds) { VolumeRampUpMicroseconds = rampUpMicroseconds; } void SetVolumeRampDownMicroseconds(int32 rampDownMicroseconds) { VolumeRampDownMicroseconds = rampDownMicroseconds; } int32 GetVolumeRampUpSamples() const; int32 GetVolumeRampDownSamples() const; void SetVolumeRampUpSamples(int32 rampUpSamples); void SetVolumeRampDownSamples(int32 rampDownSamples); bool IsValid() const { return (gdwMixingFreq > 0) && (gnChannels == 1 || gnChannels == 2 || gnChannels == 4); } MixerSettings(); }; OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Load_okt.cpp0000644000372100037210000002467313161656666020371 00000000000000/* * Load_okt.cpp * ------------ * Purpose: OKT (Oktalyzer) module loader * Notes : (currently none) * Authors: Storlek (Original author - http://schismtracker.org/ - code ported with permission) * Johannes Schultz (OpenMPT Port, tweaks) * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" OPENMPT_NAMESPACE_BEGIN struct OktIffChunk { // IFF chunk names enum ChunkIdentifiers { idCMOD = MAGIC4BE('C','M','O','D'), idSAMP = MAGIC4BE('S','A','M','P'), idSPEE = MAGIC4BE('S','P','E','E'), idSLEN = MAGIC4BE('S','L','E','N'), idPLEN = MAGIC4BE('P','L','E','N'), idPATT = MAGIC4BE('P','A','T','T'), idPBOD = MAGIC4BE('P','B','O','D'), idSBOD = MAGIC4BE('S','B','O','D'), }; uint32be signature; // IFF chunk name uint32be chunksize; // chunk size without header }; MPT_BINARY_STRUCT(OktIffChunk, 8) struct OktSample { char name[20]; uint32be length; // length in bytes uint16be loopStart; // *2 for real value uint16be loopLength; // ditto uint16be volume; // default volume uint16be type; // 7-/8-bit sample }; MPT_BINARY_STRUCT(OktSample, 32) // Parse the sample header block static void ReadOKTSamples(FileReader &chunk, std::vector &sample7bit, CSoundFile &sndFile) { sndFile.m_nSamples = std::min(static_cast(chunk.BytesLeft() / sizeof(OktSample)), MAX_SAMPLES - 1u); sample7bit.resize(sndFile.GetNumSamples()); for(SAMPLEINDEX smp = 1; smp <= sndFile.GetNumSamples(); smp++) { ModSample &mptSmp = sndFile.GetSample(smp); OktSample oktSmp; chunk.ReadStruct(oktSmp); oktSmp.length = oktSmp.length; oktSmp.loopStart = oktSmp.loopStart * 2; oktSmp.loopLength = oktSmp.loopLength * 2; oktSmp.volume = oktSmp.volume; oktSmp.type = oktSmp.type; mptSmp.Initialize(); mpt::String::Read(sndFile.m_szNames[smp], oktSmp.name); mptSmp.nC5Speed = 8287; mptSmp.nGlobalVol = 64; mptSmp.nVolume = MIN(oktSmp.volume, 64) * 4; mptSmp.nLength = oktSmp.length & ~1; // round down // parse loops if (oktSmp.loopLength > 2 && static_cast(oktSmp.loopStart) + static_cast(oktSmp.loopLength) <= mptSmp.nLength) { mptSmp.nSustainStart = oktSmp.loopStart; mptSmp.nSustainEnd = oktSmp.loopStart + oktSmp.loopLength; if (mptSmp.nSustainStart < mptSmp.nLength && mptSmp.nSustainEnd <= mptSmp.nLength) mptSmp.uFlags |= CHN_SUSTAINLOOP; else mptSmp.nSustainStart = mptSmp.nSustainEnd = 0; } sample7bit[smp - 1] = (oktSmp.type == 0 || oktSmp.type == 2); } } // Parse a pattern block static void ReadOKTPattern(FileReader &chunk, PATTERNINDEX nPat, CSoundFile &sndFile) { if(!chunk.CanRead(2)) { return; } ROWINDEX rows = Clamp(static_cast(chunk.ReadUint16BE()), ROWINDEX(1), MAX_PATTERN_ROWS); if(!sndFile.Patterns.Insert(nPat, rows)) { return; } const CHANNELINDEX chns = sndFile.GetNumChannels(); for(ROWINDEX row = 0; row < rows; row++) { ModCommand *m = sndFile.Patterns[nPat].GetRow(row); for(CHANNELINDEX chn = 0; chn < chns; chn++, m++) { uint8 note = chunk.ReadUint8(); uint8 instr = chunk.ReadUint8(); uint8 effect = chunk.ReadUint8(); m->param = chunk.ReadUint8(); if(note > 0 && note <= 36) { m->note = note + 48; m->instr = instr + 1; } else { m->instr = 0; } switch(effect) { case 0: // Nothing m->param = 0; break; case 1: // 1 Portamento Down (Period) m->command = CMD_PORTAMENTOUP; m->param &= 0x0F; break; case 2: // 2 Portamento Up (Period) m->command = CMD_PORTAMENTODOWN; m->param &= 0x0F; break; #if 0 /* these aren't like Jxx: "down" means to *subtract* the offset from the note. For now I'm going to leave these unimplemented. */ case 10: // A Arpeggio 1 (down, orig, up) case 11: // B Arpeggio 2 (orig, up, orig, down) if (m->param) m->command = CMD_ARPEGGIO; break; #endif // This one is close enough to "standard" arpeggio -- I think! case 12: // C Arpeggio 3 (up, up, orig) if (m->param) m->command = CMD_ARPEGGIO; break; case 13: // D Slide Down (Notes) if (m->param) { m->command = CMD_NOTESLIDEDOWN; m->param = 0x10 | MIN(0x0F, m->param); } break; case 30: // U Slide Up (Notes) if (m->param) { m->command = CMD_NOTESLIDEUP; m->param = 0x10 | MIN(0x0F, m->param); } break; /* We don't have fine note slide, but this is supposed to happen once per row. Sliding every 5 (non-note) ticks kind of works (at least at speed 6), but implementing fine slides would of course be better. */ case 21: // L Slide Down Once (Notes) if (m->param) { m->command = CMD_NOTESLIDEDOWN; m->param = 0x50 | MIN(0x0F, m->param); } break; case 17: // H Slide Up Once (Notes) if (m->param) { m->command = CMD_NOTESLIDEUP; m->param = 0x50 | MIN(0x0F, m->param); } break; case 15: // F Set Filter <>00:ON // Not implemented, but let's import it anyway... m->command = CMD_MODCMDEX; m->param = !!m->param; break; case 25: // P Pos Jump m->command = CMD_POSITIONJUMP; break; case 27: // R Release sample (apparently not listed in the help!) m->Clear(); m->note = NOTE_KEYOFF; break; case 28: // S Speed m->command = CMD_SPEED; // or tempo? break; case 31: // V Volume m->command = CMD_VOLUMESLIDE; switch (m->param >> 4) { case 4: if (m->param != 0x40) { m->param &= 0x0F; // D0x break; } // 0x40 is set volume -- fall through MPT_FALLTHROUGH; case 0: case 1: case 2: case 3: m->volcmd = VOLCMD_VOLUME; m->vol = m->param; m->command = CMD_NONE; m->param = 0; break; case 5: m->param = (m->param & 0x0F) << 4; // Dx0 break; case 6: m->param = 0xF0 | MIN(m->param & 0x0F, 0x0E); // DFx break; case 7: m->param = (MIN(m->param & 0x0F, 0x0E) << 4) | 0x0F; // DxF break; default: // Junk. m->command = CMD_NONE; m->param = 0; break; } break; #if 0 case 24: // O Old Volume (???) m->command = CMD_VOLUMESLIDE; m->param = 0; break; #endif default: m->command = m->param = 0; break; } } } } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderOKT(MemoryFileReader file, const uint64 *pfilesize) { if(!file.CanRead(8)) { return ProbeWantMoreData; } if(!file.ReadMagic("OKTASONG")) { return ProbeFailure; } OktIffChunk iffHead; if(!file.ReadStruct(iffHead)) { return ProbeWantMoreData; } if(iffHead.chunksize == 0) { return ProbeFailure; } if((iffHead.signature & 0x7f7f7f7fu) != iffHead.signature) // ASCII? { return ProbeFailure; } MPT_UNREFERENCED_PARAMETER(pfilesize); return ProbeSuccess; } bool CSoundFile::ReadOKT(FileReader &file, ModLoadingFlags loadFlags) { file.Rewind(); if(!file.ReadMagic("OKTASONG")) { return false; } // prepare some arrays to store offsets etc. std::vector patternChunks; std::vector sampleChunks; std::vector sample7bit; // 7-/8-bit sample ORDERINDEX numOrders = 0; InitializeGlobals(MOD_TYPE_OKT); // Go through IFF chunks... while(file.CanRead(sizeof(OktIffChunk))) { OktIffChunk iffHead; if(!file.ReadStruct(iffHead)) { break; } FileReader chunk = file.ReadChunk(iffHead.chunksize); if(!chunk.IsValid()) { break; } switch(iffHead.signature) { case OktIffChunk::idCMOD: // Read that weird channel setup table if(m_nChannels > 0 || chunk.GetLength() < 8) { break; } for(CHANNELINDEX chn = 0; chn < 4; chn++) { uint8 ch1 = chunk.ReadUint8(), ch2 = chunk.ReadUint8(); if(ch1 || ch2) { ChnSettings[m_nChannels].Reset(); ChnSettings[m_nChannels++].nPan = (((chn & 3) == 1) || ((chn & 3) == 2)) ? 0xC0 : 0x40; } ChnSettings[m_nChannels].Reset(); ChnSettings[m_nChannels++].nPan = (((chn & 3) == 1) || ((chn & 3) == 2)) ? 0xC0 : 0x40; } if(loadFlags == onlyVerifyHeader) { return true; } break; case OktIffChunk::idSAMP: // Convert sample headers if(m_nSamples > 0) { break; } ReadOKTSamples(chunk, sample7bit, *this); break; case OktIffChunk::idSPEE: // Read default speed if(chunk.GetLength() >= 2) { m_nDefaultSpeed = Clamp(chunk.ReadUint16BE(), uint16(1), uint16(255)); } break; case OktIffChunk::idSLEN: // Number of patterns, we don't need this. break; case OktIffChunk::idPLEN: // Read number of valid orders if(chunk.GetLength() >= 2) { numOrders = chunk.ReadUint16BE(); } break; case OktIffChunk::idPATT: // Read the orderlist ReadOrderFromFile(Order(), chunk, chunk.GetLength(), 0xFF, 0xFE); break; case OktIffChunk::idPBOD: // Don't read patterns for now, as the number of channels might be unknown at this point. if(patternChunks.size() < 256) { patternChunks.push_back(chunk); } break; case OktIffChunk::idSBOD: // Sample data - same as with patterns, as we need to know the sample format / length if(sampleChunks.size() < MAX_SAMPLES - 1 && chunk.GetLength() > 0) { sampleChunks.push_back(chunk); } break; } } // If there wasn't even a CMOD chunk, we can't really load this. if(m_nChannels == 0) return false; m_nDefaultTempo.Set(125); m_nDefaultGlobalVolume = MAX_GLOBAL_VOLUME; m_nSamplePreAmp = m_nVSTiVolume = 48; m_nMinPeriod = 0x71 * 4; m_nMaxPeriod = 0x358 * 4; // Fix orderlist Order().resize(numOrders); // Read patterns if(loadFlags & loadPatternData) { Patterns.ResizeArray(static_cast(patternChunks.size())); for(PATTERNINDEX pat = 0; pat < patternChunks.size(); pat++) { if(patternChunks[pat].GetLength() > 0) ReadOKTPattern(patternChunks[pat], pat, *this); else Patterns.Insert(pat, 64); // Invent empty pattern } } // Read samples size_t fileSmp = 0; for(SAMPLEINDEX smp = 1; smp < m_nSamples; smp++) { if(fileSmp >= sampleChunks.size() || !(loadFlags & loadSampleData)) break; ModSample &mptSample = Samples[smp]; if(mptSample.nLength == 0) continue; // Weird stuff? LimitMax(mptSample.nLength, mpt::saturate_cast(sampleChunks[fileSmp].GetLength())); SampleIO( SampleIO::_8bit, SampleIO::mono, SampleIO::bigEndian, sample7bit[smp - 1] ? SampleIO::PCM7to8 : SampleIO::signedPCM) .ReadSample(mptSample, sampleChunks[fileSmp]); fileSmp++; } return true; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/tuning.h0000644000372100037210000001713013161656666017574 00000000000000/* * tuning.h * -------- * Purpose: Alternative sample tuning. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include #include "tuningbase.h" OPENMPT_NAMESPACE_BEGIN namespace Tuning { class CTuningRTI { public: static const char s_FileExtension[5]; enum { TT_GENERAL = 0, TT_GROUPGEOMETRIC = 1, TT_GEOMETRIC = 3, }; static const RATIOTYPE s_DefaultFallbackRatio; static const NOTEINDEXTYPE s_StepMinDefault = -64; static const UNOTEINDEXTYPE s_RatioTableSizeDefault = 128; static const USTEPINDEXTYPE s_RatioTableFineSizeMaxDefault = 1000; public: //To return ratio of certain note. RATIOTYPE GetRatio(const NOTEINDEXTYPE& stepsFromCentre) const; //To return ratio from a 'step'(noteindex + stepindex) RATIOTYPE GetRatio(const NOTEINDEXTYPE& stepsFromCentre, const STEPINDEXTYPE& fineSteps) const; UNOTEINDEXTYPE GetRatioTableSize() const {return static_cast(m_RatioTable.size());} NOTEINDEXTYPE GetRatioTableBeginNote() const {return m_StepMin;} //Tuning might not be valid for arbitrarily large range, //so this can be used to ask where it is valid. Tells the lowest and highest //note that are valid. VRPAIR GetValidityRange() const {return VRPAIR(m_StepMin, static_cast(m_StepMin + static_cast(m_RatioTable.size()) - 1));} //Return true if note is within validity range - false otherwise. bool IsValidNote(const NOTEINDEXTYPE n) const {return (n >= GetValidityRange().first && n <= GetValidityRange().second);} UNOTEINDEXTYPE GetGroupSize() const {return m_GroupSize;} RATIOTYPE GetGroupRatio() const {return m_GroupRatio;} //To return (fine)stepcount between two consecutive mainsteps. USTEPINDEXTYPE GetFineStepCount() const {return m_FineStepCount;} //To return 'directed distance' between given notes. STEPINDEXTYPE GetStepDistance(const NOTEINDEXTYPE& from, const NOTEINDEXTYPE& to) const {return (to - from)*(static_cast(GetFineStepCount())+1);} //To return 'directed distance' between given steps. STEPINDEXTYPE GetStepDistance(const NOTEINDEXTYPE& noteFrom, const STEPINDEXTYPE& stepDistFrom, const NOTEINDEXTYPE& noteTo, const STEPINDEXTYPE& stepDistTo) const {return GetStepDistance(noteFrom, noteTo) + stepDistTo - stepDistFrom;} //To set finestepcount between two consecutive mainsteps. //Finestep count == 0 means that //stepdistances become the same as note distances. void SetFineStepCount(const USTEPINDEXTYPE& fs); //Multiply all ratios by given number. bool Multiply(const RATIOTYPE&); bool SetRatio(const NOTEINDEXTYPE& s, const RATIOTYPE& r); TUNINGTYPE GetType() const {return m_TuningType;} std::string GetNoteName(const NOTEINDEXTYPE& x, bool addOctave = true) const; void SetNoteName(const NOTEINDEXTYPE&, const std::string&); static CTuningRTI* CreateDeserialize(std::istream & f) { CTuningRTI *pT = new CTuningRTI(); if(pT->InitDeserialize(f) != SerializationResult::Success) { delete pT; return nullptr; } return pT; } //Try to read old version (v.3) and return pointer to new instance if succesfull, else nullptr. static CTuningRTI* CreateDeserializeOLD(std::istream & f) { CTuningRTI *pT = new CTuningRTI(); if(pT->InitDeserializeOLD(f) != SerializationResult::Success) { delete pT; return nullptr; } return pT; } static CTuningRTI* CreateGeneral(const std::string &name) { CTuningRTI *pT = new CTuningRTI(); pT->SetName(name); return pT; } static CTuningRTI* CreateGroupGeometric(const std::string &name, UNOTEINDEXTYPE groupsize, RATIOTYPE groupratio, USTEPINDEXTYPE finestepcount) { CTuningRTI *pT = new CTuningRTI(); pT->SetName(name); if(pT->CreateGroupGeometric(groupsize, groupratio, 0) != false) { delete pT; return nullptr; } pT->SetFineStepCount(finestepcount); return pT; } static CTuningRTI* CreateGroupGeometric(const std::string &name, const std::vector &ratios, RATIOTYPE groupratio, USTEPINDEXTYPE finestepcount) { CTuningRTI *pT = new CTuningRTI(); pT->SetName(name); VRPAIR range = std::make_pair(s_StepMinDefault, static_cast(s_StepMinDefault + s_RatioTableSizeDefault - 1)); range.second = std::max(range.second, mpt::saturate_cast(ratios.size() - 1)); range.first = 0 - range.second - 1; if(pT->CreateGroupGeometric(ratios, groupratio, range, 0) != false) { delete pT; return nullptr; } pT->SetFineStepCount(finestepcount); return pT; } static CTuningRTI* CreateGeometric(const std::string &name, UNOTEINDEXTYPE groupsize, RATIOTYPE groupratio, USTEPINDEXTYPE finestepcount) { CTuningRTI *pT = new CTuningRTI(); pT->SetName(name); if(pT->CreateGeometric(groupsize, groupratio) != false) { delete pT; return nullptr; } pT->SetFineStepCount(finestepcount); return pT; } Tuning::SerializationResult Serialize(std::ostream& out) const; #ifdef MODPLUG_TRACKER bool WriteSCL(std::ostream &f, const mpt::PathString &filename) const; #endif bool ChangeGroupsize(const NOTEINDEXTYPE&); bool ChangeGroupRatio(const RATIOTYPE&); void SetName(const std::string& s) { m_TuningName = s; } std::string GetName() const {return m_TuningName;} private: CTuningRTI(); SerializationResult InitDeserialize(std::istream& inStrm); //Try to read old version (v.3) and return pointer to new instance if succesfull, else nullptr. SerializationResult InitDeserializeOLD(std::istream&); //Create GroupGeometric tuning of *this using virtual ProCreateGroupGeometric. bool CreateGroupGeometric(const std::vector&, const RATIOTYPE&, const VRPAIR vr, const NOTEINDEXTYPE ratiostartpos); //Create GroupGeometric of *this using ratios from 'itself' and ratios starting from //position given as third argument. bool CreateGroupGeometric(const NOTEINDEXTYPE&, const RATIOTYPE&, const NOTEINDEXTYPE&); //Create geometric tuning of *this using ratio(0) = 1. bool CreateGeometric(const UNOTEINDEXTYPE& p, const RATIOTYPE& r) {return CreateGeometric(p,r,GetValidityRange());} bool CreateGeometric(const UNOTEINDEXTYPE&, const RATIOTYPE&, const VRPAIR vr); //The two methods below return false if action was done, true otherwise. bool ProCreateGroupGeometric(const std::vector&, const RATIOTYPE&, const VRPAIR&, const NOTEINDEXTYPE& ratiostartpos); bool ProCreateGeometric(const UNOTEINDEXTYPE&, const RATIOTYPE&, const VRPAIR&); void UpdateFineStepTable(); //Note: Stepdiff should be in range [1, finestepcount] RATIOTYPE GetRatioFine(const NOTEINDEXTYPE& note, USTEPINDEXTYPE stepDiff) const; //GroupPeriodic-specific. //Get the corresponding note in [0, period-1]. //For example GetRefNote(-1) is to return note :'groupsize-1'. NOTEINDEXTYPE GetRefNote(NOTEINDEXTYPE note) const; bool IsNoteInTable(const NOTEINDEXTYPE& s) const { if(s < m_StepMin || s >= m_StepMin + static_cast(m_RatioTable.size())) return false; else return true; } private: TUNINGTYPE m_TuningType; //Noteratios std::vector m_RatioTable; //'Fineratios' std::vector m_RatioTableFine; //The lowest index of note in the table NOTEINDEXTYPE m_StepMin; // this should REALLY be called 'm_NoteMin' renaming was missed in r192 //For groupgeometric tunings, tells the 'group size' and 'group ratio' //m_GroupSize should always be >= 0. NOTEINDEXTYPE m_GroupSize; RATIOTYPE m_GroupRatio; USTEPINDEXTYPE m_FineStepCount; std::string m_TuningName; std::map m_NoteNameMap; }; // class CTuningRTI typedef CTuningRTI CTuning; } // namespace Tuning OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/MPEGFrame.h0000644000372100037210000000124113070446042017747 00000000000000/* * MPEGFrame.h * ----------- * Purpose: Basic MPEG frame parsing functionality * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "../common/FileReaderFwd.h" OPENMPT_NAMESPACE_BEGIN class MPEGFrame { public: uint16 frameSize; // Complete frame size in bytes uint16 numSamples; // Number of samples in this frame (multiplied by number of channels) bool isValid; // Is a valid frame at all bool isLAME; // Has Xing/LAME header MPEGFrame(FileReader &file); static bool IsMPEGHeader(const uint8 (&header)[3]); }; OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Load_dsm.cpp0000644000372100037210000001731313161656666020350 00000000000000/* * Load_dsm.cpp * ------------ * Purpose: Digisound Interface Kit (DSIK) Internal Format (DSM v2 / RIFF) module loader * Notes : 1. There is also another fundamentally different DSIK DSM v1 module format, not handled here. * MilkyTracker can load it, but the only files of this format seen in the wild are also * available in their original format, so I did not bother implementing it so far. * * 2. Using PLAY.EXE v1.02, commands not supported in MOD do not seem to do anything at all. * In particular commands 0x11-0x13 handled below are ignored, and no files have been spotted * in the wild using any commands > 0x0F at all. * S3M-style retrigger does not seem to exist - it is translated to volume slides by CONV.EXE, * and J00 in S3M files is not converted either. * Command 8 (set panning) uses 00-80 for regular panning and A4 for surround, probably * making DSIK one of the first applications to use this particular encoding scheme still * used in "extended" S3Ms today. * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" OPENMPT_NAMESPACE_BEGIN struct DSMChunk { char magic[4]; uint32le size; }; MPT_BINARY_STRUCT(DSMChunk, 8) struct DSMSongHeader { char songName[28]; char reserved1[2]; uint16le flags; char reserved2[4]; uint16le numOrders; uint16le numSamples; uint16le numPatterns; uint16le numChannels; uint8le globalVol; uint8le mastervol; uint8le speed; uint8le bpm; uint8le panPos[16]; uint8le orders[128]; }; MPT_BINARY_STRUCT(DSMSongHeader, 192) struct DSMSampleHeader { char filename[13]; uint8le flags; char reserved1; uint8le volume; uint32le length; uint32le loopStart; uint32le loopEnd; char reserved2[4]; uint32le sampleRate; char sampleName[28]; // Convert a DSM sample header to OpenMPT's internal sample header. void ConvertToMPT(ModSample &mptSmp) const { mptSmp.Initialize(); mpt::String::Read(mptSmp.filename, filename); mptSmp.nC5Speed = sampleRate; mptSmp.uFlags.set(CHN_LOOP, (flags & 1) != 0); mptSmp.nLength = length; mptSmp.nLoopStart = loopStart; mptSmp.nLoopEnd = loopEnd; mptSmp.nVolume = std::min(volume, 64) * 4; } // Retrieve the internal sample format flags for this sample. SampleIO GetSampleFormat() const { SampleIO sampleIO( SampleIO::_8bit, SampleIO::mono, SampleIO::littleEndian, SampleIO::unsignedPCM); if(flags & 0x40) sampleIO |= SampleIO::deltaPCM; // fairlight.dsm by Comrade J else if(flags & 0x02) sampleIO |= SampleIO::signedPCM; return sampleIO; } }; MPT_BINARY_STRUCT(DSMSampleHeader, 64) struct DSMHeader { char fileMagic0[4]; char fileMagic1[4]; char fileMagic2[4]; }; MPT_BINARY_STRUCT(DSMHeader, 12) static bool ValidateHeader(const DSMHeader &fileHeader) { if(!std::memcmp(fileHeader.fileMagic0, "RIFF", 4) && !std::memcmp(fileHeader.fileMagic2, "DSMF", 4)) { // "Normal" DSM files with RIFF header // return true; } else if(!std::memcmp(fileHeader.fileMagic0, "DSMF", 4)) { // DSM files with alternative header // <4 bytes, usually 4x NUL or RIFF> <4 bytes, usually DSMF but not always> return true; } else { return false; } } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderDSM(MemoryFileReader file, const uint64 *pfilesize) { DSMHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return ProbeWantMoreData; } if(!ValidateHeader(fileHeader)) { return ProbeFailure; } if(std::memcmp(fileHeader.fileMagic0, "DSMF", 4) == 0) { if(!file.Skip(4)) { return ProbeWantMoreData; } } DSMChunk chunkHeader; if(!file.ReadStruct(chunkHeader)) { return ProbeWantMoreData; } if(std::memcmp(chunkHeader.magic, "SONG", 4)) { return ProbeFailure; } MPT_UNREFERENCED_PARAMETER(pfilesize); return ProbeSuccess; } bool CSoundFile::ReadDSM(FileReader &file, ModLoadingFlags loadFlags) { file.Rewind(); DSMHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return false; } if(!ValidateHeader(fileHeader)) { return false; } if(std::memcmp(fileHeader.fileMagic0, "DSMF", 4) == 0) { file.Skip(4); } DSMChunk chunkHeader; if(!file.ReadStruct(chunkHeader)) { return false; } // Technically, the song chunk could be anywhere in the file, but we're going to simplify // things by not using a chunk header here and just expect it to be right at the beginning. if(std::memcmp(chunkHeader.magic, "SONG", 4)) { return false; } if(loadFlags == onlyVerifyHeader) { return true; } DSMSongHeader songHeader; file.ReadStructPartial(songHeader, chunkHeader.size); InitializeGlobals(MOD_TYPE_DSM); mpt::String::Read(m_songName, songHeader.songName); m_nChannels = Clamp(songHeader.numChannels, 1, 16); m_nDefaultSpeed = songHeader.speed; m_nDefaultTempo.Set(songHeader.bpm); m_nDefaultGlobalVolume = std::min(songHeader.globalVol, 64) * 4u; if(!m_nDefaultGlobalVolume) m_nDefaultGlobalVolume = MAX_GLOBAL_VOLUME; if(songHeader.mastervol == 0x80) { m_nSamplePreAmp = std::min(256u / m_nChannels, 128u); } else { m_nSamplePreAmp = songHeader.mastervol & 0x7F; } // Read channel panning for(CHANNELINDEX chn = 0; chn < 16; chn++) { ChnSettings[chn].Reset(); if(songHeader.panPos[chn] <= 0x80) { ChnSettings[chn].nPan = songHeader.panPos[chn] * 2; } } ReadOrderFromArray(Order(), songHeader.orders, songHeader.numOrders, 0xFF, 0xFE); // Read pattern and sample chunks PATTERNINDEX patNum = 0; while(file.ReadStruct(chunkHeader)) { FileReader chunk = file.ReadChunk(chunkHeader.size); if(!memcmp(chunkHeader.magic, "PATT", 4) && (loadFlags & loadPatternData)) { // Read pattern if(!Patterns.Insert(patNum, 64)) { continue; } chunk.Skip(2); ROWINDEX row = 0; PatternRow rowBase = Patterns[patNum].GetRow(0); while(chunk.CanRead(1) && row < 64) { uint8 flag = chunk.ReadUint8(); if(!flag) { row++; rowBase = Patterns[patNum].GetRow(row); continue; } CHANNELINDEX chn = (flag & 0x0F); ModCommand dummy = ModCommand(); ModCommand &m = (chn < GetNumChannels() ? rowBase[chn] : dummy); if(flag & 0x80) { uint8 note = chunk.ReadUint8(); if(note) { if(note <= 12 * 9) note += 11 + NOTE_MIN; m.note = note; } } if(flag & 0x40) { m.instr = chunk.ReadUint8(); } if (flag & 0x20) { m.volcmd = VOLCMD_VOLUME; m.vol = std::min(chunk.ReadUint8(), uint8(64)); } if(flag & 0x10) { uint8 command = chunk.ReadUint8(); uint8 param = chunk.ReadUint8(); switch(command) { // Portamentos case 0x11: case 0x12: command &= 0x0F; break; // 3D Sound (?) case 0x13: command = 'X' - 55; param = 0x91; break; default: // Volume + Offset (?) if(command > 0x10) command = ((command & 0xF0) == 0x20) ? 0x09 : 0xFF; } m.command = command; m.param = param; ConvertModCommand(m); } } patNum++; } else if(!memcmp(chunkHeader.magic, "INST", 4) && GetNumSamples() < SAMPLEINDEX(MAX_SAMPLES - 1)) { // Read sample m_nSamples++; ModSample &sample = Samples[m_nSamples]; DSMSampleHeader sampleHeader; chunk.ReadStruct(sampleHeader); sampleHeader.ConvertToMPT(sample); mpt::String::Read(m_szNames[m_nSamples], sampleHeader.sampleName); if(loadFlags & loadSampleData) { sampleHeader.GetSampleFormat().ReadSample(sample, chunk); } } } return true; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/InstrumentExtensions.cpp0000644000372100037210000007372113164732040023043 00000000000000/* * InstrumentExtensions.cpp * ------------------------ * Purpose: Instrument properties I/O * Notes : Welcome to the absolutely horrible abominations that are the "extended instrument properties" * which are some of the earliest additions OpenMPT did to the IT / XM format. They are ugly, * and the way they work even differs between IT/XM and ITI/XI/ITP. * Yes, the world would be a better place without this stuff. * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" OPENMPT_NAMESPACE_BEGIN /*--------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------- MODULAR (in/out) ModInstrument : ----------------------------------------------------------------------------------------------- * to update: ------------ - both following functions need to be updated when adding a new member in ModInstrument : void WriteInstrumentHeaderStructOrField(ModInstrument * input, FILE * file, uint32 only_this_code, int16 fixedsize); bool ReadInstrumentHeaderField(ModInstrument * input, uint32 fcode, int16 fsize, FileReader &file); - see below for body declaration. * members: ---------- - 32bit identification CODE tag (must be unique) - 16bit content SIZE in byte(s) - member field * CODE tag naming convention: ----------------------------- - have a look below in current tag dictionnary - take the initial ones of the field name - 4 caracters code (not more, not less) - must be filled with '.' caracters if code has less than 4 caracters - for arrays, must include a '[' caracter following significant caracters ('.' not significant!!!) - use only caracters used in full member name, ordered as they appear in it - match caracter attribute (small,capital) Example with "PanEnv.nLoopEnd" , "PitchEnv.nLoopEnd" & "VolEnv.Values[MAX_ENVPOINTS]" members : - use 'PLE.' for PanEnv.nLoopEnd - use 'PiLE' for PitchEnv.nLoopEnd - use 'VE[.' for VolEnv.Values[MAX_ENVPOINTS] * In use CODE tag dictionary (alphabetical order): -------------------------------------------------- !!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!! SECTION TO BE UPDATED !!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!! [EXT] means external (not related) to ModInstrument content AUTH [EXT] Song artist C... [EXT] nChannels ChnS [EXT] IT/MPTM: Channel settings for channels 65-127 if needed (doesn't fit to IT header). CS.. nCutSwing CUES [EXT] Sample cue points CWV. [EXT] dwCreatedWithVersion DCT. nDCT; dF.. dwFlags; DGV. [EXT] nDefaultGlobalVolume DT.. [EXT] nDefaultTempo; DTFR [EXT] Fractional part of default tempo DNA. nDNA; EBIH [EXT] embeded instrument header tag (ITP file format) FM.. nFilterMode; fn[. filename[12]; FO.. nFadeOut; GV.. nGlobalVol; IFC. nIFC; IFR. nIFR; K[. Keyboard[128]; LSWV [EXT] Last Saved With Version MB.. wMidiBank; MC.. nMidiChannel; MDK. nMidiDrumKey; MIMA [EXT] MIdi MApping directives MiP. nMixPlug; MP.. nMidiProgram; MPTS [EXT] Extra song info tag MPTX [EXT] EXTRA INFO tag MSF. [EXT] Mod(Specific)Flags n[.. name[32]; NNA. nNNA; NM[. NoteMap[128]; P... nPan; PE.. PanEnv.nNodes; PE[. PanEnv.Values[MAX_ENVPOINTS]; PiE. PitchEnv.nNodes; PiE[ PitchEnv.Values[MAX_ENVPOINTS]; PiLE PitchEnv.nLoopEnd; PiLS PitchEnv.nLoopStart; PiP[ PitchEnv.Ticks[MAX_ENVPOINTS]; PiSB PitchEnv.nSustainStart; PiSE PitchEnv.nSustainEnd; PLE. PanEnv.nLoopEnd; PLS. PanEnv.nLoopStart; PMM. [EXT] nPlugMixMode; PP[. PanEnv.Ticks[MAX_ENVPOINTS]; PPC. nPPC; PPS. nPPS; PS.. nPanSwing; PSB. PanEnv.nSustainStart; PSE. PanEnv.nSustainEnd; PTTL pitchToTempoLock; PTTF pitchToTempoLock (fractional part); PVEH nPluginVelocityHandling; PVOH nPluginVolumeHandling; R... nResampling; RP.. [EXT] nRestartPos; RPB. [EXT] nRowsPerBeat; RPM. [EXT] nRowsPerMeasure; RS.. nResSwing; RSMP [EXT] Global resampling SEP@ [EXT] chunk SEPARATOR tag SPA. [EXT] m_nSamplePreAmp; TM.. [EXT] nTempoMode; VE.. VolEnv.nNodes; VE[. VolEnv.Values[MAX_ENVPOINTS]; VLE. VolEnv.nLoopEnd; VLS. VolEnv.nLoopStart; VP[. VolEnv.Ticks[MAX_ENVPOINTS]; VR.. nVolRampUp; VS.. nVolSwing; VSB. VolEnv.nSustainStart; VSE. VolEnv.nSustainEnd; VSTV [EXT] nVSTiVolume; PERN PitchEnv.nReleaseNode AERN PanEnv.nReleaseNode VERN VolEnv.nReleaseNode PFLG PitchEnv.dwFlag AFLG PanEnv.dwFlags VFLG VolEnv.dwFlags MPWD MIDI Pitch Wheel Depth ----------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------*/ #ifndef MODPLUG_NO_FILESAVE template struct IsNegativeFunctor { bool operator()(T val) const { return val < 0; } }; template struct IsNegativeFunctor { bool operator()(T val) const { return val < 0; } }; template struct IsNegativeFunctor { bool operator()(T /*val*/) const { return false; } }; template bool IsNegative(const T &val) { return IsNegativeFunctor::is_signed>()(val); } // ------------------------------------------------------------------------------------------ // Convenient macro to help WRITE_HEADER declaration for single type members ONLY (non-array) // ------------------------------------------------------------------------------------------ #define WRITE_MPTHEADER_sized_member(name,type,code) \ static_assert(sizeof(input->name) == sizeof(type), "Instrument property does match specified type!");\ fcode = code;\ fsize = sizeof( type );\ if(writeAll) \ { \ mpt::IO::WriteIntLE(file, fcode); \ mpt::IO::WriteIntLE(file, fsize); \ } else if(only_this_code == fcode)\ { \ MPT_ASSERT(fixedsize == fsize); \ } \ if(only_this_code == fcode || only_this_code == Util::MaxValueOfType(only_this_code)) \ { \ type tmp = input-> name; \ tmp = SwapBytesLE(tmp); \ fwrite(&tmp , 1 , fsize , file); \ } \ /**/ // ----------------------------------------------------------------------------------------------------- // Convenient macro to help WRITE_HEADER declaration for single type members which are written truncated // ----------------------------------------------------------------------------------------------------- #define WRITE_MPTHEADER_trunc_member(name,type,code) \ static_assert(sizeof(input->name) > sizeof(type), "Instrument property would not be truncated, use WRITE_MPTHEADER_sized_member instead!");\ fcode = code;\ fsize = sizeof( type );\ if(writeAll) \ { \ mpt::IO::WriteIntLE(file, fcode); \ mpt::IO::WriteIntLE(file, fsize); \ type tmp = (type)(input-> name ); \ tmp = SwapBytesLE(tmp); \ fwrite(&tmp , 1 , fsize , file); \ } else if(only_this_code == fcode)\ { \ /* hackish workaround to resolve mismatched size values: */ \ /* nResampling was a long time declared as uint32 but these macro tables used uint16 and UINT. */ \ /* This worked fine on little-endian, on big-endian not so much. Thus support writing size-mismatched fields. */ \ MPT_ASSERT(fixedsize >= fsize); \ type tmp = (type)(input-> name ); \ tmp = SwapBytesLE(tmp); \ fwrite(&tmp , 1 , fsize , file); \ if(fixedsize > fsize) \ { \ for(int16 i = 0; i < fixedsize - fsize; ++i) \ { \ uint8 fillbyte = !IsNegative(tmp) ? 0 : 0xff; /* sign extend */ \ fwrite(&fillbyte, 1, 1, file); \ } \ } \ } \ /**/ // ------------------------------------------------------------------------ // Convenient macro to help WRITE_HEADER declaration for array members ONLY // ------------------------------------------------------------------------ #define WRITE_MPTHEADER_array_member(name,type,code,arraysize) \ STATIC_ASSERT(sizeof(type) == sizeof(input-> name [0])); \ MPT_ASSERT(sizeof(input->name) >= sizeof(type) * arraysize);\ fcode = code;\ fsize = sizeof( type ) * arraysize;\ if(writeAll) \ { \ mpt::IO::WriteIntLE(file, fcode); \ mpt::IO::WriteIntLE(file, fsize); \ } else if(only_this_code == fcode)\ { \ /* MPT_ASSERT(fixedsize <= fsize); */ \ fsize = fixedsize; /* just trust the size we got passed */ \ } \ if(only_this_code == fcode || only_this_code == Util::MaxValueOfType(only_this_code)) \ { \ for(std::size_t i = 0; i < fsize/sizeof(type); ++i) \ { \ type tmp; \ tmp = input-> name [i]; \ tmp = SwapBytesLE(tmp); \ fwrite(&tmp, 1, sizeof(type), file); \ } \ } \ /**/ // ------------------------------------------------------------------------ // Convenient macro to help WRITE_HEADER declaration for envelope members ONLY // ------------------------------------------------------------------------ #define WRITE_MPTHEADER_envelope_member(envType,envField,type,code) \ {\ const InstrumentEnvelope &env = input->GetEnvelope(envType); \ STATIC_ASSERT(sizeof(type) == sizeof(env[0]. envField)); \ fcode = code;\ fsize = mpt::saturate_cast(sizeof( type ) * env.size());\ MPT_ASSERT(size_t(fsize) == sizeof( type ) * env.size()); \ \ if(writeAll) \ { \ mpt::IO::WriteIntLE(file, fcode); \ mpt::IO::WriteIntLE(file, fsize); \ } else if(only_this_code == fcode)\ { \ fsize = fixedsize; /* just trust the size we got passed */ \ } \ if(only_this_code == fcode || only_this_code == Util::MaxValueOfType(only_this_code)) \ { \ uint32 maxNodes = std::min(fsize/sizeof(type), env.size()); \ for(uint32 i = 0; i < maxNodes; ++i) \ { \ type tmp; \ tmp = env[i]. envField; \ tmp = SwapBytesLE(tmp); \ fwrite(&tmp, 1, sizeof(type), file); \ } \ /* Not every instrument's envelope will be the same length. fill up with zeros. */ \ for(uint32 i = maxNodes; i < fsize/sizeof(type); ++i) \ { \ type tmp = 0; \ tmp = SwapBytesLE(tmp); \ fwrite(&tmp, 1, sizeof(type), file); \ } \ } \ }\ /**/ // Write (in 'file') 'input' ModInstrument with 'code' & 'size' extra field infos for each member void WriteInstrumentHeaderStructOrField(ModInstrument * input, FILE * file, uint32 only_this_code, uint16 fixedsize) { uint32 fcode; uint16 fsize; // If true, all extension are written to the file; otherwise only the specified extension is written. // writeAll is true iff we are saving an instrument (or, hypothetically, the legacy ITP format) const bool writeAll = only_this_code == Util::MaxValueOfType(only_this_code); if(!writeAll) { MPT_ASSERT(fixedsize > 0); } WRITE_MPTHEADER_sized_member( nFadeOut , uint32 , MAGIC4BE('F','O','.','.') ) WRITE_MPTHEADER_sized_member( nPan , uint32 , MAGIC4BE('P','.','.','.') ) WRITE_MPTHEADER_sized_member( VolEnv.size() , uint32 , MAGIC4BE('V','E','.','.') ) WRITE_MPTHEADER_sized_member( PanEnv.size() , uint32 , MAGIC4BE('P','E','.','.') ) WRITE_MPTHEADER_sized_member( PitchEnv.size() , uint32 , MAGIC4BE('P','i','E','.') ) WRITE_MPTHEADER_sized_member( wMidiBank , uint16 , MAGIC4BE('M','B','.','.') ) WRITE_MPTHEADER_sized_member( nMidiProgram , uint8 , MAGIC4BE('M','P','.','.') ) WRITE_MPTHEADER_sized_member( nMidiChannel , uint8 , MAGIC4BE('M','C','.','.') ) WRITE_MPTHEADER_envelope_member( ENV_VOLUME , tick , uint16 , MAGIC4BE('V','P','[','.') ) WRITE_MPTHEADER_envelope_member( ENV_PANNING , tick , uint16 , MAGIC4BE('P','P','[','.') ) WRITE_MPTHEADER_envelope_member( ENV_PITCH , tick , uint16 , MAGIC4BE('P','i','P','[') ) WRITE_MPTHEADER_envelope_member( ENV_VOLUME , value , uint8 , MAGIC4BE('V','E','[','.') ) WRITE_MPTHEADER_envelope_member( ENV_PANNING , value , uint8 , MAGIC4BE('P','E','[','.') ) WRITE_MPTHEADER_envelope_member( ENV_PITCH , value , uint8 , MAGIC4BE('P','i','E','[') ) WRITE_MPTHEADER_sized_member( nMixPlug , uint8 , MAGIC4BE('M','i','P','.') ) WRITE_MPTHEADER_sized_member( nVolRampUp , uint16 , MAGIC4BE('V','R','.','.') ) WRITE_MPTHEADER_trunc_member( nResampling , uint16 , MAGIC4BE('R','.','.','.') ) WRITE_MPTHEADER_sized_member( nCutSwing , uint8 , MAGIC4BE('C','S','.','.') ) WRITE_MPTHEADER_sized_member( nResSwing , uint8 , MAGIC4BE('R','S','.','.') ) WRITE_MPTHEADER_sized_member( nFilterMode , uint8 , MAGIC4BE('F','M','.','.') ) WRITE_MPTHEADER_sized_member( nPluginVelocityHandling , uint8 , MAGIC4BE('P','V','E','H') ) WRITE_MPTHEADER_sized_member( nPluginVolumeHandling , uint8 , MAGIC4BE('P','V','O','H') ) WRITE_MPTHEADER_trunc_member( pitchToTempoLock.GetInt() , uint16 , MAGIC4BE('P','T','T','L') ) WRITE_MPTHEADER_trunc_member( pitchToTempoLock.GetFract() , uint16 , MAGIC4LE('P','T','T','F') ) WRITE_MPTHEADER_sized_member( PitchEnv.nReleaseNode , uint8 , MAGIC4BE('P','E','R','N') ) WRITE_MPTHEADER_sized_member( PanEnv.nReleaseNode , uint8 , MAGIC4BE('A','E','R','N') ) WRITE_MPTHEADER_sized_member( VolEnv.nReleaseNode , uint8 , MAGIC4BE('V','E','R','N') ) WRITE_MPTHEADER_sized_member( PitchEnv.dwFlags , uint32 , MAGIC4BE('P','F','L','G') ) WRITE_MPTHEADER_sized_member( PanEnv.dwFlags , uint32 , MAGIC4BE('A','F','L','G') ) WRITE_MPTHEADER_sized_member( VolEnv.dwFlags , uint32 , MAGIC4BE('V','F','L','G') ) WRITE_MPTHEADER_sized_member( midiPWD , int8 , MAGIC4BE('M','P','W','D') ) } // Used only when saving IT, XM and MPTM. // ITI, ITP saves using Ericus' macros etc... // The reason is that ITs and XMs save [code][size][ins1.Value][ins2.Value]... // whereas ITP saves [code][size][ins1.Value][code][size][ins2.Value]... // too late to turn back.... void CSoundFile::SaveExtendedInstrumentProperties(INSTRUMENTINDEX nInstruments, FILE *f) const { uint32 code = MAGIC4BE('M','P','T','X'); // write extension header code mpt::IO::WriteIntLE(f, code); if (nInstruments == 0) return; WriteInstrumentPropertyForAllInstruments(MAGIC4BE('V','R','.','.'), sizeof(ModInstrument().nVolRampUp), f, nInstruments); WriteInstrumentPropertyForAllInstruments(MAGIC4BE('M','i','P','.'), sizeof(ModInstrument().nMixPlug), f, nInstruments); WriteInstrumentPropertyForAllInstruments(MAGIC4BE('M','C','.','.'), sizeof(ModInstrument().nMidiChannel),f, nInstruments); WriteInstrumentPropertyForAllInstruments(MAGIC4BE('M','P','.','.'), sizeof(ModInstrument().nMidiProgram),f, nInstruments); WriteInstrumentPropertyForAllInstruments(MAGIC4BE('M','B','.','.'), sizeof(ModInstrument().wMidiBank), f, nInstruments); WriteInstrumentPropertyForAllInstruments(MAGIC4BE('P','.','.','.'), sizeof(ModInstrument().nPan), f, nInstruments); WriteInstrumentPropertyForAllInstruments(MAGIC4BE('F','O','.','.'), sizeof(ModInstrument().nFadeOut), f, nInstruments); WriteInstrumentPropertyForAllInstruments(MAGIC4BE('R','.','.','.'), sizeof(ModInstrument().nResampling), f, nInstruments); WriteInstrumentPropertyForAllInstruments(MAGIC4BE('C','S','.','.'), sizeof(ModInstrument().nCutSwing), f, nInstruments); WriteInstrumentPropertyForAllInstruments(MAGIC4BE('R','S','.','.'), sizeof(ModInstrument().nResSwing), f, nInstruments); WriteInstrumentPropertyForAllInstruments(MAGIC4BE('F','M','.','.'), sizeof(ModInstrument().nFilterMode), f, nInstruments); WriteInstrumentPropertyForAllInstruments(MAGIC4BE('P','E','R','N'), sizeof(ModInstrument().PitchEnv.nReleaseNode ), f, nInstruments); WriteInstrumentPropertyForAllInstruments(MAGIC4BE('A','E','R','N'), sizeof(ModInstrument().PanEnv.nReleaseNode), f, nInstruments); WriteInstrumentPropertyForAllInstruments(MAGIC4BE('V','E','R','N'), sizeof(ModInstrument().VolEnv.nReleaseNode), f, nInstruments); WriteInstrumentPropertyForAllInstruments(MAGIC4BE('P','T','T','L'), sizeof(uint16), f, nInstruments); WriteInstrumentPropertyForAllInstruments(MAGIC4LE('P','T','T','F'), sizeof(uint16), f, nInstruments); WriteInstrumentPropertyForAllInstruments(MAGIC4BE('P','V','E','H'), sizeof(ModInstrument().nPluginVelocityHandling), f, nInstruments); WriteInstrumentPropertyForAllInstruments(MAGIC4BE('P','V','O','H'), sizeof(ModInstrument().nPluginVolumeHandling), f, nInstruments); if(!(GetType() & MOD_TYPE_XM)) { // XM instrument headers already have support for this WriteInstrumentPropertyForAllInstruments(MAGIC4BE('M','P','W','D'), sizeof(ModInstrument().midiPWD), f, nInstruments); } if(GetType() & MOD_TYPE_MPT) { uint32 maxNodes[3] = { 0 }; for(INSTRUMENTINDEX i = 1; i <= m_nInstruments; i++) if(Instruments[i] != nullptr) { maxNodes[0] = std::max(maxNodes[0], Instruments[i]->VolEnv.size()); maxNodes[1] = std::max(maxNodes[1], Instruments[i]->PanEnv.size()); maxNodes[2] = std::max(maxNodes[2], Instruments[i]->PitchEnv.size()); } // write full envelope information for MPTM files (more env points) if(maxNodes[0] > 25) { WriteInstrumentPropertyForAllInstruments(MAGIC4BE('V','E','.','.'), sizeof(ModInstrument().VolEnv.size()), f, nInstruments); WriteInstrumentPropertyForAllInstruments(MAGIC4BE('V','P','[','.'), static_cast(maxNodes[0] * sizeof(EnvelopeNode().tick)), f, nInstruments); WriteInstrumentPropertyForAllInstruments(MAGIC4BE('V','E','[','.'), static_cast(maxNodes[0] * sizeof(EnvelopeNode().value)), f, nInstruments); } if(maxNodes[1] > 25) { WriteInstrumentPropertyForAllInstruments(MAGIC4BE('P','E','.','.'), sizeof(ModInstrument().PanEnv.size()), f, nInstruments); WriteInstrumentPropertyForAllInstruments(MAGIC4BE('P','P','[','.'), static_cast(maxNodes[1] * sizeof(EnvelopeNode().tick)), f, nInstruments); WriteInstrumentPropertyForAllInstruments(MAGIC4BE('P','E','[','.'), static_cast(maxNodes[1] * sizeof(EnvelopeNode().value)), f, nInstruments); } if(maxNodes[2] > 25) { WriteInstrumentPropertyForAllInstruments(MAGIC4BE('P','i','E','.'), sizeof(ModInstrument().PitchEnv.size()), f, nInstruments); WriteInstrumentPropertyForAllInstruments(MAGIC4BE('P','i','P','['), static_cast(maxNodes[2] * sizeof(EnvelopeNode().tick)), f, nInstruments); WriteInstrumentPropertyForAllInstruments(MAGIC4BE('P','i','E','['), static_cast(maxNodes[2] * sizeof(EnvelopeNode().value)), f, nInstruments); } } } void CSoundFile::WriteInstrumentPropertyForAllInstruments(uint32 code, uint16 size, FILE *f, INSTRUMENTINDEX nInstruments) const { mpt::IO::WriteIntLE(f, code); //write code mpt::IO::WriteIntLE(f, size); //write size for(INSTRUMENTINDEX i = 1; i <= nInstruments; i++) //for all instruments... { if (Instruments[i]) { WriteInstrumentHeaderStructOrField(Instruments[i], f, code, size); } else { ModInstrument emptyInstrument; WriteInstrumentHeaderStructOrField(&emptyInstrument, f, code, size); } } } #endif // !MODPLUG_NO_FILESAVE // -------------------------------------------------------------------------------------------- // Convenient macro to help GET_HEADER declaration for single type members ONLY (non-array) // -------------------------------------------------------------------------------------------- #define GET_MPTHEADER_sized_member(name,type,code) \ case code: \ {\ if( fsize <= sizeof( type ) ) \ { \ /* hackish workaround to resolve mismatched size values: */ \ /* nResampling was a long time declared as uint32 but these macro tables used uint16 and UINT. */ \ /* This worked fine on little-endian, on big-endian not so much. Thus support reading size-mismatched fields. */ \ if(file.CanRead(fsize)) \ { \ type tmp; \ tmp = file.ReadTruncatedIntLE(fsize); \ STATIC_ASSERT(sizeof(tmp) == sizeof(input-> name )); \ memcpy(&(input-> name ), &tmp, sizeof(type)); \ result = true; \ } \ } \ } break; // -------------------------------------------------------------------------------------------- // Convenient macro to help GET_HEADER declaration for array members ONLY // -------------------------------------------------------------------------------------------- #define GET_MPTHEADER_array_member(name,type,code) \ case code: \ {\ if( fsize <= sizeof( type ) * CountOf(input-> name) ) \ { \ FileReader arrayChunk = file.ReadChunk(fsize); \ for(std::size_t i = 0; i < CountOf(input-> name); ++i) \ { \ input-> name [i] = arrayChunk.ReadIntLE(); \ } \ result = true; \ } \ } break; // -------------------------------------------------------------------------------------------- // Convenient macro to help GET_HEADER declaration for envelope tick/value members // -------------------------------------------------------------------------------------------- #define GET_MPTHEADER_envelope_member(envType,envField,type,code) \ case code: \ {\ FileReader arrayChunk = file.ReadChunk(fsize); \ InstrumentEnvelope &env = input->GetEnvelope(envType); \ for(uint32 i = 0; i < env.size(); i++) \ { \ env[i]. envField = arrayChunk.ReadIntLE(); \ } \ result = true; \ } break; // Return a pointer on the wanted field in 'input' ModInstrument given field code & size bool ReadInstrumentHeaderField(ModInstrument *input, uint32 fcode, uint16 fsize, FileReader &file) { if(input == nullptr) return false; bool result = false; // Members which can be found in this table but not in the write table are only required in the legacy ITP format. switch(fcode) { GET_MPTHEADER_sized_member( nFadeOut , uint32 , MAGIC4BE('F','O','.','.') ) GET_MPTHEADER_sized_member( dwFlags , uint32 , MAGIC4BE('d','F','.','.') ) GET_MPTHEADER_sized_member( nGlobalVol , uint32 , MAGIC4BE('G','V','.','.') ) GET_MPTHEADER_sized_member( nPan , uint32 , MAGIC4BE('P','.','.','.') ) GET_MPTHEADER_sized_member( VolEnv.nLoopStart , uint8 , MAGIC4BE('V','L','S','.') ) GET_MPTHEADER_sized_member( VolEnv.nLoopEnd , uint8 , MAGIC4BE('V','L','E','.') ) GET_MPTHEADER_sized_member( VolEnv.nSustainStart , uint8 , MAGIC4BE('V','S','B','.') ) GET_MPTHEADER_sized_member( VolEnv.nSustainEnd , uint8 , MAGIC4BE('V','S','E','.') ) GET_MPTHEADER_sized_member( PanEnv.nLoopStart , uint8 , MAGIC4BE('P','L','S','.') ) GET_MPTHEADER_sized_member( PanEnv.nLoopEnd , uint8 , MAGIC4BE('P','L','E','.') ) GET_MPTHEADER_sized_member( PanEnv.nSustainStart , uint8 , MAGIC4BE('P','S','B','.') ) GET_MPTHEADER_sized_member( PanEnv.nSustainEnd , uint8 , MAGIC4BE('P','S','E','.') ) GET_MPTHEADER_sized_member( PitchEnv.nLoopStart , uint8 , MAGIC4BE('P','i','L','S') ) GET_MPTHEADER_sized_member( PitchEnv.nLoopEnd , uint8 , MAGIC4BE('P','i','L','E') ) GET_MPTHEADER_sized_member( PitchEnv.nSustainStart , uint8 , MAGIC4BE('P','i','S','B') ) GET_MPTHEADER_sized_member( PitchEnv.nSustainEnd , uint8 , MAGIC4BE('P','i','S','E') ) GET_MPTHEADER_sized_member( nNNA , uint8 , MAGIC4BE('N','N','A','.') ) GET_MPTHEADER_sized_member( nDCT , uint8 , MAGIC4BE('D','C','T','.') ) GET_MPTHEADER_sized_member( nDNA , uint8 , MAGIC4BE('D','N','A','.') ) GET_MPTHEADER_sized_member( nPanSwing , uint8 , MAGIC4BE('P','S','.','.') ) GET_MPTHEADER_sized_member( nVolSwing , uint8 , MAGIC4BE('V','S','.','.') ) GET_MPTHEADER_sized_member( nIFC , uint8 , MAGIC4BE('I','F','C','.') ) GET_MPTHEADER_sized_member( nIFR , uint8 , MAGIC4BE('I','F','R','.') ) GET_MPTHEADER_sized_member( wMidiBank , uint16 , MAGIC4BE('M','B','.','.') ) GET_MPTHEADER_sized_member( nMidiProgram , uint8 , MAGIC4BE('M','P','.','.') ) GET_MPTHEADER_sized_member( nMidiChannel , uint8 , MAGIC4BE('M','C','.','.') ) GET_MPTHEADER_sized_member( nPPS , int8 , MAGIC4BE('P','P','S','.') ) GET_MPTHEADER_sized_member( nPPC , uint8 , MAGIC4BE('P','P','C','.') ) GET_MPTHEADER_envelope_member(ENV_VOLUME , tick , uint16 , MAGIC4BE('V','P','[','.') ) GET_MPTHEADER_envelope_member(ENV_PANNING , tick , uint16 , MAGIC4BE('P','P','[','.') ) GET_MPTHEADER_envelope_member(ENV_PITCH , tick , uint16 , MAGIC4BE('P','i','P','[') ) GET_MPTHEADER_envelope_member(ENV_VOLUME , value , uint8 , MAGIC4BE('V','E','[','.') ) GET_MPTHEADER_envelope_member(ENV_PANNING , value , uint8 , MAGIC4BE('P','E','[','.') ) GET_MPTHEADER_envelope_member(ENV_PITCH , value , uint8 , MAGIC4BE('P','i','E','[') ) GET_MPTHEADER_array_member( NoteMap , uint8 , MAGIC4BE('N','M','[','.') ) GET_MPTHEADER_array_member( Keyboard , uint16 , MAGIC4BE('K','[','.','.') ) GET_MPTHEADER_array_member( name , char , MAGIC4BE('n','[','.','.') ) GET_MPTHEADER_array_member( filename , char , MAGIC4BE('f','n','[','.') ) GET_MPTHEADER_sized_member( nMixPlug , uint8 , MAGIC4BE('M','i','P','.') ) GET_MPTHEADER_sized_member( nVolRampUp , uint16 , MAGIC4BE('V','R','.','.') ) GET_MPTHEADER_sized_member( nResampling , uint32 , MAGIC4BE('R','.','.','.') ) GET_MPTHEADER_sized_member( nCutSwing , uint8 , MAGIC4BE('C','S','.','.') ) GET_MPTHEADER_sized_member( nResSwing , uint8 , MAGIC4BE('R','S','.','.') ) GET_MPTHEADER_sized_member( nFilterMode , uint8 , MAGIC4BE('F','M','.','.') ) GET_MPTHEADER_sized_member( nPluginVelocityHandling , uint8 , MAGIC4BE('P','V','E','H') ) GET_MPTHEADER_sized_member( nPluginVolumeHandling , uint8 , MAGIC4BE('P','V','O','H') ) GET_MPTHEADER_sized_member( PitchEnv.nReleaseNode , uint8 , MAGIC4BE('P','E','R','N') ) GET_MPTHEADER_sized_member( PanEnv.nReleaseNode , uint8 , MAGIC4BE('A','E','R','N') ) GET_MPTHEADER_sized_member( VolEnv.nReleaseNode , uint8 , MAGIC4BE('V','E','R','N') ) GET_MPTHEADER_sized_member( PitchEnv.dwFlags , uint32 , MAGIC4BE('P','F','L','G') ) GET_MPTHEADER_sized_member( PanEnv.dwFlags , uint32 , MAGIC4BE('A','F','L','G') ) GET_MPTHEADER_sized_member( VolEnv.dwFlags , uint32 , MAGIC4BE('V','F','L','G') ) GET_MPTHEADER_sized_member( midiPWD , int8 , MAGIC4BE('M','P','W','D') ) case MAGIC4BE('P','T','T','L'): { // Integer part of pitch/tempo lock uint16 tmp = file.ReadTruncatedIntLE(fsize); input->pitchToTempoLock.Set(tmp, input->pitchToTempoLock.GetFract()); result = true; } break; case MAGIC4LE('P','T','T','F'): { // Fractional part of pitch/tempo lock uint16 tmp = file.ReadTruncatedIntLE(fsize); input->pitchToTempoLock.Set(input->pitchToTempoLock.GetInt(), tmp); result = true; } break; case MAGIC4BE('V','E','.','.'): input->VolEnv.resize(std::min(MAX_ENVPOINTS, file.ReadTruncatedIntLE(fsize))); result = true; break; case MAGIC4BE('P','E','.','.'): input->PanEnv.resize(std::min(MAX_ENVPOINTS, file.ReadTruncatedIntLE(fsize))); result = true; break; case MAGIC4BE('P','i','E','.'): input->PitchEnv.resize(std::min(MAX_ENVPOINTS, file.ReadTruncatedIntLE(fsize))); result = true; break; } return result; } // Convert instrument flags which were read from 'dF..' extension to proper internal representation. static void ConvertReadExtendedFlags(ModInstrument *pIns) { // Flags of 'dF..' datafield in extended instrument properties. enum { dFdd_VOLUME = 0x0001, dFdd_VOLSUSTAIN = 0x0002, dFdd_VOLLOOP = 0x0004, dFdd_PANNING = 0x0008, dFdd_PANSUSTAIN = 0x0010, dFdd_PANLOOP = 0x0020, dFdd_PITCH = 0x0040, dFdd_PITCHSUSTAIN = 0x0080, dFdd_PITCHLOOP = 0x0100, dFdd_SETPANNING = 0x0200, dFdd_FILTER = 0x0400, dFdd_VOLCARRY = 0x0800, dFdd_PANCARRY = 0x1000, dFdd_PITCHCARRY = 0x2000, dFdd_MUTE = 0x4000, }; const uint32 dwOldFlags = pIns->dwFlags.GetRaw(); pIns->VolEnv.dwFlags.set(ENV_ENABLED, (dwOldFlags & dFdd_VOLUME) != 0); pIns->VolEnv.dwFlags.set(ENV_SUSTAIN, (dwOldFlags & dFdd_VOLSUSTAIN) != 0); pIns->VolEnv.dwFlags.set(ENV_LOOP, (dwOldFlags & dFdd_VOLLOOP) != 0); pIns->VolEnv.dwFlags.set(ENV_CARRY, (dwOldFlags & dFdd_VOLCARRY) != 0); pIns->PanEnv.dwFlags.set(ENV_ENABLED, (dwOldFlags & dFdd_PANNING) != 0); pIns->PanEnv.dwFlags.set(ENV_SUSTAIN, (dwOldFlags & dFdd_PANSUSTAIN) != 0); pIns->PanEnv.dwFlags.set(ENV_LOOP, (dwOldFlags & dFdd_PANLOOP) != 0); pIns->PanEnv.dwFlags.set(ENV_CARRY, (dwOldFlags & dFdd_PANCARRY) != 0); pIns->PitchEnv.dwFlags.set(ENV_ENABLED, (dwOldFlags & dFdd_PITCH) != 0); pIns->PitchEnv.dwFlags.set(ENV_SUSTAIN, (dwOldFlags & dFdd_PITCHSUSTAIN) != 0); pIns->PitchEnv.dwFlags.set(ENV_LOOP, (dwOldFlags & dFdd_PITCHLOOP) != 0); pIns->PitchEnv.dwFlags.set(ENV_CARRY, (dwOldFlags & dFdd_PITCHCARRY) != 0); pIns->PitchEnv.dwFlags.set(ENV_FILTER, (dwOldFlags & dFdd_FILTER) != 0); pIns->dwFlags.reset(); pIns->dwFlags.set(INS_SETPANNING, (dwOldFlags & dFdd_SETPANNING) != 0); pIns->dwFlags.set(INS_MUTE, (dwOldFlags & dFdd_MUTE) != 0); } void ReadInstrumentExtensionField(ModInstrument* pIns, const uint32 code, const uint16 size, FileReader &file) { if(code == MAGIC4BE('K','[','.','.')) { // skip keyboard mapping file.Skip(size); return; } bool success = ReadInstrumentHeaderField(pIns, code, size, file); if(!success) { file.Skip(size); return; } if(code == MAGIC4BE('n','[','.','.')) mpt::String::SetNullTerminator(pIns->name); if(code == MAGIC4BE('f','n','[','.')) mpt::String::SetNullTerminator(pIns->filename); if(code == MAGIC4BE('d','F','.','.')) // 'dF..' field requires additional processing. ConvertReadExtendedFlags(pIns); } void ReadExtendedInstrumentProperty(ModInstrument* pIns, const uint32 code, FileReader &file) { uint16 size = file.ReadUint16LE(); if(!file.CanRead(size)) { return; } ReadInstrumentExtensionField(pIns, code, size, file); } void ReadExtendedInstrumentProperties(ModInstrument* pIns, FileReader &file) { if(!file.ReadMagic("XTPM")) // 'MPTX' { return; } while(file.CanRead(7)) { ReadExtendedInstrumentProperty(pIns, file.ReadUint32LE(), file); } } void CSoundFile::LoadExtendedInstrumentProperties(FileReader &file, bool *pInterpretMptMade) { if(!file.ReadMagic("XTPM")) // 'MPTX' { return; } // Found MPTX, interpret the file MPT made. if(pInterpretMptMade != nullptr) *pInterpretMptMade = true; while(file.CanRead(6)) { uint32 code = file.ReadUint32LE(); if(code == MAGIC4BE('M','P','T','S') // Reached song extensions, break out of this loop || code == MAGIC4LE('2','2','8',4) // Reached MPTM extensions (in case there are no song extensions) || (code & 0x80808080) || !(code & 0x60606060)) // Non-ASCII chunk ID { file.SkipBack(4); return; } // Read size of this property for *one* instrument const uint16 size = file.ReadUint16LE(); for(INSTRUMENTINDEX i = 1; i <= GetNumInstruments(); i++) { if(Instruments[i]) { ReadInstrumentExtensionField(Instruments[i], code, size, file); } } } } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Sndfile.h0000644000372100037210000013047513233626144017650 00000000000000/* * Sndfile.h * --------- * Purpose: Core class of the playback engine. Every song is represented by a CSoundFile object. * Notes : (currently none) * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "SoundFilePlayConfig.h" #include "MixerSettings.h" #include "../common/misc_util.h" #include "../common/mptRandom.h" #include #include #include #include "Snd_defs.h" #include "tuningbase.h" #include "MIDIMacros.h" #ifdef MODPLUG_TRACKER #include "../mptrack/MIDIMapping.h" #endif // MODPLUG_TRACKER #include "Mixer.h" #include "Resampler.h" #ifndef NO_REVERB #include "../sounddsp/Reverb.h" #endif #ifndef NO_AGC #include "../sounddsp/AGC.h" #endif #ifndef NO_DSP #include "../sounddsp/DSP.h" #endif #ifndef NO_EQ #include "../sounddsp/EQ.h" #endif #include "modcommand.h" #include "ModSample.h" #include "ModInstrument.h" #include "ModChannel.h" #include "plugins/PluginStructs.h" #include "RowVisitor.h" #include "Message.h" #include "pattern.h" #include "patternContainer.h" #include "ModSequence.h" #include "../common/FileReaderFwd.h" OPENMPT_NAMESPACE_BEGIN // ----------------------------------------------------------------------------- // MODULAR ModInstrument FIELD ACCESS : body content in InstrumentExtensions.cpp // ----------------------------------------------------------------------------- #ifndef MODPLUG_NO_FILESAVE extern void WriteInstrumentHeaderStructOrField(ModInstrument * input, FILE * file, uint32 only_this_code = -1 /* -1 for all */, uint16 fixedsize = 0); #endif // !MODPLUG_NO_FILESAVE extern bool ReadInstrumentHeaderField(ModInstrument * input, uint32 fcode, uint16 fsize, FileReader &file); // -------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------- typedef void (* LPSNDMIXHOOKPROC)(int *, unsigned long, unsigned long); // buffer, samples, channels #ifdef LIBOPENMPT_BUILD #ifndef NO_PLUGINS class CVstPluginManager; #endif #endif typedef std::bitset PlayBehaviourSet; #ifdef MODPLUG_TRACKER // For WAV export (writing pattern positions to file) struct PatternCuePoint { uint64 offset; // offset in the file (in samples) ORDERINDEX order; // which order is this? bool processed; // has this point been processed by the main WAV render function yet? }; #endif // MODPLUG_TRACKER // Return values for GetLength() struct GetLengthType { double duration; // total time in seconds ROWINDEX lastRow; // last parsed row (if no target is specified, this is the first row that is parsed twice, i.e. not the *last* played order) ROWINDEX endRow; // last row before module loops (UNDEFINED if a target is specified) ROWINDEX startRow; // first row of parsed subsong ORDERINDEX lastOrder; // last parsed order (see lastRow remark) ORDERINDEX endOrder; // last order before module loops (UNDEFINED if a target is specified) ORDERINDEX startOrder; // first order of parsed subsong bool targetReached; // true if the specified order/row combination or duration has been reached while going through the module GetLengthType() : duration(0.0) , lastRow(ROWINDEX_INVALID), endRow(ROWINDEX_INVALID), startRow(0) , lastOrder(ORDERINDEX_INVALID), endOrder(ORDERINDEX_INVALID), startOrder(0) , targetReached(false) { } }; // Target seek mode for GetLength() struct GetLengthTarget { ROWINDEX startRow; ORDERINDEX startOrder; SEQUENCEINDEX sequence; struct pos_type { ROWINDEX row; ORDERINDEX order; }; union { double time; pos_type pos; }; enum Mode { NoTarget, // Don't seek, i.e. return complete length of the first subsong. GetAllSubsongs, // Same as NoTarget (i.e. get complete length), but returns the length of all sub songs SeekPosition, // Seek to given pattern position. SeekSeconds, // Seek to given time. } mode; // Don't seek, i.e. return complete module length. GetLengthTarget(bool allSongs = false) { mode = allSongs ? GetAllSubsongs : NoTarget; sequence = SEQUENCEINDEX_INVALID; startOrder = 0; startRow = 0; } // Seek to given pattern position if position is valid. GetLengthTarget(ORDERINDEX order, ROWINDEX row) { mode = NoTarget; sequence = SEQUENCEINDEX_INVALID; startOrder = 0; startRow = 0; if(order != ORDERINDEX_INVALID && row != ROWINDEX_INVALID) { mode = SeekPosition; pos.row = row; pos.order = order; } } // Seek to given time if t is valid (i.e. not negative). GetLengthTarget(double t) { mode = NoTarget; sequence = SEQUENCEINDEX_INVALID; startOrder = 0; startRow = 0; if(t >= 0.0) { mode = SeekSeconds; time = t; } } // Set start position from which seeking should begin. GetLengthTarget &StartPos(SEQUENCEINDEX seq, ORDERINDEX order, ROWINDEX row) { sequence = seq; startOrder = order; startRow = row; return *this; } }; // Reset mode for GetLength() enum enmGetLengthResetMode { // Never adjust global variables / mod parameters eNoAdjust = 0x00, // Mod parameters (such as global volume, speed, tempo, etc...) will always be memorized if the target was reached (i.e. they won't be reset to the previous values). If target couldn't be reached, they are reset to their default values. eAdjust = 0x01, // Same as above, but global variables will only be memorized if the target could be reached. This does *NOT* influence the visited rows vector - it will *ALWAYS* be adjusted in this mode. eAdjustOnSuccess = 0x02 | eAdjust, // Same as previous option, but will also try to emulate sample playback so that voices from previous patterns will sound when continuing playback at the target position. eAdjustSamplePositions = 0x04 | eAdjustOnSuccess, }; // Delete samples assigned to instrument enum deleteInstrumentSamples { deleteAssociatedSamples, doNoDeleteAssociatedSamples, }; namespace Tuning { class CTuningCollection; } // namespace Tuning typedef Tuning::CTuningCollection CTuningCollection; struct CModSpecifications; #ifdef MODPLUG_TRACKER class CModDoc; #endif // MODPLUG_TRACKER ///////////////////////////////////////////////////////////////////////// // File edit history #define HISTORY_TIMER_PRECISION 18.2f struct FileHistory { // Date when the file was loaded in the the tracker or created. tm loadDate; // Time the file was open in the editor, in 1/18.2th seconds (frequency of a standard DOS timer, to keep compatibility with Impulse Tracker easy). uint32 openTime; // Return the date as a (possibly truncated if not enough precision is available) ISO 8601 formatted date. mpt::ustring AsISO8601() const; }; struct TimingInfo { double InputLatency; // seconds double OutputLatency; // seconds int64 StreamFrames; uint64 SystemTimestamp; // nanoseconds double Speed; TimingInfo() : InputLatency(0.0) , OutputLatency(0.0) , StreamFrames(0) , SystemTimestamp(0) , Speed(1.0) { return; } }; class IAudioReadTarget { protected: virtual ~IAudioReadTarget() { } public: virtual void DataCallback(int *MixSoundBuffer, std::size_t channels, std::size_t countChunk) = 0; }; typedef char NoteName[4]; class CSoundFile { friend class GetLengthMemory; public: //Misc #ifdef MODPLUG_TRACKER void ChangeModTypeTo(const MODTYPE& newType); #endif // MODPLUG_TRACKER // Returns value in seconds. If given position won't be played at all, returns -1. // If updateVars is true, the state of various playback variables will be updated according to the playback position. // If updateSamplePos is also true, the sample positions of samples still playing from previous patterns will be kept in sync. double GetPlaybackTimeAt(ORDERINDEX ord, ROWINDEX row, bool updateVars, bool updateSamplePos); //Tuning--> public: static CTuning* CreateTuning12TET(const std::string &name); static CTuning *GetDefaultTuning() {return nullptr;} CTuningCollection& GetTuneSpecificTunings() {return *m_pTuningsTuneSpecific;} std::string GetNoteName(const ModCommand::NOTE note, const INSTRUMENTINDEX inst) const; std::string GetNoteName(const ModCommand::NOTE note) const; static std::string GetNoteName(const ModCommand::NOTE note, const NoteName *noteNames); #ifdef MODPLUG_TRACKER static const NoteName *m_NoteNames; static void SetDefaultNoteNames(); static const NoteName *GetDefaultNoteNames(); #else const NoteName *m_NoteNames; #endif private: CTuningCollection* m_pTuningsTuneSpecific; //<--Tuning #ifdef MODPLUG_TRACKER public: CMIDIMapper& GetMIDIMapper() {return m_MIDIMapper;} const CMIDIMapper& GetMIDIMapper() const {return m_MIDIMapper;} private: CMIDIMapper m_MIDIMapper; #endif // MODPLUG_TRACKER private: //Misc private methods. static void SetModSpecsPointer(const CModSpecifications*& pModSpecs, const MODTYPE type); private: //Misc data const CModSpecifications *m_pModSpecs; private: // Interleaved Front Mix Buffer (Also room for interleaved rear mix) mixsample_t MixSoundBuffer[MIXBUFFERSIZE * 4]; mixsample_t MixRearBuffer[MIXBUFFERSIZE * 2]; // Non-interleaved plugin processing buffer float MixFloatBuffer[2][MIXBUFFERSIZE]; mixsample_t gnDryLOfsVol; mixsample_t gnDryROfsVol; public: MixerSettings m_MixerSettings; CResampler m_Resampler; #ifndef NO_REVERB CReverb m_Reverb; #endif #ifndef NO_DSP CSurround m_Surround; CMegaBass m_MegaBass; #endif #ifndef NO_EQ CQuadEQ m_EQ; #endif #ifndef NO_AGC CAGC m_AGC; #endif typedef uint32 samplecount_t; // Number of rendered samples public: // for Editing #ifdef MODPLUG_TRACKER CModDoc *m_pModDoc; // Can be a null pointer for example when previewing samples from the treeview. #endif // MODPLUG_TRACKER Enum m_nType; private: MODCONTAINERTYPE m_ContainerType; public: CHANNELINDEX m_nChannels; SAMPLEINDEX m_nSamples; INSTRUMENTINDEX m_nInstruments; uint32 m_nDefaultSpeed, m_nDefaultGlobalVolume; TEMPO m_nDefaultTempo; FlagSet m_SongFlags; CHANNELINDEX m_nMixChannels; private: CHANNELINDEX m_nMixStat; public: ROWINDEX m_nDefaultRowsPerBeat, m_nDefaultRowsPerMeasure; // default rows per beat and measure for this module TempoMode m_nTempoMode; #ifdef MODPLUG_TRACKER // Lock playback between two rows. Lock is active if lock start != ROWINDEX_INVALID). ROWINDEX m_lockRowStart, m_lockRowEnd; // Lock playback between two orders. Lock is active if lock start != ORDERINDEX_INVALID). ORDERINDEX m_lockOrderStart, m_lockOrderEnd; #endif // MODPLUG_TRACKER uint32 m_nSamplePreAmp, m_nVSTiVolume; bool IsGlobalVolumeUnset() const { return IsFirstTick(); } #ifndef MODPLUG_TRACKER uint32 m_nFreqFactor; // Pitch shift factor (65536 = no pitch shifting). Only used in libopenmpt (openmpt::ext::interactive::set_pitch_factor) uint32 m_nTempoFactor; // Tempo factor (65536 = no tempo adjustment). Only used in libopenmpt (openmpt::ext::interactive::set_tempo_factor) #endif // Row swing factors for modern tempo mode TempoSwing m_tempoSwing; // Min Period = highest possible frequency, Max Period = lowest possible frequency for current format // Note: Period is an Amiga metric that is inverse to frequency. // Periods in MPT are 4 times as fine as Amiga periods because of extra fine frequency slides (introduced in the S3M format). int32 m_nMinPeriod, m_nMaxPeriod; ResamplingMode m_nResampling; // Resampling mode (if overriding the globally set resampling) int32 m_nRepeatCount; // -1 means repeat infinitely. ORDERINDEX m_nMaxOrderPosition; ModChannelSettings ChnSettings[MAX_BASECHANNELS]; // Initial channels settings CPatternContainer Patterns; // Patterns ModSequenceSet Order; // Modsequences. Order[x] returns an index of a pattern located at order x of the current sequence. protected: ModSample Samples[MAX_SAMPLES]; // Sample Headers public: ModInstrument *Instruments[MAX_INSTRUMENTS]; // Instrument Headers MIDIMacroConfig m_MidiCfg; // MIDI Macro config table #ifndef NO_PLUGINS SNDMIXPLUGIN m_MixPlugins[MAX_MIXPLUGINS]; // Mix plugins #endif char m_szNames[MAX_SAMPLES][MAX_SAMPLENAME]; // Sample names uint32 m_dwCreatedWithVersion; uint32 m_dwLastSavedWithVersion; PlayBehaviourSet m_playBehaviour; protected: mpt::fast_prng m_PRNG; inline mpt::fast_prng & AccessPRNG() const { return const_cast(this)->m_PRNG; } inline mpt::fast_prng & AccessPRNG() { return m_PRNG; } protected: // Mix level stuff CSoundFilePlayConfig m_PlayConfig; MixLevels m_nMixLevels; public: struct PlayState { friend class CSoundFile; protected: samplecount_t m_nBufferCount; double m_dBufferDiff; public: samplecount_t m_lTotalSampleCount; public: uint32 m_nTickCount; protected: uint32 m_nPatternDelay, m_nFrameDelay; // m_nPatternDelay = pattern delay (rows), m_nFrameDelay = fine pattern delay (ticks) public: uint32 m_nSamplesPerTick; ROWINDEX m_nCurrentRowsPerBeat, m_nCurrentRowsPerMeasure; // current rows per beat and measure for this module uint32 m_nMusicSpeed; // Current speed TEMPO m_nMusicTempo; // Current tempo // Playback position ROWINDEX m_nRow; ROWINDEX m_nNextRow; protected: ROWINDEX m_nNextPatStartRow; // for FT2's E60 bug public: PATTERNINDEX m_nPattern; ORDERINDEX m_nCurrentOrder, m_nNextOrder, m_nSeqOverride; // Global volume public: int32 m_nGlobalVolume; protected: int32 m_nSamplesToGlobalVolRampDest, m_nGlobalVolumeRampAmount, m_nGlobalVolumeDestination; int32 m_lHighResRampingGlobalVolume; public: bool m_bPositionChanged; // Report to plugins that we jumped around in the module public: CHANNELINDEX ChnMix[MAX_CHANNELS]; // Channels to be mixed ModChannel Chn[MAX_CHANNELS]; // Mixing channels... First m_nChannels channels are master channels (i.e. they are never NNA channels)! public: PlayState() : m_lTotalSampleCount(0) , m_nSeqOverride(ORDERINDEX_INVALID) , m_bPositionChanged(true) { std::fill(std::begin(Chn), std::end(Chn), ModChannel()); } }; PlayState m_PlayState; protected: // For handling backwards jumps and stuff to prevent infinite loops when counting the mod length or rendering to wav. RowVisitor visitedSongRows; public: #ifdef MODPLUG_TRACKER std::bitset m_bChannelMuteTogglePending; std::vector m_PatternCuePoints; // For WAV export (writing pattern positions to file) #endif // MODPLUG_TRACKER public: #ifdef LIBOPENMPT_BUILD #ifndef NO_PLUGINS std::unique_ptr m_PluginManager; #endif #endif public: std::string m_songName; mpt::ustring m_songArtist; // Song message SongMessage m_songMessage; mpt::ustring m_madeWithTracker; protected: std::vector m_FileHistory; // File edit history public: std::vector &GetFileHistory() { return m_FileHistory; } const std::vector &GetFileHistory() const { return m_FileHistory; } #ifdef MPT_EXTERNAL_SAMPLES // MPTM external on-disk sample paths protected: std::vector m_samplePaths; public: void SetSamplePath(SAMPLEINDEX smp, const mpt::PathString &filename) { if(m_samplePaths.size() < smp) m_samplePaths.resize(smp); m_samplePaths[smp - 1] = filename.Simplify(); } void ResetSamplePath(SAMPLEINDEX smp) { if(m_samplePaths.size() >= smp) m_samplePaths[smp - 1] = mpt::PathString(); Samples[smp].uFlags.reset(SMP_KEEPONDISK | SMP_MODIFIED);} mpt::PathString GetSamplePath(SAMPLEINDEX smp) const { if(m_samplePaths.size() >= smp) return m_samplePaths[smp - 1]; else return mpt::PathString(); } bool SampleHasPath(SAMPLEINDEX smp) const { if(m_samplePaths.size() >= smp) return !m_samplePaths[smp - 1].empty(); else return false; } bool IsExternalSampleMissing(SAMPLEINDEX smp) const { return Samples[smp].uFlags[SMP_KEEPONDISK] && Samples[smp].pSample == nullptr; } bool LoadExternalSample(SAMPLEINDEX smp, const mpt::PathString &filename); #endif // MPT_EXTERNAL_SAMPLES bool m_bIsRendering; TimingInfo m_TimingInfo; // only valid if !m_bIsRendering private: // logging ILog *m_pCustomLog; public: CSoundFile(); ~CSoundFile(); public: // logging void SetCustomLog(ILog *pLog) { m_pCustomLog = pLog; } void AddToLog(LogLevel level, const mpt::ustring &text) const; /*MPT_DEPRECATED*/ void AddToLog(const AnyStringLocale &text) const { AddToLog(LogInformation, mpt::ToUnicode(text)); } public: enum ModLoadingFlags { onlyVerifyHeader = 0x00, loadPatternData = 0x01, // If unset, advise loaders to not process any pattern data (if possible) loadSampleData = 0x02, // If unset, advise loaders to not process any sample data (if possible) loadPluginData = 0x04, // If unset, plugin data is not loaded (and as a consequence, plugins are not instanciated). loadPluginInstance = 0x08, // If unset, plugins are not instanciated. skipContainer = 0x10, skipModules = 0x20, // Shortcuts loadCompleteModule = loadSampleData | loadPatternData | loadPluginData | loadPluginInstance, loadNoPatternOrPluginData = loadSampleData, loadNoPluginInstance = loadSampleData | loadPatternData | loadPluginData, }; #define PROBE_RECOMMENDED_SIZE 2048u static const std::size_t ProbeRecommendedSize; enum ProbeFlags { ProbeModules = 0x1, ProbeContainers = 0x2, ProbeFlagsDefault = ProbeModules | ProbeContainers, ProbeFlagsNone = 0 }; enum ProbeResult { ProbeSuccess = 1, ProbeFailure = 0, ProbeWantMoreData = -1 }; static ProbeResult ProbeAdditionalSize(MemoryFileReader &file, const uint64 *pfilesize, uint64 minimumAdditionalSize); static ProbeResult Probe(ProbeFlags flags, mpt::span data, const uint64 *pfilesize); public: #ifdef MODPLUG_TRACKER // Get parent CModDoc. Can be nullptr if previewing from tree view, and is always nullptr if we're not actually compiling OpenMPT. CModDoc *GetpModDoc() const { return m_pModDoc; } bool Create(FileReader file, ModLoadingFlags loadFlags = loadCompleteModule, CModDoc *pModDoc = nullptr); #else bool Create(FileReader file, ModLoadingFlags loadFlags); #endif // MODPLUG_TRACKER bool Destroy(); Enum GetType() const { return m_nType; } MODCONTAINERTYPE GetContainerType() const { return m_ContainerType; } // rough heuristic, could be improved mpt::Charset GetCharsetFile() const // 8bit string encoding of strings in the on-disk file { return GetCharsetFromModType(GetType()); } mpt::Charset GetCharsetInternal() const // 8bit string encoding of strings internal in CSoundFile { #if defined(MODPLUG_TRACKER) return mpt::CharsetLocale; #else // MODPLUG_TRACKER return GetCharsetFile(); #endif // MODPLUG_TRACKER } void SetPreAmp(uint32 vol); uint32 GetPreAmp() const { return m_MixerSettings.m_nPreAmp; } void SetMixLevels(MixLevels levels); MixLevels GetMixLevels() const { return m_nMixLevels; } const CSoundFilePlayConfig &GetPlayConfig() const { return m_PlayConfig; } INSTRUMENTINDEX GetNumInstruments() const { return m_nInstruments; } SAMPLEINDEX GetNumSamples() const { return m_nSamples; } PATTERNINDEX GetCurrentPattern() const { return m_PlayState.m_nPattern; } ORDERINDEX GetCurrentOrder() const { return m_PlayState.m_nCurrentOrder; } CHANNELINDEX GetNumChannels() const { return m_nChannels; } #ifndef NO_PLUGINS IMixPlugin* GetInstrumentPlugin(INSTRUMENTINDEX instr); #endif const CModSpecifications& GetModSpecifications() const {return *m_pModSpecs;} static const CModSpecifications& GetModSpecifications(const MODTYPE type); #ifdef MODPLUG_TRACKER void PatternTranstionChnSolo(const CHANNELINDEX chnIndex); void PatternTransitionChnUnmuteAll(); #endif // MODPLUG_TRACKER double GetCurrentBPM() const; void DontLoopPattern(PATTERNINDEX nPat, ROWINDEX nRow = 0); CHANNELINDEX GetMixStat() const { return m_nMixStat; } void ResetMixStat() { m_nMixStat = 0; } void ResetPlayPos(); void SetCurrentOrder(ORDERINDEX nOrder); std::string GetTitle() const { return m_songName; } bool SetTitle(const std::string &newTitle); // Return true if title was changed. const char *GetSampleName(SAMPLEINDEX nSample) const; const char *GetInstrumentName(INSTRUMENTINDEX nInstr) const; uint32 GetMusicSpeed() const { return m_PlayState.m_nMusicSpeed; } TEMPO GetMusicTempo() const { return m_PlayState.m_nMusicTempo; } bool IsFirstTick() const { return (m_PlayState.m_lTotalSampleCount == 0); } //Get modlength in various cases: total length, length to //specific order&row etc. Return value is in seconds. std::vector GetLength(enmGetLengthResetMode adjustMode, GetLengthTarget target = GetLengthTarget()); public: //Returns song length in seconds. double GetSongTime() { return GetLength(eNoAdjust).back().duration; } void RecalculateSamplesPerTick(); double GetRowDuration(TEMPO tempo, uint32 speed) const; uint32 GetTickDuration(PlayState &playState) const; // A repeat count value of -1 means infinite loop void SetRepeatCount(int n) { m_nRepeatCount = n; } int GetRepeatCount() const { return m_nRepeatCount; } bool IsPaused() const { return m_SongFlags[SONG_PAUSED | SONG_STEP]; } // Added SONG_STEP as it seems to be desirable in most cases to check for this as well. void LoopPattern(PATTERNINDEX nPat, ROWINDEX nRow = 0); bool InitChannel(CHANNELINDEX nChn); void InitAmigaResampler(); static ProbeResult ProbeFileHeaderMMCMP(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderPP20(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderUMX(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderXPK(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeader669(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderAM(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderAMF_Asylum(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderAMF_DSMI(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderAMS(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderAMS2(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderDBM(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderDTM(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderDIGI(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderDMF(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderDSM(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderFAR(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderGDM(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderICE(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderIMF(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderIT(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderITP(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderJ2B(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderM15(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderMDL(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderMED(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderMO3(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderMOD(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderMT2(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderMTM(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderOKT(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderPLM(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderPSM(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderPSM16(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderPT36(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderPTM(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderS3M(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderSFX(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderSTM(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderSTP(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderULT(MemoryFileReader file, const uint64 *pfilesize); static ProbeResult ProbeFileHeaderXM(MemoryFileReader file, const uint64 *pfilesize); // Module Loaders bool Read669(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadAM(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadAMF_Asylum(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadAMF_DSMI(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadAMS(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadAMS2(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadDBM(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadDTM(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadDIGI(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadDMF(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadDSM(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadFAR(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadGDM(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadICE(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadIMF(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadIT(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadITProject(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadJ2B(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadM15(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadMDL(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadMed(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadMO3(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadMod(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadMT2(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadMTM(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadOKT(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadPLM(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadPSM(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadPSM16(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadPT36(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadPTM(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadS3M(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadSFX(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadSTM(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadSTP(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadUlt(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadXM(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadMID(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadUAX(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); bool ReadWav(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule); static std::vector GetSupportedExtensions(bool otherFormats); static bool IsExtensionSupported(const char *ext); // UTF8, casing of ext is ignored static mpt::Charset GetCharsetFromModType(MODTYPE modtype); static mpt::ustring ModTypeToString(MODTYPE modtype); static mpt::ustring ModContainerTypeToString(MODCONTAINERTYPE containertype); static mpt::ustring ModTypeToTracker(MODTYPE modtype); static mpt::ustring ModContainerTypeToTracker(MODCONTAINERTYPE containertype); void UpgradeModule(); // Save Functions #ifndef MODPLUG_NO_FILESAVE bool SaveXM(const mpt::PathString &filename, bool compatibilityExport = false); bool SaveS3M(const mpt::PathString &filename) const; bool SaveMod(const mpt::PathString &filename) const; bool SaveIT(const mpt::PathString &filename, bool compatibilityExport = false); uint32 SaveMixPlugins(FILE *f=NULL, bool bUpdate=true); void WriteInstrumentPropertyForAllInstruments(uint32 code, uint16 size, FILE* f, INSTRUMENTINDEX nInstruments) const; void SaveExtendedInstrumentProperties(INSTRUMENTINDEX nInstruments, FILE* f) const; void SaveExtendedSongProperties(FILE* f) const; #endif // MODPLUG_NO_FILESAVE void LoadExtendedSongProperties(FileReader &file, bool* pInterpretMptMade = nullptr); void LoadMPTMProperties(FileReader &file, uint16 cwtv); mpt::ustring GetSchismTrackerVersion(uint16 cwtv); // Reads extended instrument properties(XM/IT/MPTM). // If no errors occur and song extension tag is found, returns pointer to the beginning // of the tag, else returns NULL. void LoadExtendedInstrumentProperties(FileReader &file, bool *pInterpretMptMade = nullptr); void SetDefaultPlaybackBehaviour(MODTYPE type); static PlayBehaviourSet GetSupportedPlaybackBehaviour(MODTYPE type); static PlayBehaviourSet GetDefaultPlaybackBehaviour(MODTYPE type); // MOD Convert function MODTYPE GetBestSaveFormat() const; static void ConvertModCommand(ModCommand &m); static void S3MConvert(ModCommand &m, bool fromIT); void S3MSaveConvert(uint8 &command, uint8 ¶m, bool toIT, bool compatibilityExport = false) const; void ModSaveCommand(uint8 &command, uint8 ¶m, const bool toXM, const bool compatibilityExport = false) const; static void ReadMODPatternEntry(FileReader &file, ModCommand &m); static void ReadMODPatternEntry(const uint8 (&data)[4], ModCommand &m); void SetupMODPanning(bool bForceSetup = false); // Setup LRRL panning, max channel volume public: // Real-time sound functions void SuspendPlugins(); void ResumePlugins(); void StopAllVsti(); void RecalculateGainForAllPlugs(); void ResetChannels(); samplecount_t Read(samplecount_t count, IAudioReadTarget &target); private: void CreateStereoMix(int count); public: bool FadeSong(uint32 msec); private: void ProcessDSP(std::size_t countChunk); void ProcessPlugins(uint32 nCount); public: samplecount_t GetTotalSampleCount() const { return m_PlayState.m_lTotalSampleCount; } bool HasPositionChanged() { bool b = m_PlayState.m_bPositionChanged; m_PlayState.m_bPositionChanged = false; return b; } bool IsRenderingToDisc() const { return m_bIsRendering; } void PrecomputeSampleLoops(bool updateChannels = false); public: // Mixer Config void SetMixerSettings(const MixerSettings &mixersettings); void SetResamplerSettings(const CResamplerSettings &resamplersettings); void InitPlayer(bool bReset=false); void SetDspEffects(uint32 DSPMask); uint32 GetSampleRate() const { return m_MixerSettings.gdwMixingFreq; } #ifndef NO_EQ void SetEQGains(const uint32 *pGains, uint32 nBands, const uint32 *pFreqs=NULL, bool bReset=false) { m_EQ.SetEQGains(pGains, nBands, pFreqs, bReset, m_MixerSettings.gdwMixingFreq); } // 0=-12dB, 32=+12dB #endif // NO_EQ public: bool ReadNote(); bool ProcessRow(); bool ProcessEffects(); CHANNELINDEX GetNNAChannel(CHANNELINDEX nChn) const; CHANNELINDEX CheckNNA(CHANNELINDEX nChn, uint32 instr, int note, bool forceCut); void NoteChange(ModChannel *pChn, int note, bool bPorta = false, bool bResetEnv = true, bool bManual = false) const; void InstrumentChange(ModChannel *pChn, uint32 instr, bool bPorta = false, bool bUpdVol = true, bool bResetEnv = true) const; void ApplyInstrumentPanning(ModChannel *pChn, const ModInstrument *instr, const ModSample *smp) const; uint32 CalculateXParam(PATTERNINDEX pat, ROWINDEX row, CHANNELINDEX chn, bool *isExtended = nullptr) const; // Channel Effects void KeyOff(ModChannel *pChn) const; // Global Effects void SetTempo(TEMPO param, bool setAsNonModcommand = false); void SetSpeed(PlayState &playState, uint32 param) const; static TEMPO ConvertST2Tempo(uint8 tempo); protected: // Global variable initializer for loader functions void SetType(MODTYPE type); void InitializeGlobals(MODTYPE type = MOD_TYPE_NONE); void InitializeChannels(); // Channel effect processing int GetVibratoDelta(int type, int position) const; void ProcessVolumeSwing(ModChannel *pChn, int &vol) const; void ProcessPanningSwing(ModChannel *pChn) const; void ProcessTremolo(ModChannel *pChn, int &vol) const; void ProcessTremor(CHANNELINDEX nChn, int &vol); bool IsEnvelopeProcessed(const ModChannel *pChn, EnvelopeType env) const; void ProcessVolumeEnvelope(ModChannel *pChn, int &vol) const; void ProcessPanningEnvelope(ModChannel *pChn) const; void ProcessPitchFilterEnvelope(ModChannel *pChn, int &period) const; void IncrementEnvelopePosition(ModChannel *pChn, EnvelopeType envType) const; void IncrementEnvelopePositions(ModChannel *pChn) const; void ProcessInstrumentFade(ModChannel *pChn, int &vol) const; void ProcessPitchPanSeparation(ModChannel *pChn) const; void ProcessPanbrello(ModChannel *pChn) const; void ProcessArpeggio(CHANNELINDEX nChn, int &period, Tuning::NOTEINDEXTYPE &arpeggioSteps); void ProcessVibrato(CHANNELINDEX nChn, int &period, Tuning::RATIOTYPE &vibratoFactor); void ProcessSampleAutoVibrato(ModChannel *pChn, int &period, Tuning::RATIOTYPE &vibratoFactor, int &nPeriodFrac) const; void ProcessRamping(ModChannel *pChn) const; SamplePosition GetChannelIncrement(ModChannel *pChn, uint32 period, int periodFrac) const; protected: // Type of panning command enum PanningType { Pan4bit = 4, Pan6bit = 6, Pan8bit = 8, }; // Channel Effects void UpdateS3MEffectMemory(ModChannel *pChn, ModCommand::PARAM param) const; void PortamentoUp(CHANNELINDEX nChn, ModCommand::PARAM param, const bool doFinePortamentoAsRegular = false); void PortamentoDown(CHANNELINDEX nChn, ModCommand::PARAM param, const bool doFinePortamentoAsRegular = false); void MidiPortamento(CHANNELINDEX nChn, int param, bool doFineSlides); void FinePortamentoUp(ModChannel *pChn, ModCommand::PARAM param) const; void FinePortamentoDown(ModChannel *pChn, ModCommand::PARAM param) const; void ExtraFinePortamentoUp(ModChannel *pChn, ModCommand::PARAM param) const; void ExtraFinePortamentoDown(ModChannel *pChn, ModCommand::PARAM param) const; void PortamentoMPT(ModChannel*, int); void PortamentoFineMPT(ModChannel*, int); void PortamentoExtraFineMPT(ModChannel*, int); void NoteSlide(ModChannel *pChn, uint32 param, bool slideUp, bool retrig) const; void TonePortamento(ModChannel *pChn, uint32 param) const; void Vibrato(ModChannel *pChn, uint32 param) const; void FineVibrato(ModChannel *pChn, uint32 param) const; void VolumeSlide(ModChannel *pChn, ModCommand::PARAM param); void PanningSlide(ModChannel *pChn, ModCommand::PARAM param, bool memory = true); void ChannelVolSlide(ModChannel *pChn, ModCommand::PARAM param) const; void FineVolumeUp(ModChannel *pChn, ModCommand::PARAM param, bool volCol) const; void FineVolumeDown(ModChannel *pChn, ModCommand::PARAM param, bool volCol) const; void Tremolo(ModChannel *pChn, uint32 param) const; void Panbrello(ModChannel *pChn, uint32 param) const; void Panning(ModChannel *pChn, uint32 param, PanningType panBits) const; void RetrigNote(CHANNELINDEX nChn, int param, int offset = 0); void SampleOffset(ModChannel &chn, SmpLength param) const; void ReverseSampleOffset(ModChannel &chn, ModCommand::PARAM param) const; void NoteCut(CHANNELINDEX nChn, uint32 nTick, bool cutSample); ROWINDEX PatternLoop(ModChannel *, uint32 param); void ExtendedMODCommands(CHANNELINDEX nChn, ModCommand::PARAM param); void ExtendedS3MCommands(CHANNELINDEX nChn, ModCommand::PARAM param); void ExtendedChannelEffect(ModChannel *, uint32 param); void InvertLoop(ModChannel* pChn); ROWINDEX PatternBreak(PlayState &state, CHANNELINDEX chn, uint8 param) const; void GlobalVolSlide(ModCommand::PARAM param, uint8 &nOldGlobalVolSlide); void ProcessMacroOnChannel(CHANNELINDEX nChn); void ProcessMIDIMacro(CHANNELINDEX nChn, bool isSmooth, const char *macro, uint8 param = 0, PLUGINDEX plugin = 0); float CalculateSmoothParamChange(float currentValue, float param) const; uint32 SendMIDIData(CHANNELINDEX nChn, bool isSmooth, const unsigned char *macro, uint32 macroLen, PLUGINDEX plugin); void SendMIDINote(CHANNELINDEX chn, uint16 note, uint16 volume); void SetupChannelFilter(ModChannel *pChn, bool bReset, int flt_modifier = 256) const; // Low-Level effect processing void DoFreqSlide(ModChannel *pChn, int32 nFreqSlide) const; void UpdateTimeSignature(); public: // Convert frequency to IT cutoff (0...127) uint8 FrequencyToCutOff(double frequency) const; // Convert IT cutoff (0...127 + modifier) to frequency uint32 CutOffToFrequency(uint32 nCutOff, int flt_modifier = 256) const; // [0-127] => [1-10KHz] // Returns true if periods are actually plain frequency values in Hz. bool PeriodsAreFrequencies() const { return m_SongFlags[SONG_LINEARSLIDES] && m_playBehaviour[kHertzInLinearMode] && GetType() != MOD_TYPE_XM; } // Returns true if the current format uses transpose+finetune rather than frequency in Hz to specify middle-C. static constexpr bool UseFinetuneAndTranspose(MODTYPE type) { return (type & (MOD_TYPE_AMF0 | MOD_TYPE_DIGI | MOD_TYPE_MED | MOD_TYPE_MOD | MOD_TYPE_MTM | MOD_TYPE_OKT | MOD_TYPE_SFX | MOD_TYPE_STP | MOD_TYPE_XM)); } bool UseFinetuneAndTranspose() const { return UseFinetuneAndTranspose(GetType()); } public: uint32 GetNumTicksOnCurrentRow() const { return (m_PlayState.m_nMusicSpeed + m_PlayState.m_nFrameDelay) * std::max(m_PlayState.m_nPatternDelay, static_cast(1)); } bool DestroySample(SAMPLEINDEX nSample); bool DestroySampleThreadsafe(SAMPLEINDEX nSample); // Find an unused sample slot. If it is going to be assigned to an instrument, targetInstrument should be specified. // SAMPLEINDEX_INVLAID is returned if no free sample slot could be found. SAMPLEINDEX GetNextFreeSample(INSTRUMENTINDEX targetInstrument = INSTRUMENTINDEX_INVALID, SAMPLEINDEX start = 1) const; // Find an unused instrument slot. // INSTRUMENTINDEX_INVALID is returned if no free instrument slot could be found. INSTRUMENTINDEX GetNextFreeInstrument(INSTRUMENTINDEX start = 1) const; // Check whether a given sample is used by a given instrument. bool IsSampleReferencedByInstrument(SAMPLEINDEX sample, INSTRUMENTINDEX instr) const; ModInstrument *AllocateInstrument(INSTRUMENTINDEX instr, SAMPLEINDEX assignedSample = 0); bool DestroyInstrument(INSTRUMENTINDEX nInstr, deleteInstrumentSamples removeSamples); bool RemoveInstrumentSamples(INSTRUMENTINDEX nInstr, SAMPLEINDEX keepSample = SAMPLEINDEX_INVALID); SAMPLEINDEX DetectUnusedSamples(std::vector &sampleUsed) const; SAMPLEINDEX RemoveSelectedSamples(const std::vector &keepSamples); // Set the autovibrato settings for all samples associated to the given instrument. void PropagateXMAutoVibrato(INSTRUMENTINDEX ins, uint8 type, uint8 sweep, uint8 depth, uint8 rate); // Samples file I/O bool ReadSampleFromFile(SAMPLEINDEX nSample, FileReader &file, bool mayNormalize = false, bool includeInstrumentFormats = true); bool ReadWAVSample(SAMPLEINDEX nSample, FileReader &file, bool mayNormalize = false, FileReader *wsmpChunk = nullptr); bool ReadPATSample(SAMPLEINDEX nSample, FileReader &file); bool ReadS3ISample(SAMPLEINDEX nSample, FileReader &file); bool ReadAIFFSample(SAMPLEINDEX nSample, FileReader &file, bool mayNormalize = false); bool ReadAUSample(SAMPLEINDEX nSample, FileReader &file, bool mayNormalize = false); bool ReadXISample(SAMPLEINDEX nSample, FileReader &file); bool ReadITSSample(SAMPLEINDEX nSample, FileReader &file, bool rewind = true); bool ReadITISample(SAMPLEINDEX nSample, FileReader &file); bool ReadIFFSample(SAMPLEINDEX nInstr, FileReader &file); bool ReadFLACSample(SAMPLEINDEX sample, FileReader &file); bool ReadOpusSample(SAMPLEINDEX sample, FileReader &file); bool ReadVorbisSample(SAMPLEINDEX sample, FileReader &file); bool ReadMP3Sample(SAMPLEINDEX sample, FileReader &file, bool mo3Decode = false); bool ReadMediaFoundationSample(SAMPLEINDEX sample, FileReader &file, bool mo3Decode = false); #ifdef MODPLUG_TRACKER static std::vector GetMediaFoundationFileTypes(); #endif // MODPLUG_TRACKER #ifndef MODPLUG_NO_FILESAVE bool SaveWAVSample(SAMPLEINDEX nSample, const mpt::PathString &filename) const; bool SaveRAWSample(SAMPLEINDEX nSample, const mpt::PathString &filename) const; bool SaveFLACSample(SAMPLEINDEX nSample, const mpt::PathString &filename) const; #endif static bool CanReadMP3(); static bool CanReadVorbis(); static bool CanReadMediaFoundation(); // Instrument file I/O bool ReadInstrumentFromFile(INSTRUMENTINDEX nInstr, FileReader &file, bool mayNormalize=false); bool ReadXIInstrument(INSTRUMENTINDEX nInstr, FileReader &file); bool ReadITIInstrument(INSTRUMENTINDEX nInstr, FileReader &file); bool ReadPATInstrument(INSTRUMENTINDEX nInstr, FileReader &file); bool ReadSFZInstrument(INSTRUMENTINDEX nInstr, FileReader &file); bool ReadSampleAsInstrument(INSTRUMENTINDEX nInstr, FileReader &file, bool mayNormalize=false); #ifndef MODPLUG_NO_FILESAVE bool SaveXIInstrument(INSTRUMENTINDEX nInstr, const mpt::PathString &filename) const; bool SaveITIInstrument(INSTRUMENTINDEX nInstr, const mpt::PathString &filename, bool compress, bool allowExternal) const; #endif // I/O from another sound file bool ReadInstrumentFromSong(INSTRUMENTINDEX targetInstr, const CSoundFile &srcSong, INSTRUMENTINDEX sourceInstr); bool ReadSampleFromSong(SAMPLEINDEX targetSample, const CSoundFile &srcSong, SAMPLEINDEX sourceSample); // Period/Note functions uint32 GetNoteFromPeriod(uint32 period, int32 nFineTune = 0, uint32 nC5Speed = 0) const; uint32 GetPeriodFromNote(uint32 note, int32 nFineTune, uint32 nC5Speed) const; uint32 GetFreqFromPeriod(uint32 period, uint32 c5speed, int32 nPeriodFrac = 0) const; // Misc functions ModSample &GetSample(SAMPLEINDEX sample) { MPT_ASSERT(sample <= m_nSamples && sample < CountOf(Samples)); return Samples[sample]; } const ModSample &GetSample(SAMPLEINDEX sample) const { MPT_ASSERT(sample <= m_nSamples && sample < CountOf(Samples)); return Samples[sample]; } uint32 MapMidiInstrument(uint8 program, uint16 bank, uint8 midiChannel, uint8 note, bool isXG, std::bitset<16> drumChns); size_t ITInstrToMPT(FileReader &file, ModInstrument &ins, uint16 trkvers); void LoadMixPlugins(FileReader &file); #ifndef NO_PLUGINS static void ReadMixPluginChunk(FileReader &file, SNDMIXPLUGIN &plugin); void ProcessMidiOut(CHANNELINDEX nChn); #endif // NO_PLUGINS void ProcessGlobalVolume(long countChunk); void ProcessStereoSeparation(long countChunk); private: PLUGINDEX GetChannelPlugin(CHANNELINDEX nChn, PluginMutePriority respectMutes) const; PLUGINDEX GetActiveInstrumentPlugin(CHANNELINDEX, PluginMutePriority respectMutes) const; IMixPlugin *GetChannelInstrumentPlugin(CHANNELINDEX chn) const; void HandlePatternTransitionEvents(); public: PLUGINDEX GetBestPlugin(CHANNELINDEX nChn, PluginPriority priority, PluginMutePriority respectMutes) const; uint8 GetBestMidiChannel(CHANNELINDEX nChn) const; }; #ifndef NO_PLUGINS inline IMixPlugin* CSoundFile::GetInstrumentPlugin(INSTRUMENTINDEX instr) { if(instr > 0 && instr <= GetNumInstruments() && Instruments[instr] && Instruments[instr]->nMixPlug && Instruments[instr]->nMixPlug <= MAX_MIXPLUGINS) return m_MixPlugins[Instruments[instr]->nMixPlug - 1].pMixPlugin; else return nullptr; } #endif // NO_PLUGINS /////////////////////////////////////////////////////////// // Low-level Mixing functions #define SCRATCH_BUFFER_SIZE 64 //Used for plug's final processing (cleanup) #define FADESONGDELAY 100 #define MOD2XMFineTune(k) ((int)( (signed char)((k)<<4) )) #define XM2MODFineTune(k) ((int)( (k>>4)&0x0f )) // Read instrument property with 'code' and 'size' from 'file' to instrument 'pIns'. void ReadInstrumentExtensionField(ModInstrument* pIns, const uint32 code, const uint16 size, FileReader &file); // Read instrument property with 'code' from 'file' to instrument 'pIns'. void ReadExtendedInstrumentProperty(ModInstrument* pIns, const uint32 code, FileReader &file); // Read extended instrument properties from 'file' to instrument 'pIns'. void ReadExtendedInstrumentProperties(ModInstrument* pIns, FileReader &file); OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/UMXTools.h0000644000372100037210000000322713160657642017756 00000000000000/* * UMXTools.h * ------------ * Purpose: UMX/UAX (Unreal) helper functions * Notes : None. * Authors: Johannes Schultz (inspired by code from http://wiki.beyondunreal.com/Legacy:Package_File_Format) * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once OPENMPT_NAMESPACE_BEGIN // UMX File Header struct UMXFileHeader { char magic[4]; // C1 83 2A 9E uint16le packageVersion; uint16le licenseMode; uint32le flags; uint32le nameCount; uint32le nameOffset; uint32le exportCount; uint32le exportOffset; uint32le importCount; uint32le importOffset; }; MPT_BINARY_STRUCT(UMXFileHeader, 36) // Read compressed unreal integers - similar to MIDI integers, but signed values are possible. int32 ReadUMXIndex(FileReader &chunk); // Returns true if the given nme exists in the name table. bool FindUMXNameTableEntry(FileReader &file, const UMXFileHeader &fileHeader, const char *name); // Returns true if the given nme exists in the name table. bool FindUMXNameTableEntryMemory(MemoryFileReader &file, const UMXFileHeader &fileHeader, const char *name); // Read an entry from the name table. std::string ReadUMXNameTableEntry(FileReader &chunk, uint16 packageVersion); // Read complete name table. std::vector ReadUMXNameTable(FileReader &file, const UMXFileHeader &fileHeader); // Read an entry from the import table. int32 ReadUMXImportTableEntry(FileReader &chunk, uint16 packageVersion); // Read an entry from the export table. void ReadUMXExportTableEntry(FileReader &chunk, int32 &objClass, int32 &objOffset, int32 &objSize, int32 &objName, uint16 packageVersion); OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Load_mt2.cpp0000644000372100037210000007621113161656666020271 00000000000000/* * Load_mt2.cpp * ------------ * Purpose: MT2 (MadTracker 2) module loader * Notes : A couple of things are not handled properly or not at all, such as internal effects and automation envelopes * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" #ifdef MPT_EXTERNAL_SAMPLES // For loading external samples #include "../common/mptPathString.h" #endif // MPT_EXTERNAL_SAMPLES #ifndef NO_VST #include "../mptrack/Vstplug.h" #endif // NO_VST OPENMPT_NAMESPACE_BEGIN struct MT2FileHeader { enum MT2HeaderFlags { packedPatterns = 0x01, automation = 0x02, drumsAutomation = 0x08, masterAutomation = 0x10, }; char signature[4]; // "MT20" uint32le userID; uint16le version; char trackerName[32]; // "MadTracker 2.0" char songName[64]; uint16le numOrders; uint16le restartPos; uint16le numPatterns; uint16le numChannels; uint16le samplesPerTick; uint8le ticksPerLine; uint8le linesPerBeat; uint32le flags; // See HeaderFlags uint16le numInstruments; uint16le numSamples; }; MPT_BINARY_STRUCT(MT2FileHeader, 126) struct MT2DrumsData { uint16le numDrumPatterns; uint16le DrumSamples[8]; uint8le DrumPatternOrder[256]; }; MPT_BINARY_STRUCT(MT2DrumsData, 274) struct MT2TrackSettings { uint16le volume; uint8le trackfx; // Built-in effect type is used uint8le output; uint16le fxID; uint16le trackEffectParam[64][8]; }; MPT_BINARY_STRUCT(MT2TrackSettings, 1030) struct MT2Command { uint8 note; // 0=nothing, 97=note off uint8 instr; uint8 vol; uint8 pan; uint8 fxcmd; uint8 fxparam1; uint8 fxparam2; }; MPT_BINARY_STRUCT(MT2Command, 7) struct MT2EnvPoint { uint16le x; uint16le y; }; MPT_BINARY_STRUCT(MT2EnvPoint, 4) struct MT2Instrument { enum EnvTypes { VolumeEnv = 1, PanningEnv = 2, PitchEnv = 4, FilterEnv = 8, }; uint16le numSamples; uint8le groupMap[96]; uint8le vibtype, vibsweep, vibdepth, vibrate; uint16le fadeout; uint16le nna; }; MPT_BINARY_STRUCT(MT2Instrument, 106) struct MT2IEnvelope { uint8le flags; uint8le numPoints; uint8le sustainPos; uint8le loopStart; uint8le loopEnd; uint8le reserved[3]; MT2EnvPoint points[16]; }; MPT_BINARY_STRUCT(MT2IEnvelope, 72) // Note: The order of these fields differs a bit in MTIOModule_MT2.cpp - maybe just typos, I'm not sure. // This struct follows the save format of MadTracker 2.6.1. struct MT2InstrSynth { uint8le synthID; uint8le effectID; // 0 = Lowpass filter, 1 = Highpass filter uint16le cutoff; // 100...11000 Hz uint8le resonance; // 0...128 uint8le attack; // 0...128 uint8le decay; // 0...128 uint8le midiChannel; // 0...15 int8le device; // VST slot (positive) or MIDI device (negative) int8le unknown1; // Missing in MTIOModule_MT2.cpp uint8le volume; // 0...255 int8le finetune; // -96...96 int8le transpose; // -48...48 uint8le unknown2; // Seems to be equal to instrument number. uint8le unknown3; uint8le midiProgram; uint8le reserved[16]; }; MPT_BINARY_STRUCT(MT2InstrSynth, 32) struct MT2Sample { uint32le length; uint32le frequency; uint8le depth; uint8le channels; uint8le flags; uint8le loopType; uint32le loopStart; uint32le loopEnd; uint16le volume; int8le panning; int8le note; int16le spb; }; MPT_BINARY_STRUCT(MT2Sample, 26) struct MT2Group { uint8le sample; uint8le vol; // 0...128 int8le pitch; // -128...127 uint8le reserved[5]; }; MPT_BINARY_STRUCT(MT2Group, 8) struct MT2VST { char dll[64]; char programName[28]; uint32le fxID; uint32le fxVersion; uint32le programNr; uint8le useChunks; uint8le track; int8le pan; // Not imported - could use pan mix mode for D/W ratio, but this is not implemented for instrument plugins! char reserved[17]; uint32le n; }; MPT_BINARY_STRUCT(MT2VST, 128) static bool ConvertMT2Command(CSoundFile *that, ModCommand &m, MT2Command &p) { bool hasLegacyTempo = false; // Note m.note = NOTE_NONE; if(p.note) m.note = (p.note > 96) ? NOTE_KEYOFF : (p.note + NOTE_MIN + 11); // Instrument m.instr = p.instr; // Volume Column if(p.vol >= 0x10 && p.vol <= 0x90) { m.volcmd = VOLCMD_VOLUME; m.vol = (p.vol - 0x10) / 2; } else if(p.vol >= 0xA0 && p.vol <= 0xAF) { m.volcmd = VOLCMD_VOLSLIDEDOWN; m.vol = (p.vol & 0x0F); } else if(p.vol >= 0xB0 && p.vol <= 0xBF) { m.volcmd = VOLCMD_VOLSLIDEUP; m.vol = (p.vol & 0x0F); } else if(p.vol >= 0xC0 && p.vol <= 0xCF) { m.volcmd = VOLCMD_FINEVOLDOWN; m.vol = (p.vol & 0x0F); } else if(p.vol >= 0xD0 && p.vol <= 0xDF) { m.volcmd = VOLCMD_FINEVOLUP; m.vol = (p.vol & 0x0F); } // Effects if(p.fxcmd || p.fxparam1 || p.fxparam2) { switch(p.fxcmd) { case 0x00: // FastTracker effect m.command = p.fxparam2; m.param = p.fxparam1; CSoundFile::ConvertModCommand(m); #ifdef MODPLUG_TRACKER m.Convert(MOD_TYPE_XM, MOD_TYPE_IT, *that); #else MPT_UNREFERENCED_PARAMETER(that); #endif // MODPLUG_TRACKER if(p.fxparam2 == 0x0F) hasLegacyTempo = true; break; case 0x01: // Portamento up (on every tick) m.command = CMD_PORTAMENTOUP; m.param = mpt::saturate_cast((p.fxparam2 << 4) | (p.fxparam1 >> 4)); break; case 0x02: // Portamento down (on every tick) m.command = CMD_PORTAMENTODOWN; m.param = mpt::saturate_cast((p.fxparam2 << 4) | (p.fxparam1 >> 4)); break; case 0x03: // Tone Portamento (on every tick) m.command = CMD_TONEPORTAMENTO; m.param = mpt::saturate_cast((p.fxparam2 << 4) | (p.fxparam1 >> 4)); break; case 0x04: // Vibrato m.command = CMD_VIBRATO; m.param = (p.fxparam2 & 0xF0) | (p.fxparam1 >> 4); break; case 0x08: // Panning + Polarity (we can only import panning for now) if(p.fxparam1) { m.command = CMD_PANNING8; m.param = p.fxparam1; } else if(p.fxparam2 == 1 || p.fxparam2 == 2) { // Invert left or right channel m.command = CMD_S3MCMDEX; m.param = 0x91; } break; case 0x0C: // Set volume (0x80 = 100%) m.command = CMD_VOLUME; m.param = p.fxparam2 / 2; break; case 0x0F: // Set tempo, LPB and ticks (we can only import tempo for now) if(p.fxparam2 != 0) { m.command = CMD_TEMPO; m.param = p.fxparam2; } else { m.command = CMD_SPEED; m.param = (p.fxparam1 & 0x0F); } break; case 0x10: // Impulse Tracker effect m.command = p.fxparam2; m.param = p.fxparam1; CSoundFile::S3MConvert(m, true); if(m.command == CMD_TEMPO || m.command == CMD_SPEED) hasLegacyTempo = true; break; case 0x1D: // Gapper (like IT Tremor with old FX, i.e. 1D 00 XY = ontime X + 1 ticks, offtime Y + 1 ticks) m.command = CMD_TREMOR; m.param = p.fxparam1; break; case 0x20: // Cutoff + Resonance (we can only import cutoff for now) m.command = CMD_MIDI; m.param = p.fxparam2 >> 1; break; case 0x22: // Cutoff + Resonance + Attack + Decay (we can only import cutoff for now) m.command = CMD_MIDI; m.param = (p.fxparam2 & 0xF0) >> 1; break; case 0x24: // Reverse m.command = CMD_S3MCMDEX; m.param = 0x9F; break; case 0x80: // Track volume m.command = CMD_CHANNELVOLUME; m.param = p.fxparam2 / 4u; break; case 0x9D: // Offset + delay m.volcmd = VOLCMD_OFFSET; m.vol = p.fxparam2 >> 3; m.command = CMD_S3MCMDEX; m.param = 0xD0 | std::min(p.fxparam1, uint8(0x0F)); break; case 0xCC: // MIDI CC //m.command = CMD_MIDI; break; // TODO: More MT2 Effects } } if(p.pan) { if(m.command == CMD_NONE) { m.command = CMD_PANNING8; m.param = p.pan; } else if(m.volcmd == VOLCMD_NONE) { m.volcmd = VOLCMD_PANNING; m.vol = p.pan / 4; } } return hasLegacyTempo; } // This doesn't really do anything but skipping the envelope chunk at the moment. static void ReadMT2Automation(uint16 version, FileReader &file) { uint32 flags; uint32 trkfxid; if(version >= 0x203) { flags = file.ReadUint32LE(); trkfxid = file.ReadUint32LE(); } else { flags = file.ReadUint16LE(); trkfxid = file.ReadUint16LE(); } MPT_UNREFERENCED_PARAMETER(trkfxid); while(flags != 0) { if(flags & 1) { file.Skip(4 + sizeof(MT2EnvPoint) * 64); } flags >>= 1; } } static bool ValidateHeader(const MT2FileHeader &fileHeader) { if(std::memcmp(fileHeader.signature, "MT20", 4) || fileHeader.version < 0x200 || fileHeader.version >= 0x300 || fileHeader.numChannels < 1 || fileHeader.numChannels > 64 || fileHeader.numOrders > 256 || fileHeader.numInstruments >= MAX_INSTRUMENTS || fileHeader.numSamples >= MAX_SAMPLES ) { return false; } return true; } static uint64 GetHeaderMinimumAdditionalSize(const MT2FileHeader &fileHeader) { MPT_UNREFERENCED_PARAMETER(fileHeader); return 256; } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderMT2(MemoryFileReader file, const uint64 *pfilesize) { MT2FileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return ProbeWantMoreData; } if(!ValidateHeader(fileHeader)) { return ProbeFailure; } return ProbeAdditionalSize(file, pfilesize, GetHeaderMinimumAdditionalSize(fileHeader)); } bool CSoundFile::ReadMT2(FileReader &file, ModLoadingFlags loadFlags) { file.Rewind(); MT2FileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return false; } if(!ValidateHeader(fileHeader)) { return false; } if(!file.CanRead(mpt::saturate_cast(GetHeaderMinimumAdditionalSize(fileHeader)))) { return false; } if(loadFlags == onlyVerifyHeader) { return true; } InitializeGlobals(MOD_TYPE_MT2); InitializeChannels(); mpt::String::Read(m_madeWithTracker, mpt::CharsetWindows1252, fileHeader.trackerName); mpt::String::Read(m_songName, fileHeader.songName); m_nChannels = fileHeader.numChannels; m_nDefaultSpeed = Clamp(fileHeader.ticksPerLine, 1, 31); m_nDefaultTempo.Set(125); m_SongFlags = SONG_LINEARSLIDES | SONG_ITCOMPATGXX | SONG_EXFILTERRANGE; m_nInstruments = fileHeader.numInstruments; m_nSamples = fileHeader.numSamples; m_nDefaultRowsPerBeat = Clamp(fileHeader.linesPerBeat, 1, 32); m_nDefaultRowsPerMeasure = m_nDefaultRowsPerBeat * 4; m_nVSTiVolume = 48; m_nSamplePreAmp = 48 * 2; // Double pre-amp because we will halve the volume of all non-drum instruments, because the volume of drum samples can exceed that of normal samples uint8 orders[256]; file.ReadArray(orders); ReadOrderFromArray(Order(), orders, fileHeader.numOrders); Order().SetRestartPos(fileHeader.restartPos); FileReader drumData = file.ReadChunk(file.ReadUint16LE()); FileReader extraData = file.ReadChunk(file.ReadUint32LE()); const CHANNELINDEX channelsWithoutDrums = m_nChannels; const bool hasDrumChannels = drumData.CanRead(sizeof(MT2DrumsData)); STATIC_ASSERT(MAX_BASECHANNELS >= 64 + 8); if(hasDrumChannels) { m_nChannels += 8; } bool hasLegacyTempo = false; // Read patterns if(loadFlags & loadPatternData) Patterns.ResizeArray(fileHeader.numPatterns); for(PATTERNINDEX pat = 0; pat < fileHeader.numPatterns; pat++) { ROWINDEX numRows = file.ReadUint16LE(); FileReader chunk = file.ReadChunk((file.ReadUint32LE() + 1) & ~1); LimitMax(numRows, MAX_PATTERN_ROWS); if(!numRows || !(loadFlags & loadPatternData) || !Patterns.Insert(pat, numRows)) { continue; } if(fileHeader.flags & MT2FileHeader::packedPatterns) { ROWINDEX row = 0; CHANNELINDEX chn = 0; while(chunk.CanRead(1)) { MT2Command cmd; uint8 infobyte = chunk.ReadUint8(); uint8 repeatCount = 0; if(infobyte == 0xFF) { repeatCount = chunk.ReadUint8(); infobyte = chunk.ReadUint8(); } if(infobyte & 0x7F) { ModCommand *m = Patterns[pat].GetpModCommand(row, chn); MemsetZero(cmd); if(infobyte & 0x01) cmd.note = chunk.ReadUint8(); if(infobyte & 0x02) cmd.instr = chunk.ReadUint8(); if(infobyte & 0x04) cmd.vol = chunk.ReadUint8(); if(infobyte & 0x08) cmd.pan = chunk.ReadUint8(); if(infobyte & 0x10) cmd.fxcmd = chunk.ReadUint8(); if(infobyte & 0x20) cmd.fxparam1 = chunk.ReadUint8(); if(infobyte & 0x40) cmd.fxparam2 = chunk.ReadUint8(); hasLegacyTempo |= ConvertMT2Command(this, *m, cmd); const ModCommand &orig = *m; const ROWINDEX fillRows = std::min((uint32)repeatCount, (uint32)numRows - (row + 1)); for(ROWINDEX r = 0; r < fillRows; r++) { m += GetNumChannels(); *m = orig; } } row += repeatCount + 1; while(row >= numRows) { row -= numRows; chn++; } if(chn >= channelsWithoutDrums) break; } } else { for(ROWINDEX row = 0; row < numRows; row++) { ModCommand *m = Patterns[pat].GetRow(row); for(CHANNELINDEX chn = 0; chn < channelsWithoutDrums; chn++, m++) { MT2Command cmd; chunk.ReadStruct(cmd); hasLegacyTempo |= ConvertMT2Command(this, *m, cmd); } } } } if(fileHeader.samplesPerTick > 1 && fileHeader.samplesPerTick < 5000) { if(hasLegacyTempo) { m_nDefaultTempo.SetRaw(Util::muldivr(110250, TEMPO::fractFact, fileHeader.samplesPerTick)); m_nTempoMode = tempoModeClassic; } else { m_nDefaultTempo = TEMPO(44100.0 * 60.0 / (m_nDefaultSpeed * m_nDefaultRowsPerBeat * fileHeader.samplesPerTick)); m_nTempoMode = tempoModeModern; } } // Read extra data uint32 numVST = 0; std::vector trackRouting(GetNumChannels(), 0); while(extraData.CanRead(8)) { uint32 id = extraData.ReadUint32LE(); FileReader chunk = extraData.ReadChunk(extraData.ReadUint32LE()); switch(id) { case MAGIC4LE('B','P','M','+'): if(!hasLegacyTempo) { m_nTempoMode = tempoModeModern; double d = chunk.ReadDoubleLE(); if(d != 0.0) { m_nDefaultTempo = TEMPO(44100.0 * 60.0 / (m_nDefaultSpeed * m_nDefaultRowsPerBeat * d)); } } break; case MAGIC4LE('T','F','X','M'): break; case MAGIC4LE('T','R','K','O'): break; case MAGIC4LE('T','R','K','S'): m_nSamplePreAmp = chunk.ReadUint16LE() / 256u; // 131072 is 0dB... I think (that's how MTIOModule_MT2.cpp reads) m_nVSTiVolume = m_nSamplePreAmp / 2u; for(CHANNELINDEX c = 0; c < GetNumChannels(); c++) { MT2TrackSettings trackSettings; if(chunk.ReadStruct(trackSettings)) { ChnSettings[c].nVolume = trackSettings.volume >> 10; // 32768 is 0dB trackRouting[c] = trackSettings.output; LimitMax(ChnSettings[c].nVolume, uint16(64)); } } break; case MAGIC4LE('T','R','K','L'): for(CHANNELINDEX i = 0; i < m_nChannels && chunk.CanRead(1); i++) { std::string name; chunk.ReadNullString(name); mpt::String::Read(ChnSettings[i].szName, name.c_str(), name.length()); } break; case MAGIC4LE('P','A','T','N'): for(PATTERNINDEX i = 0; i < fileHeader.numPatterns && chunk.CanRead(1) && Patterns.IsValidIndex(i); i++) { std::string name; chunk.ReadNullString(name); Patterns[i].SetName(name); } break; case MAGIC4LE('M','S','G','\0'): chunk.Skip(1); // Show message on startup m_songMessage.Read(chunk, chunk.BytesLeft(), SongMessage::leCRLF); break; case MAGIC4LE('P','I','C','T'): break; case MAGIC4LE('S','U','M','\0'): { uint8 summaryMask[6]; chunk.ReadArray(summaryMask); std::string artist; chunk.ReadNullString(artist); if(artist != "Unregistered") { m_songArtist = mpt::ToUnicode(mpt::CharsetWindows1252, artist); } } break; case MAGIC4LE('T','M','A','P'): break; case MAGIC4LE('M','I','D','I'): break; case MAGIC4LE('T','R','E','Q'): break; case MAGIC4LE('V','S','T','2'): numVST = chunk.ReadUint32LE(); #ifndef NO_VST if(!(loadFlags & loadPluginData)) { break; } for(uint32 i = 0; i < std::min(numVST, uint32(MAX_MIXPLUGINS)); i++) { MT2VST vstHeader; if(chunk.ReadStruct(vstHeader)) { if(fileHeader.version >= 0x0250) chunk.Skip(16 * 4); // Parameter automation map for 16 parameters SNDMIXPLUGIN &mixPlug = m_MixPlugins[i]; mixPlug.Destroy(); mpt::String::Read(mixPlug.Info.szLibraryName, vstHeader.dll); mpt::String::Read(mixPlug.Info.szName, vstHeader.programName); const size_t len = strlen(mixPlug.Info.szLibraryName); if(len > 4 && mixPlug.Info.szLibraryName[len - 4] == '.') { // Remove ".dll" from library name mixPlug.Info.szLibraryName[len - 4] = '\0'; } mixPlug.Info.dwPluginId1 = kEffectMagic; mixPlug.Info.dwPluginId2 = vstHeader.fxID; if(vstHeader.track >= m_nChannels) { mixPlug.SetMasterEffect(true); } else { if(!ChnSettings[vstHeader.track].nMixPlugin) { ChnSettings[vstHeader.track].nMixPlugin = static_cast(i + 1); } else { // Channel already has plugin assignment - chain the plugins PLUGINDEX outPlug = ChnSettings[vstHeader.track].nMixPlugin - 1; while(true) { if(m_MixPlugins[outPlug].GetOutputPlugin() == PLUGINDEX_INVALID) { m_MixPlugins[outPlug].SetOutputPlugin(static_cast(i)); break; } outPlug = m_MixPlugins[outPlug].GetOutputPlugin(); } } } // Read plugin settings uint32 dataSize; if(vstHeader.useChunks) { // MT2 only ever calls effGetChunk for programs, and OpenMPT uses the defaultProgram value to determine // whether it should use effSetChunk for programs or banks... mixPlug.defaultProgram = -1; LimitMax(vstHeader.n, Util::MaxValueOfType(dataSize) - 4); dataSize = vstHeader.n + 4; } else { mixPlug.defaultProgram = vstHeader.programNr; LimitMax(vstHeader.n, (Util::MaxValueOfType(dataSize) / 4u) - 1); dataSize = vstHeader.n * 4 + 4; } mixPlug.pluginData.resize(dataSize); if(vstHeader.useChunks) { memcpy(mixPlug.pluginData.data(), "fEvN", 4); // 'NvEf' plugin data type chunk.ReadRaw(mixPlug.pluginData.data() + 4, vstHeader.n); } else { float32 *f = reinterpret_cast(mixPlug.pluginData.data()); *(f++) = 0; // Plugin data type for(uint32 param = 0; param < vstHeader.n; param++, f++) { *f = chunk.ReadFloatLE(); } } } else { break; } } #endif // NO_VST break; } } #ifndef NO_PLUGINS // Now that we have both the track settings and plugins, establish the track routing by applying the same plugins to the source track as to the target track: for(CHANNELINDEX c = 0; c < GetNumChannels(); c++) { int8 outTrack = trackRouting[c]; if(outTrack > c && outTrack < GetNumChannels() && ChnSettings[outTrack].nMixPlugin != 0) { if(ChnSettings[c].nMixPlugin == 0) { ChnSettings[c].nMixPlugin = ChnSettings[outTrack].nMixPlugin; } else { PLUGINDEX outPlug = ChnSettings[c].nMixPlugin - 1; for(;;) { if(m_MixPlugins[outPlug].GetOutputPlugin() == PLUGINDEX_INVALID) { m_MixPlugins[outPlug].SetOutputPlugin(ChnSettings[outTrack].nMixPlugin - 1); break; } outPlug = m_MixPlugins[outPlug].GetOutputPlugin(); } } } } #endif // NO_PLUGINS // Read drum channels INSTRUMENTINDEX drumMap[8] = { 0 }; uint16 drumSample[8] = { 0 }; if(hasDrumChannels) { MT2DrumsData drumHeader; drumData.ReadStruct(drumHeader); // Allocate some instruments to handle the drum samples for(INSTRUMENTINDEX i = 0; i < 8; i++) { drumMap[i] = GetNextFreeInstrument(m_nInstruments + 1); drumSample[i] = drumHeader.DrumSamples[i]; if(drumMap[i] != INSTRUMENTINDEX_INVALID) { ModInstrument *mptIns = AllocateInstrument(drumMap[i], drumHeader.DrumSamples[i] + 1); if(mptIns != nullptr) { strcpy(mptIns->name, "Drum #x"); mptIns->name[6] = '1' + char(i); } } else { drumMap[i] = 0; } } // Get all the drum pattern chunks std::vector patternChunks(drumHeader.numDrumPatterns); for(uint32 pat = 0; pat < drumHeader.numDrumPatterns; pat++) { uint16 numRows = file.ReadUint16LE(); patternChunks[pat] = file.ReadChunk(numRows * 32); } std::vector patMapping(fileHeader.numPatterns, PATTERNINDEX_INVALID); for(uint32 ord = 0; ord < fileHeader.numOrders; ord++) { if(drumHeader.DrumPatternOrder[ord] >= drumHeader.numDrumPatterns || Order()[ord] >= fileHeader.numPatterns) continue; // Figure out where to write this drum pattern PATTERNINDEX writePat = Order()[ord]; if(patMapping[writePat] == PATTERNINDEX_INVALID) { patMapping[writePat] = drumHeader.DrumPatternOrder[ord]; } else if(patMapping[writePat] != drumHeader.DrumPatternOrder[ord]) { // Damn, this pattern has previously used a different drum pattern. Duplicate it... PATTERNINDEX newPat = Patterns.Duplicate(writePat); if(newPat != PATTERNINDEX_INVALID) { writePat = newPat; Order()[ord] = writePat; } } if(!Patterns.IsValidPat(writePat)) continue; FileReader &chunk = patternChunks[drumHeader.DrumPatternOrder[ord]]; chunk.Rewind(); const ROWINDEX numRows = static_cast(chunk.GetLength() / 32u); for(ROWINDEX row = 0; row < Patterns[writePat].GetNumRows(); row++) { ModCommand *m = Patterns[writePat].GetpModCommand(row, m_nChannels - 8); for(CHANNELINDEX chn = 0; chn < 8; chn++, m++) { *m = ModCommand::Empty(); if(row >= numRows) continue; uint8 drums[4]; chunk.ReadArray(drums); if(drums[0] & 0x80) { m->note = NOTE_MIDDLEC; m->instr = static_cast(drumMap[chn]); uint8 delay = drums[0] & 0x1F; if(delay) { LimitMax(delay, uint8(0x0F)); m->command = CMD_S3MCMDEX; m->param = 0xD0 | delay; } m->volcmd = VOLCMD_VOLUME; // Volume is 0...255, but 128 is equivalent to v64 - we compensate this by halving the global volume of all non-drum instruments m->vol = static_cast((static_cast(drums[1]) + 3) / 4u); } } } } } // Read automation envelopes if(fileHeader.flags & MT2FileHeader::automation) { const uint32 numEnvelopes = ((fileHeader.flags & MT2FileHeader::drumsAutomation) ? m_nChannels : channelsWithoutDrums) + ((fileHeader.version >= 0x0250) ? numVST : 0) + ((fileHeader.flags & MT2FileHeader::masterAutomation) ? 1 : 0); for(uint32 pat = 0; pat < fileHeader.numPatterns; pat++) { for(uint32 env = 0; env < numEnvelopes && file.CanRead(4); env++) { // TODO ReadMT2Automation(fileHeader.version, file); } } } // Read instruments std::vector instrChunks(255); for(INSTRUMENTINDEX i = 0; i < 255; i++) { char instrName[32]; file.ReadArray(instrName); uint32 dataLength = file.ReadUint32LE(); if(dataLength == 32) dataLength += 108 + sizeof(MT2IEnvelope) * 4; if(fileHeader.version > 0x0201 && dataLength) dataLength += 4; FileReader instrChunk = instrChunks[i] = file.ReadChunk(dataLength); ModInstrument *mptIns = nullptr; if(i < fileHeader.numInstruments) { // Default sample assignment if there is no data chunk? Fixes e.g. instrument 33 in Destiny - Dream Alone.mt2 mptIns = AllocateInstrument(i + 1, i + 1); } if(mptIns == nullptr) continue; mpt::String::Read(mptIns->name, instrName); if(!dataLength) continue; MT2Instrument insHeader; instrChunk.ReadStruct(insHeader); uint16 flags = 0; if(fileHeader.version >= 0x0201) flags = instrChunk.ReadUint16LE(); uint32 envMask = MT2Instrument::VolumeEnv | MT2Instrument::PanningEnv; if(fileHeader.version >= 0x0202) envMask = instrChunk.ReadUint32LE(); mptIns->nFadeOut = insHeader.fadeout; const uint8 NNA[4] = { NNA_NOTECUT, NNA_CONTINUE, NNA_NOTEOFF, NNA_NOTEFADE }; const uint8 DCT[4] = { DCT_NONE, DCT_NOTE, DCT_SAMPLE, DCT_INSTRUMENT }; const uint8 DNA[4] = { DNA_NOTECUT, DNA_NOTEFADE /* actually continue, but IT doesn't have that */, DNA_NOTEOFF, DNA_NOTEFADE }; mptIns->nNNA = NNA[insHeader.nna & 3]; mptIns->nDCT = DCT[(insHeader.nna >> 8) & 3]; mptIns->nDNA = DNA[(insHeader.nna >> 12) & 3]; // Load envelopes for(uint32 env = 0; env < 4; env++) { if(envMask & 1) { MT2IEnvelope mt2Env; instrChunk.ReadStruct(mt2Env); const EnvelopeType envType[4] = { ENV_VOLUME, ENV_PANNING, ENV_PITCH, ENV_PITCH }; InstrumentEnvelope &mptEnv = mptIns->GetEnvelope(envType[env]); mptEnv.dwFlags.set(ENV_FILTER, (env == 3) && (mt2Env.flags & 1) != 0); mptEnv.dwFlags.set(ENV_ENABLED, (mt2Env.flags & 1) != 0); mptEnv.dwFlags.set(ENV_SUSTAIN, (mt2Env.flags & 2) != 0); mptEnv.dwFlags.set(ENV_LOOP, (mt2Env.flags & 4) != 0); mptEnv.resize(std::min(mt2Env.numPoints, 16)); mptEnv.nSustainStart = mptEnv.nSustainEnd = mt2Env.sustainPos; mptEnv.nLoopStart = mt2Env.loopStart; mptEnv.nLoopEnd = mt2Env.loopEnd; for(uint32 p = 0; p < mptEnv.size(); p++) { mptEnv[p].tick = mt2Env.points[p].x; mptEnv[p].value = static_cast(Clamp(mt2Env.points[p].y, 0, 64)); } } envMask >>= 1; } if(!mptIns->VolEnv.dwFlags[ENV_ENABLED] && mptIns->nNNA != NNA_NOTEFADE) { mptIns->nFadeOut = int16_max; } mptIns->SetCutoff(0x7F, true); mptIns->SetResonance(0, true); if(flags) { MT2InstrSynth synthData; instrChunk.ReadStruct(synthData); if(flags & 2) { mptIns->SetCutoff(FrequencyToCutOff(synthData.cutoff), true); mptIns->SetResonance(synthData.resonance, true); } mptIns->nFilterMode = synthData.effectID == 1 ? FLTMODE_HIGHPASS : FLTMODE_LOWPASS; if(flags & 4) { // VSTi / MIDI synth enabled mptIns->nMidiChannel = synthData.midiChannel + 1; mptIns->nMixPlug = static_cast(synthData.device + 1); if(synthData.device < 0) { // TODO: This is a MIDI device - maybe use MIDI I/O plugin to emulate those? mptIns->nMidiProgram = synthData.midiProgram + 1; // MT2 only seems to use this for MIDI devices, not VSTis! } if(synthData.transpose) { for(uint32 n = 0; n < CountOf(mptIns->NoteMap); n++) { int note = NOTE_MIN + n + synthData.transpose; Limit(note, NOTE_MIN, NOTE_MAX); mptIns->NoteMap[n] = static_cast(note); } } // Instruments with plugin assignments never play samples at the same time! mptIns->AssignSample(0); } } } // Read sample headers std::bitset<256> sampleNoInterpolation; std::bitset<256> sampleSynchronized; for(SAMPLEINDEX i = 0; i < 256; i++) { char sampleName[32]; file.ReadArray(sampleName); uint32 dataLength = file.ReadUint32LE(); FileReader sampleChunk = file.ReadChunk(dataLength); if(i < fileHeader.numSamples) { mpt::String::Read(m_szNames[i + 1], sampleName); } if(dataLength && i < fileHeader.numSamples) { ModSample &mptSmp = Samples[i + 1]; mptSmp.Initialize(MOD_TYPE_IT); MT2Sample sampleHeader; sampleChunk.ReadStruct(sampleHeader); mptSmp.nLength = sampleHeader.length; mptSmp.nC5Speed = sampleHeader.frequency; if(sampleHeader.depth > 1) { mptSmp.uFlags.set(CHN_16BIT); mptSmp.nLength /= 2u; } if(sampleHeader.channels > 1) { mptSmp.uFlags.set(CHN_STEREO); mptSmp.nLength /= 2u; } if(sampleHeader.loopType == 1) mptSmp.uFlags.set(CHN_LOOP); else if(sampleHeader.loopType == 2) mptSmp.uFlags.set(CHN_LOOP | CHN_PINGPONGLOOP); mptSmp.nLoopStart = sampleHeader.loopStart; mptSmp.nLoopEnd = sampleHeader.loopEnd; mptSmp.nVolume = sampleHeader.volume >> 7; if(sampleHeader.panning == -128) mptSmp.uFlags.set(CHN_SURROUND); else mptSmp.nPan = sampleHeader.panning + 128; mptSmp.uFlags.set(CHN_PANNING); mptSmp.RelativeTone = sampleHeader.note; if(sampleHeader.flags & 2) { // Sample is synchronized to beat // The synchronization part is not supported in OpenMPT, but synchronized samples also always play at the same pitch as C-5, which we CAN do! sampleSynchronized[i] = true; //mptSmp.nC5Speed = Util::muldiv(mptSmp.nC5Speed, sampleHeader.spb, 22050); } if(sampleHeader.flags & 5) { // External sample mptSmp.uFlags.set(SMP_KEEPONDISK); } if(sampleHeader.flags & 8) { sampleNoInterpolation[i] = true; for(INSTRUMENTINDEX drum = 0; drum < 8; drum++) { if(drumSample[drum] == i && Instruments[drumMap[drum]] != nullptr) { Instruments[drumMap[drum]]->nResampling = SRCMODE_NEAREST; } } } } } // Read sample groups for(INSTRUMENTINDEX ins = 0; ins < fileHeader.numInstruments; ins++) { if(instrChunks[ins].GetLength()) { FileReader &chunk = instrChunks[ins]; MT2Instrument insHeader; chunk.Rewind(); chunk.ReadStruct(insHeader); std::vector groups; file.ReadVector(groups, insHeader.numSamples); ModInstrument *mptIns = Instruments[ins + 1]; // Instruments with plugin assignments never play samples at the same time! if(mptIns == nullptr || mptIns->nMixPlug != 0) continue; mptIns->nGlobalVol = 32; // Compensate for extended dynamic range of drum instruments mptIns->AssignSample(0); for(uint32 note = 0; note < 96; note++) { if(insHeader.groupMap[note] < insHeader.numSamples) { const MT2Group &group = groups[insHeader.groupMap[note]]; SAMPLEINDEX sample = group.sample + 1; mptIns->Keyboard[note + 11 + NOTE_MIN] = sample; if(sample > 0 && sample <= m_nSamples) { ModSample &mptSmp = Samples[sample]; mptSmp.nVibType = insHeader.vibtype; mptSmp.nVibSweep = insHeader.vibsweep; mptSmp.nVibDepth = insHeader.vibdepth; mptSmp.nVibRate = insHeader.vibrate; mptSmp.nGlobalVol = uint16(group.vol) * 2; mptSmp.nFineTune = group.pitch; if(sampleNoInterpolation[sample - 1]) { mptIns->nResampling = SRCMODE_NEAREST; } if(sampleSynchronized[sample - 1]) { mptIns->NoteMap[note + 11 + NOTE_MIN] = NOTE_MIDDLEC; } } // TODO: volume, finetune for duplicated samples } } } } if(!(loadFlags & loadSampleData)) return true; // Read sample data for(SAMPLEINDEX i = 0; i < m_nSamples; i++) { ModSample &mptSmp = Samples[i + 1]; mptSmp.Transpose(-(mptSmp.RelativeTone - 49 - (mptSmp.nFineTune / 128.0)) / 12.0); mptSmp.nFineTune = 0; mptSmp.RelativeTone = 0; if(!mptSmp.uFlags[SMP_KEEPONDISK]) { SampleIO( mptSmp.uFlags[CHN_16BIT] ? SampleIO::_16bit : SampleIO::_8bit, mptSmp.uFlags[CHN_STEREO] ? SampleIO::stereoSplit : SampleIO::mono, SampleIO::littleEndian, SampleIO::MT2) .ReadSample(mptSmp, file); } else { // External sample const uint32 filenameSize = file.ReadUint32LE(); file.Skip(12); // Reserved std::string filename; file.ReadString(filename, filenameSize); mpt::String::Copy(mptSmp.filename, filename); #if defined(MPT_EXTERNAL_SAMPLES) if(filename.length() >= 2 && filename.at(0) != '\\' // Relative path on same drive && filename.at(1) != ':') // Absolute path { // Relative path in same folder or sub folder filename = ".\\" + filename; } SetSamplePath(i + 1, mpt::PathString::FromLocaleSilent(filename)); #elif !defined(LIBOPENMPT_BUILD_TEST) AddToLog(LogWarning, mpt::format(MPT_USTRING("Loading external sample %1 ('%2') failed: External samples are not supported."))(i, mpt::ToUnicode(GetCharsetFile(), filename))); #endif // MPT_EXTERNAL_SAMPLES } } return true; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/ModSequence.cpp0000644000372100037210000004212313161656666021033 00000000000000/* * ModSequence.cpp * --------------- * Purpose: Order and sequence handling. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "ModSequence.h" #include "Sndfile.h" #include "mod_specifications.h" #ifdef MODPLUG_TRACKER #include "../mptrack/Reporting.h" #endif // MODPLUG_TRACKER #include "../common/version.h" #include "../common/serialization_utils.h" OPENMPT_NAMESPACE_BEGIN #define str_SequenceTruncationNote ("Module has sequence of length %1; it will be truncated to maximum supported length, %2.") ModSequence::ModSequence(CSoundFile &sndFile) : m_sndFile(sndFile) , m_restartPos(0) { } ModSequence& ModSequence::operator=(const ModSequence &other) { if(&other == this) return *this; std::vector::assign(other.begin(), other.end()); m_name = other.m_name; m_restartPos = other.m_restartPos; return *this; } bool ModSequence::operator== (const ModSequence &other) const { return static_cast &>(*this) == other && m_name == other.m_name && m_restartPos == other.m_restartPos; } bool ModSequence::NeedsExtraDatafield() const { return (m_sndFile.GetType() == MOD_TYPE_MPT && m_sndFile.Patterns.GetNumPatterns() > 0xFD); } void ModSequence::AdjustToNewModType(const MODTYPE oldtype) { auto &specs = m_sndFile.GetModSpecifications(); if(oldtype != MOD_TYPE_NONE) { // If not supported, remove "+++" separator order items. if(!specs.hasIgnoreIndex) { RemovePattern(GetIgnoreIndex()); } // If not supported, remove "---" items between patterns. if(!specs.hasStopIndex) { RemovePattern(GetInvalidPatIndex()); } } //Resize orderlist if needed. if(specs.ordersMax < size()) { // Order list too long? Remove "unnecessary" order items first. if(oldtype != MOD_TYPE_NONE && specs.ordersMax < GetLengthTailTrimmed()) { erase(std::remove_if(begin(), end(), [&] (PATTERNINDEX pat) { return !m_sndFile.Patterns.IsValidPat(pat); }), end()); if(GetLengthTailTrimmed() > specs.ordersMax) { m_sndFile.AddToLog("WARNING: Order list has been trimmed!"); } } resize(specs.ordersMax); } } ORDERINDEX ModSequence::GetLengthTailTrimmed() const { if(empty()) return 0; auto last = std::find_if(rbegin(), rend(), [] (PATTERNINDEX pat) { return pat != GetInvalidPatIndex(); }); return static_cast(std::distance(begin(), last.base())); } ORDERINDEX ModSequence::GetLengthFirstEmpty() const { return static_cast(std::distance(begin(), std::find(begin(), end(), GetInvalidPatIndex()))); } ORDERINDEX ModSequence::GetNextOrderIgnoringSkips(const ORDERINDEX start) const { if(empty()) return 0; auto length = GetLength(); ORDERINDEX next = std::min(ORDERINDEX(length - 1), ORDERINDEX(start + 1)); while(next + 1 < length && at(next) == GetIgnoreIndex()) next++; return next; } ORDERINDEX ModSequence::GetPreviousOrderIgnoringSkips(const ORDERINDEX start) const { const ORDERINDEX last = GetLastIndex(); if(start == 0 || last == 0) return 0; ORDERINDEX prev = std::min(ORDERINDEX(start - 1), last); while(prev > 0 && at(prev) == GetIgnoreIndex()) prev--; return prev; } void ModSequence::Remove(ORDERINDEX posBegin, ORDERINDEX posEnd) { if(posEnd < posBegin || posEnd >= size()) return; erase(begin() + posBegin, begin() + posEnd + 1); } // Remove all references to a given pattern index from the order list. Jump commands are updated accordingly. void ModSequence::RemovePattern(PATTERNINDEX pat) { // First, calculate the offset that needs to be applied to jump commands const ORDERINDEX orderLength = GetLengthTailTrimmed(); std::vector jumpOffset(orderLength, 0); ORDERINDEX maxJump = 0; for(ORDERINDEX i = 0; i < orderLength; i++) { jumpOffset[i] = i - maxJump; if(at(i) == pat) { maxJump++; } } if(!maxJump) { return; } erase(std::remove_if(begin(), end(), [pat](PATTERNINDEX p) { return p == pat; }), end()); // Only apply to patterns actually found in this sequence for(auto p : *this) if(m_sndFile.Patterns.IsValidPat(p)) { for(auto &m : m_sndFile.Patterns[p]) { if(m.command == CMD_POSITIONJUMP && m.param < jumpOffset.size()) { m.param = static_cast(jumpOffset[m.param]); } } } if(m_restartPos < jumpOffset.size()) { m_restartPos = jumpOffset[m_restartPos]; } } void ModSequence::assign(ORDERINDEX newSize, PATTERNINDEX pat) { LimitMax(newSize, m_sndFile.GetModSpecifications().ordersMax); std::vector::assign(newSize, pat); } ORDERINDEX ModSequence::insert(ORDERINDEX pos, ORDERINDEX count, PATTERNINDEX fill) { if (pos >= m_sndFile.GetModSpecifications().ordersMax || count == 0) return 0; // Limit number of orders to be inserted so that we don't exceed the format limit. LimitMax(count, ORDERINDEX(m_sndFile.GetModSpecifications().ordersMax - pos)); reserve(pos + count); // Inserting past the end of the container? if(pos > size()) resize(pos); std::vector::insert(begin() + pos, count, fill); // Did we overgrow? Remove patterns at end. if(size() > m_sndFile.GetModSpecifications().ordersMax) resize(m_sndFile.GetModSpecifications().ordersMax); return count; } bool ModSequence::IsValidPat(ORDERINDEX ord) const { if(ord < size()) return m_sndFile.Patterns.IsValidPat(at(ord)); return false; } ORDERINDEX ModSequence::FindOrder(PATTERNINDEX pat, ORDERINDEX startSearchAt, bool searchForward) const { const ORDERINDEX length = GetLength(); ORDERINDEX ord = startSearchAt; for(ORDERINDEX p = 0; p < length; p++) { if(at(ord) == pat) { return ord; } if(searchForward) { if(++ord >= length) ord = 0; } else { if(ord-- == 0) ord = length - 1; } } return ORDERINDEX_INVALID; } PATTERNINDEX ModSequence::EnsureUnique(ORDERINDEX ord) { PATTERNINDEX pat = at(ord); for(const auto &sequence : m_sndFile.Order) { ORDERINDEX ords = sequence.GetLength(); for(ORDERINDEX o = 0; o < ords; o++) { if(sequence[o] == pat && (o != ord || &sequence != this)) { // Found duplicate usage. PATTERNINDEX newPat = m_sndFile.Patterns.Duplicate(pat); if(newPat != PATTERNINDEX_INVALID) { at(ord) = newPat; return newPat; } } } } return pat; } ///////////////////////////////////// // ModSequenceSet ///////////////////////////////////// ModSequenceSet::ModSequenceSet(CSoundFile &sndFile) : m_sndFile(sndFile) { Initialize(); } void ModSequenceSet::Initialize() { m_currentSeq = 0; m_Sequences.assign(1, ModSequence(m_sndFile)); } void ModSequenceSet::SetSequence(SEQUENCEINDEX n) { if(n < m_Sequences.size()) m_currentSeq = n; } SEQUENCEINDEX ModSequenceSet::AddSequence(bool duplicate) { if(GetNumSequences() == MAX_SEQUENCES) return SEQUENCEINDEX_INVALID; if(duplicate) { m_Sequences.push_back(m_Sequences[m_currentSeq]); m_Sequences.back().m_name.clear(); // Don't copy sequence name. } else { m_Sequences.push_back(ModSequence(m_sndFile)); } SetSequence(GetNumSequences() - 1); return GetNumSequences() - 1; } void ModSequenceSet::RemoveSequence(SEQUENCEINDEX i) { // Do nothing if index is invalid or if there's only one sequence left. if(i >= m_Sequences.size() || m_Sequences.size() <= 1) return; m_Sequences.erase(m_Sequences.begin() + i); if(i < m_currentSeq || m_currentSeq >= GetNumSequences()) m_currentSeq--; } #ifdef MODPLUG_TRACKER void ModSequenceSet::OnModTypeChanged(MODTYPE oldType) { for(auto &seq : m_Sequences) { seq.AdjustToNewModType(oldType); } // Multisequences not suppported by other formats if(oldType != MOD_TYPE_NONE && m_sndFile.GetModSpecifications().sequencesMax <= 1) MergeSequences(); // Convert sequence with separator patterns into multiple sequences? if(oldType != MOD_TYPE_NONE && m_sndFile.GetModSpecifications().sequencesMax > 1 && GetNumSequences() == 1) ConvertSubsongsToMultipleSequences(); } bool ModSequenceSet::ConvertSubsongsToMultipleSequences() { // Allow conversion only if there's only one sequence. if(GetNumSequences() != 1 || m_sndFile.GetModSpecifications().sequencesMax <= 1) return false; m_Sequences[0].Shrink(); bool hasSepPatterns = std::find_if(m_Sequences[0].begin(), m_Sequences[0].end(), [&] (PATTERNINDEX pat) { return pat != GetIgnoreIndex() && !m_sndFile.Patterns.IsValidPat(pat); }) != m_Sequences[0].end(); bool modified = false; if(hasSepPatterns && Reporting::Confirm("The order list contains separator items.\nThe new format supports multiple sequences, do you want to convert those separate tracks into multiple song sequences?", "Order list conversion", false, true) == cnfYes) { ORDERINDEX length = m_Sequences[0].GetLengthTailTrimmed(); for(ORDERINDEX ord = 0; ord < length; ord++) { // End of subsong? if(!m_Sequences[0].IsValidPat(ord) && m_Sequences[0][ord] != GetIgnoreIndex()) { // remove all separator patterns between current and next subsong first while(ord < length && !m_sndFile.Patterns.IsValidIndex(m_Sequences[0][ord])) { m_Sequences[0][ord] = GetInvalidPatIndex(); ord++; modified = true; } if(ord >= length) break; ORDERINDEX startOrd = ord; modified = true; SEQUENCEINDEX newSeq = AddSequence(false); m_Sequences[newSeq].reserve(length - startOrd); // now, move all following orders to the new sequence while(ord < length && m_Sequences[0][ord] != GetInvalidPatIndex()) { PATTERNINDEX copyPat = m_Sequences[0][ord]; m_Sequences[newSeq].push_back(copyPat); m_Sequences[0][ord] = GetInvalidPatIndex(); ord++; // is this a valid pattern? adjust pattern jump commands, if necessary. if(m_sndFile.Patterns.IsValidPat(copyPat)) { for(auto &m : m_sndFile.Patterns[copyPat]) { if(m.command == CMD_POSITIONJUMP && m.param >= startOrd) { m.param = static_cast(m.param - startOrd); } } } } } } SetSequence(0); } return modified; } // Convert the sequence's restart position information to a pattern command. bool ModSequenceSet::RestartPosToPattern(SEQUENCEINDEX seq) { bool result = false; auto length = m_sndFile.GetLength(eNoAdjust, GetLengthTarget(true).StartPos(seq, 0, 0)); ModSequence &order = m_Sequences[seq]; for(const auto &subSong : length) { if(subSong.endOrder != ORDERINDEX_INVALID && subSong.endRow != ROWINDEX_INVALID) { if(Util::TypeCanHoldValue(order.GetRestartPos())) { PATTERNINDEX writePat = order.EnsureUnique(subSong.endOrder); result = m_sndFile.Patterns[writePat].WriteEffect( EffectWriter(CMD_POSITIONJUMP, static_cast(order.GetRestartPos())).Row(subSong.endRow).RetryNextRow()); } else { result = false; } } } order.SetRestartPos(0); return result; } bool ModSequenceSet::MergeSequences() { if(GetNumSequences() <= 1) return false; ModSequence &firstSeq = m_Sequences[0]; firstSeq.resize(firstSeq.GetLengthTailTrimmed()); std::vector patternsFixed(m_sndFile.Patterns.Size(), SEQUENCEINDEX_INVALID); // pattern fixed by other sequence already? // Mark patterns handled in first sequence for(auto pat : firstSeq) { if(m_sndFile.Patterns.IsValidPat(pat)) patternsFixed[pat] = 0; } for(SEQUENCEINDEX seqNum = 1; seqNum < GetNumSequences(); seqNum++) { ModSequence &seq = m_Sequences[seqNum]; const ORDERINDEX firstOrder = firstSeq.GetLength() + 1; // +1 for separator item const ORDERINDEX lengthTrimmed = seq.GetLengthTailTrimmed(); if(firstOrder + lengthTrimmed > m_sndFile.GetModSpecifications().ordersMax) { m_sndFile.AddToLog(mpt::format("WARNING: Cannot merge Sequence %1 (too long!)")(seqNum)); continue; } firstSeq.reserve(firstOrder + lengthTrimmed); firstSeq.push_back(); // Separator item RestartPosToPattern(seqNum); for(ORDERINDEX ord = 0; ord < lengthTrimmed; ord++) { PATTERNINDEX pat = seq[ord]; firstSeq.push_back(pat); // Try to fix pattern jump commands if(!m_sndFile.Patterns.IsValidPat(pat)) continue; auto m = m_sndFile.Patterns[pat].begin(); for(size_t len = 0; len < m_sndFile.Patterns[pat].GetNumRows() * m_sndFile.m_nChannels; m++, len++) { if(m->command == CMD_POSITIONJUMP) { if(patternsFixed[pat] != SEQUENCEINDEX_INVALID && patternsFixed[pat] != seqNum) { // Oops, some other sequence uses this pattern already. const PATTERNINDEX newPat = m_sndFile.Patterns.Duplicate(pat, true); if(newPat != PATTERNINDEX_INVALID) { // Could create new pattern - copy data over and continue from here. firstSeq[firstOrder + ord] = newPat; m = m_sndFile.Patterns[newPat].begin() + len; if(newPat >= patternsFixed.size()) patternsFixed.resize(newPat + 1, SEQUENCEINDEX_INVALID); pat = newPat; } else { // Cannot create new pattern: notify the user m_sndFile.AddToLog(mpt::format("CONFLICT: Pattern break commands in Pattern %1 might be broken since it has been used in several sequences!")(pat)); } } m->param = static_cast(m->param + firstOrder); patternsFixed[pat] = seqNum; } } } } m_Sequences.erase(m_Sequences.begin() + 1, m_Sequences.end()); return true; } // Check if a playback position is currently locked (inaccessible) bool ModSequence::IsPositionLocked(ORDERINDEX position) const { return(m_sndFile.m_lockOrderStart != ORDERINDEX_INVALID && (position < m_sndFile.m_lockOrderStart || position > m_sndFile.m_lockOrderEnd)); } #endif // MODPLUG_TRACKER ///////////////////////////////////// // Read/Write ///////////////////////////////////// size_t ModSequence::WriteAsByte(FILE *f, const ORDERINDEX count, uint8 stopIndex, uint8 ignoreIndex) const { const size_t limit = std::min(count, GetLength()); for(size_t i = 0; i < limit; i++) { const PATTERNINDEX pat = at(i); uint8 temp = static_cast(pat); if(pat == GetInvalidPatIndex()) temp = stopIndex; else if(pat == GetIgnoreIndex() || pat > 0xFF) temp = ignoreIndex; fwrite(&temp, 1, 1, f); } // Fill non-existing order items with stop indices for(size_t i = limit; i < count; i++) { fwrite(&stopIndex, 1, 1, f); } return count; //Returns the number of bytes written. } void ReadModSequenceOld(std::istream& iStrm, ModSequenceSet& seq, const size_t) { uint16 size; mpt::IO::ReadIntLE(iStrm, size); if(size > ModSpecs::mptm.ordersMax) { seq.m_sndFile.AddToLog(mpt::format(str_SequenceTruncationNote)(size, ModSpecs::mptm.ordersMax)); size = ModSpecs::mptm.ordersMax; } seq(0).resize(size); for(auto &pat : seq(0)) { uint16 temp; mpt::IO::ReadIntLE(iStrm, temp); pat = temp; } } void WriteModSequenceOld(std::ostream& oStrm, const ModSequenceSet& seq) { const uint16 size = seq().GetLength(); mpt::IO::WriteIntLE(oStrm, size); for(auto pat : seq()) { mpt::IO::WriteIntLE(oStrm, static_cast(pat)); } } void WriteModSequence(std::ostream& oStrm, const ModSequence& seq) { srlztn::SsbWrite ssb(oStrm); ssb.BeginWrite(FileIdSequence, MptVersion::num); ssb.WriteItem(seq.GetName(), "n"); const uint16 length = seq.GetLengthTailTrimmed(); ssb.WriteItem(length, "l"); ssb.WriteItem(seq, "a", srlztn::VectorWriter(length)); if(seq.GetRestartPos() > 0) ssb.WriteItem(seq.GetRestartPos(), "r"); ssb.FinishWrite(); } void ReadModSequence(std::istream& iStrm, ModSequence& seq, const size_t) { srlztn::SsbRead ssb(iStrm); ssb.BeginRead(FileIdSequence, MptVersion::num); if ((ssb.GetStatus() & srlztn::SNT_FAILURE) != 0) return; std::string str; ssb.ReadItem(str, "n"); seq.SetName(str); ORDERINDEX nSize = 0; ssb.ReadItem(nSize, "l"); LimitMax(nSize, ModSpecs::mptm.ordersMax); ssb.ReadItem(seq, "a", srlztn::VectorReader(nSize)); ORDERINDEX restartPos = ORDERINDEX_INVALID; if(ssb.ReadItem(restartPos, "r") != srlztn::SsbRead::EntryNotFound && restartPos < nSize) seq.SetRestartPos(restartPos); } void WriteModSequences(std::ostream& oStrm, const ModSequenceSet& seq) { srlztn::SsbWrite ssb(oStrm); ssb.BeginWrite(FileIdSequences, MptVersion::num); const uint8 nSeqs = seq.GetNumSequences(); const uint8 nCurrent = seq.GetCurrentSequenceIndex(); ssb.WriteItem(nSeqs, "n"); ssb.WriteItem(nCurrent, "c"); for(uint8 i = 0; i < nSeqs; i++) { ssb.WriteItem(seq(i), srlztn::ID::FromInt(i), &WriteModSequence); } ssb.FinishWrite(); } void ReadModSequences(std::istream& iStrm, ModSequenceSet& seq, const size_t) { srlztn::SsbRead ssb(iStrm); ssb.BeginRead(FileIdSequences, MptVersion::num); if ((ssb.GetStatus() & srlztn::SNT_FAILURE) != 0) return; SEQUENCEINDEX seqs = 0; uint8 currentSeq = 0; ssb.ReadItem(seqs, "n"); if (seqs == 0) return; LimitMax(seqs, MAX_SEQUENCES); ssb.ReadItem(currentSeq, "c"); if (seq.GetNumSequences() < seqs) seq.m_Sequences.resize(seqs, ModSequence(seq.m_sndFile)); // There used to be only one restart position for all sequences ORDERINDEX legacyRestartPos = seq(0).GetRestartPos(); for(SEQUENCEINDEX i = 0; i < seqs; i++) { seq(i).SetRestartPos(legacyRestartPos); ssb.ReadItem(seq(i), srlztn::ID::FromInt(i), &ReadModSequence); } seq.m_currentSeq = (currentSeq < seq.GetNumSequences()) ? currentSeq : 0; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Tagging.h0000644000372100037210000000125613161656666017652 00000000000000/* * Tagging.h * --------- * Purpose: Structure holding a superset of tags for all supported output sample or stream files or types. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include OPENMPT_NAMESPACE_BEGIN struct FileTags { mpt::ustring encoder; mpt::ustring title; mpt::ustring comments; mpt::ustring bpm; mpt::ustring artist; mpt::ustring album; mpt::ustring trackno; mpt::ustring year; mpt::ustring url; mpt::ustring genre; FileTags(); }; mpt::ustring GetSampleNameFromTags(const FileTags &tags); OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/ModInstrument.h0000644000372100037210000001541213134621005021054 00000000000000/* * ModInstrument.h * --------------- * Purpose: Module Instrument header class and helpers * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "tuningbase.h" #include "Snd_defs.h" #include "../common/FlagSet.h" #include "../common/misc_util.h" #include OPENMPT_NAMESPACE_BEGIN // Instrument Nodes struct EnvelopeNode { typedef uint16 tick_t; typedef uint8 value_t; tick_t tick; // Envelope node position (x axis) value_t value; // Envelope node value (y axis) EnvelopeNode() : tick(0), value(0) { } EnvelopeNode(tick_t tick, value_t value) : tick(tick), value(value) { } bool operator== (const EnvelopeNode &other) const { return tick == other.tick && value == other.value; } }; // Instrument Envelopes struct InstrumentEnvelope : public std::vector { FlagSet dwFlags; // Envelope flags uint8 nLoopStart; // Loop start node uint8 nLoopEnd; // Loop end node uint8 nSustainStart; // Sustain start node uint8 nSustainEnd; // Sustain end node uint8 nReleaseNode; // Release node InstrumentEnvelope() { nLoopStart = nLoopEnd = 0; nSustainStart = nSustainEnd = 0; nReleaseNode = ENV_RELEASE_NODE_UNSET; } // Convert envelope data between various formats. void Convert(MODTYPE fromType, MODTYPE toType); // Get envelope value at a given tick. Assumes that the envelope data is in rage [0, rangeIn], // returns value in range [0, rangeOut]. int32 GetValueFromPosition(int position, int32 rangeOut, int32 rangeIn = ENVELOPE_MAX) const; // Ensure that ticks are ordered in increasing order and values are within the allowed range. void Sanitize(uint8 maxValue = ENVELOPE_MAX); uint32 size() const { return static_cast(std::vector::size()); } using std::vector::push_back; void push_back(EnvelopeNode::tick_t tick, EnvelopeNode::value_t value) { push_back(EnvelopeNode(tick, value)); } }; // Instrument Struct struct ModInstrument { FlagSet dwFlags; // Instrument flags uint32 nFadeOut; // Instrument fadeout speed uint32 nGlobalVol; // Global volume (0...64, all sample volumes are multiplied with this - TODO: This is 0...128 in Impulse Tracker) uint32 nPan; // Default pan (0...256), if the appropriate flag is set. Sample panning overrides instrument panning. uint16 nVolRampUp; // Default sample ramping up, 0 = use global default uint16 wMidiBank; // MIDI Bank (1...16384). 0 = Don't send. uint8 nMidiProgram; // MIDI Program (1...128). 0 = Don't send. uint8 nMidiChannel; // MIDI Channel (1...16). 0 = Don't send. 17 = Mapped (Send to tracker channel modulo 16). uint8 nMidiDrumKey; // Drum set note mapping (currently only used by the .MID loader) int8 midiPWD; // MIDI Pitch Wheel Depth in semitones uint8 nNNA; // New note action (NNA_* constants) uint8 nDCT; // Duplicate check type (i.e. which condition will trigger the duplicate note action, DCT_* constants) uint8 nDNA; // Duplicate note action (DNA_* constants) uint8 nPanSwing; // Random panning factor (0...64) uint8 nVolSwing; // Random volume factor (0...100) uint8 nIFC; // Default filter cutoff (0...127). Used if the high bit is set uint8 nIFR; // Default filter resonance (0...127). Used if the high bit is set int8 nPPS; // Pitch/Pan separation (i.e. how wide the panning spreads, -32...32) uint8 nPPC; // Pitch/Pan centre (zero-based, default is NOTE_MIDDLE_C - 1) PLUGINDEX nMixPlug; // Plugin assigned to this instrument (0 = no plugin, 1 = first plugin) uint8 nCutSwing; // Random cutoff factor (0...64) uint8 nResSwing; // Random resonance factor (0...64) uint8 nFilterMode; // Default filter mode (FLTMODE_* constants) uint8 nPluginVelocityHandling; // How to deal with plugin velocity (PLUGIN_VELOCITYHANDLING_* constants) uint8 nPluginVolumeHandling; // How to deal with plugin volume (PLUGIN_VOLUMEHANDLING_* constants) TEMPO pitchToTempoLock; // BPM at which the samples assigned to this instrument loop correctly (0 = unset) uint32 nResampling; // Resampling mode (SRCMODE_* constants) CTuning *pTuning; // sample tuning assigned to this instrument InstrumentEnvelope VolEnv; // Volume envelope data InstrumentEnvelope PanEnv; // Panning envelope data InstrumentEnvelope PitchEnv; // Pitch / filter envelope data uint8 NoteMap[128]; // Note mapping, e.g. C-5 => D-5. SAMPLEINDEX Keyboard[128]; // Sample mapping, e.g. C-5 => Sample 1 char name[MAX_INSTRUMENTNAME]; char filename[MAX_INSTRUMENTFILENAME]; // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // WHEN adding new members here, ALSO update InstrumentExtensions.cpp // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! void SetTuning(CTuning* pT) { pTuning = pT; } ModInstrument(SAMPLEINDEX sample = 0); // Assign all notes to a given sample. void AssignSample(SAMPLEINDEX sample) { for(size_t n = 0; n < CountOf(Keyboard); n++) { Keyboard[n] = sample; } } // Reset note mapping (i.e. every note is mapped to itself) void ResetNoteMap() { for(size_t n = 0; n < CountOf(NoteMap); n++) { NoteMap[n] = static_cast(n + 1); } } bool IsCutoffEnabled() const { return (nIFC & 0x80) != 0; } bool IsResonanceEnabled() const { return (nIFR & 0x80) != 0; } uint8 GetCutoff() const { return (nIFC & 0x7F); } uint8 GetResonance() const { return (nIFR & 0x7F); } void SetCutoff(uint8 cutoff, bool enable) { nIFC = std::min(cutoff, 0x7F) | (enable ? 0x80 : 0x00); } void SetResonance(uint8 resonance, bool enable) { nIFR = std::min(resonance, 0x7F) | (enable ? 0x80 : 0x00); } bool HasValidMIDIChannel() const { return (nMidiChannel >= 1 && nMidiChannel <= 17); } // Get a reference to a specific envelope of this instrument const InstrumentEnvelope &GetEnvelope(EnvelopeType envType) const { switch(envType) { case ENV_VOLUME: default: return VolEnv; case ENV_PANNING: return PanEnv; case ENV_PITCH: return PitchEnv; } } InstrumentEnvelope &GetEnvelope(EnvelopeType envType) { return const_cast(static_cast(*this).GetEnvelope(envType)); } // Get a set of all samples referenced by this instrument std::set GetSamples() const; // Write sample references into a bool vector. If a sample is referenced by this instrument, true is written. // The caller has to initialize the vector. void GetSamples(std::vector &referencedSamples) const; // Translate instrument properties between two given formats. void Convert(MODTYPE fromType, MODTYPE toType); // Sanitize all instrument data. void Sanitize(MODTYPE modType); }; OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/ModChannel.h0000644000372100037210000001573013144303472020265 00000000000000/* * ModChannel.h * ------------ * Purpose: Module Channel header class and helpers * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "ModSample.h" #include "ModInstrument.h" #include "modcommand.h" #include "Paula.h" OPENMPT_NAMESPACE_BEGIN class CSoundFile; // Mix Channel Struct struct ModChannel { // Envelope playback info struct EnvInfo { FlagSet flags; uint32 nEnvPosition; int32 nEnvValueAtReleaseJump; void Reset() { nEnvPosition = 0; nEnvValueAtReleaseJump = NOT_YET_RELEASED; } }; // Information used in the mixer (should be kept tight for better caching) SamplePosition position; // Current play position (fixed point) SamplePosition increment; // Sample speed relative to mixing frequency (fixed point) const void *pCurrentSample; // Currently playing sample (nullptr if no sample is playing) int32 leftVol; // 0...4096 (12 bits, since 16 bits + 12 bits = 28 bits = 0dB in integer mixer, see MIXING_ATTENUATION) int32 rightVol; // Ditto int32 leftRamp; // Ramping delta, 20.12 fixed point (see VOLUMERAMPPRECISION) int32 rightRamp; // Ditto int32 rampLeftVol; // Current ramping volume, 20.12 fixed point (see VOLUMERAMPPRECISION) int32 rampRightVol; // Ditto mixsample_t nFilter_Y[2][2]; // Filter memory - two history items per sample channel mixsample_t nFilter_A0, nFilter_B0, nFilter_B1; // Filter coeffs mixsample_t nFilter_HP; SmpLength nLength; SmpLength nLoopStart; SmpLength nLoopEnd; FlagSet dwFlags; mixsample_t nROfs, nLOfs; uint32 nRampLength; const ModSample *pModSample; // Currently assigned sample slot (may already be stopped) Paula::State paulaState; // Information not used in the mixer const ModInstrument *pModInstrument; // Currently assigned instrument slot SmpLength proTrackerOffset; // Offset for instrument-less notes in ProTracker mode SmpLength oldOffset; FlagSet dwOldFlags; // Flags from previous tick int32 newLeftVol, newRightVol; int32 nRealVolume, nRealPan; int32 nVolume, nPan, nFadeOutVol; int32 nPeriod, nC5Speed, nPortamentoDest; int32 cachedPeriod, glissandoPeriod; int32 nCalcVolume; // Calculated channel volume, 14-Bit (without global volume, pre-amp etc applied) - for MIDI macros EnvInfo VolEnv, PanEnv, PitchEnv; // Envelope playback info int32 nGlobalVol; // Channel volume (CV in ITTECH.TXT) int32 nInsVol; // Sample / Instrument volume (SV * IV in ITTECH.TXT) int32 nFineTune, nTranspose; int32 nPortamentoSlide, nAutoVibDepth; uint32 nEFxOffset; // offset memory for Invert Loop (EFx, .MOD only) int16 nVolSwing, nPanSwing; int16 nCutSwing, nResSwing; int16 nRestorePanOnNewNote; //If > 0, nPan should be set to nRestorePanOnNewNote - 1 on new note. Used to recover from panswing. int16 nRetrigCount, nRetrigParam; ROWINDEX nPatternLoop; CHANNELINDEX nMasterChn; ModCommand rowCommand; // 8-bit members uint8 resamplingMode; uint8 nRestoreResonanceOnNewNote; // See nRestorePanOnNewNote uint8 nRestoreCutoffOnNewNote; // ditto uint8 nNote, nNNA; uint8 nLastNote; // Last note, ignoring note offs and cuts - for MIDI macros uint8 nArpeggioLastNote, nArpeggioBaseNote; // For plugin arpeggio uint8 nNewNote, nNewIns, nOldIns, nCommand, nArpeggio; uint8 nOldVolumeSlide, nOldFineVolUpDown; uint8 nOldPortaUp, nOldPortaDown, nOldFinePortaUpDown, nOldExtraFinePortaUpDown; uint8 nOldPanSlide, nOldChnVolSlide; uint8 nOldGlobalVolSlide; uint8 nAutoVibPos, nVibratoPos, nTremoloPos, nPanbrelloPos; uint8 nVibratoType, nVibratoSpeed, nVibratoDepth; uint8 nTremoloType, nTremoloSpeed, nTremoloDepth; uint8 nPanbrelloType, nPanbrelloSpeed, nPanbrelloDepth; int8 nPanbrelloOffset, nPanbrelloRandomMemory; uint8 nOldCmdEx, nOldVolParam, nOldTempo; uint8 nOldHiOffset; uint8 nCutOff, nResonance; uint8 nTremorCount, nTremorParam; uint8 nPatternLoopCount; uint8 nLeftVU, nRightVU; uint8 nActiveMacro, nFilterMode; uint8 nEFxSpeed, nEFxDelay; // memory for Invert Loop (EFx, .MOD only) uint8 nNoteSlideCounter, nNoteSlideSpeed, nNoteSlideStep; // IMF / PTM Note Slide uint8 lastZxxParam; // Memory for \xx slides bool isFirstTick : 1; //-->Variables used to make user-definable tuning modes work with pattern effects. //If true, freq should be recalculated in ReadNote() on first tick. //Currently used only for vibrato things - using in other context might be //problematic. bool m_ReCalculateFreqOnFirstTick : 1; //To tell whether to calculate frequency. bool m_CalculateFreq : 1; int32 m_PortamentoFineSteps, m_PortamentoTickSlide; uint32 m_Freq; //<---- //NOTE_PCs memory. float m_plugParamValueStep, m_plugParamTargetValue; uint16 m_RowPlugParam; PLUGINDEX m_RowPlug; void ClearRowCmd() { rowCommand = ModCommand::Empty(); } // Get a reference to a specific envelope of this channel const EnvInfo &GetEnvelope(EnvelopeType envType) const { switch(envType) { case ENV_VOLUME: default: return VolEnv; case ENV_PANNING: return PanEnv; case ENV_PITCH: return PitchEnv; } } EnvInfo &GetEnvelope(EnvelopeType envType) { return const_cast(static_cast(this)->GetEnvelope(envType)); } void ResetEnvelopes() { VolEnv.Reset(); PanEnv.Reset(); PitchEnv.Reset(); } enum ResetFlags { resetChannelSettings = 1, // Reload initial channel settings resetSetPosBasic = 2, // Reset basic runtime channel attributes resetSetPosAdvanced = 4, // Reset more runtime channel attributes resetSetPosFull = resetSetPosBasic | resetSetPosAdvanced | resetChannelSettings, // Reset all runtime channel attributes resetTotal = resetSetPosFull, }; void Reset(ResetFlags resetMask, const CSoundFile &sndFile, CHANNELINDEX sourceChannel); void Stop(); bool IsSamplePlaying() const { return !increment.IsZero(); } uint32 GetVSTVolume() { return (pModInstrument) ? pModInstrument->nGlobalVol * 4 : nVolume; } ModCommand::NOTE GetPluginNote(bool realNoteMapping) const; // Check if the channel has a valid MIDI output. This function guarantees that pModInstrument != nullptr. bool HasMIDIOutput() const { return pModInstrument != nullptr && pModInstrument->HasValidMIDIChannel(); } // Check if currently processed loop is a sustain loop. pModSample is not checked for validity! bool InSustainLoop() const { return (dwFlags & (CHN_LOOP | CHN_KEYOFF)) == CHN_LOOP && pModSample->uFlags[CHN_SUSTAINLOOP]; } void UpdateInstrumentVolume(const ModSample *smp, const ModInstrument *ins); }; // Default pattern channel settings struct ModChannelSettings { FlagSet dwFlags; // Channel flags uint16 nPan; // Initial pan (0...256) uint16 nVolume; // Initial channel volume (0...64) PLUGINDEX nMixPlugin; // Assigned plugin char szName[MAX_CHANNELNAME]; // Channel name ModChannelSettings() { Reset(); } void Reset() { dwFlags.reset(); nPan = 128; nVolume = 64; nMixPlugin = 0; szName[0] = '\0'; } }; OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/WindowedFIR.cpp0000644000372100037210000000602712345336772020743 00000000000000/* * WindowedFIR.cpp * --------------- * Purpose: FIR resampling code * Notes : (currently none) * Authors: OpenMPT Devs * ModPlug-XMMS Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "WindowedFIR.h" #include OPENMPT_NAMESPACE_BEGIN // -> CODE#0025 // -> DESC="enable polyphase resampling on stereo samples" // -> !!! stolen from modplug-xmms sourceforge project !!! float CWindowedFIR::coef( int _PCnr, float _POfs, float _PCut, int _PWidth, int _PType ) //float _PPos, float _PFc, int _PLen ) { double _LWidthM1 = _PWidth-1; double _LWidthM1Half = 0.5*_LWidthM1; double _LPosU = ((double)_PCnr - _POfs); double _LPos = _LPosU-_LWidthM1Half; double _LPIdl = 2.0*M_zPI/_LWidthM1; double _LWc,_LSi; if(fabs(_LPos) < M_zEPS) { _LWc = 1.0; _LSi = _PCut; } else { switch( _PType ) { case WFIR_HANN: _LWc = 0.50 - 0.50 * cos(_LPIdl*_LPosU); break; case WFIR_HAMMING: _LWc = 0.54 - 0.46 * cos(_LPIdl*_LPosU); break; case WFIR_BLACKMANEXACT: _LWc = 0.42 - 0.50 * cos(_LPIdl*_LPosU) + 0.08 * cos(2.0*_LPIdl*_LPosU); break; case WFIR_BLACKMAN3T61: _LWc = 0.44959 - 0.49364 * cos(_LPIdl*_LPosU) + 0.05677 * cos(2.0*_LPIdl*_LPosU); break; case WFIR_BLACKMAN3T67: _LWc = 0.42323 - 0.49755 * cos(_LPIdl*_LPosU) + 0.07922 * cos(2.0*_LPIdl*_LPosU); break; case WFIR_BLACKMAN4T92: // blackman harris _LWc = 0.35875 - 0.48829 * cos(_LPIdl*_LPosU) + 0.14128 * cos(2.0*_LPIdl*_LPosU) - 0.01168 * cos(3.0*_LPIdl*_LPosU); break; case WFIR_BLACKMAN4T74: _LWc = 0.40217 - 0.49703 * cos(_LPIdl*_LPosU) + 0.09392 * cos(2.0*_LPIdl*_LPosU) - 0.00183 * cos(3.0*_LPIdl*_LPosU); break; case WFIR_KAISER4T: // kaiser-bessel, alpha~7.5 _LWc = 0.40243 - 0.49804 * cos(_LPIdl*_LPosU) + 0.09831 * cos(2.0*_LPIdl*_LPosU) - 0.00122 * cos(3.0*_LPIdl*_LPosU); break; default: _LWc = 1.0; break; } _LPos *= M_zPI; _LSi = sin(_PCut*_LPos)/_LPos; } return (float)(_LWc*_LSi); } void CWindowedFIR::InitTable(double WFIRCutoff, uint8 WFIRType) { int _LPcl; float _LPcllen = (float)(1L<(WFIRCutoff); for( _LPcl=0;_LPclWFIR_QUANTSCALE)?WFIR_QUANTSCALE:_LCoef) ); #else float _LCoef = _LCoefs[_LCc] * _LGain; lut[_LIdx+_LCc] = _LCoef; #endif // MPT_INTMIXER } } } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Paula.cpp0000644000372100037210000005432713161656666017676 00000000000000/* * Paula.cpp * --------- * Purpose: Emulating the Amiga's sound chip, Paula, by implementing resampling using band-limited steps (BLEPs) * Notes : (currently none) * Authors: OpenMPT Devs * Antti S. Lankila * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Paula.h" OPENMPT_NAMESPACE_BEGIN namespace Paula { // Tables are: A500 (filter off), A500 (filter on) static constexpr int32 WinSincIntegral[2][2048] = { { 131072,131072,131072,131072,131072,131072,131072,131072,131072,131072,131072, 131072,131072,131072,131072,131072,131072,131072,131072,131072,131072,131071,131071, 131071,131071,131071,131071,131071,131071,131071,131071,131071,131070,131070,131070, 131070,131070,131069,131069,131069,131068,131068,131068,131067,131067,131066,131066, 131065,131065,131064,131063,131063,131062,131061,131060,131059,131058,131056,131055, 131054,131052,131050,131049,131047,131045,131043,131040,131038,131035,131033,131030, 131026,131023,131020,131016,131012,131008,131003,130998,130993,130988,130982,130976, 130970,130963,130956,130949,130941,130932,130924,130914,130905,130895,130884,130872, 130861,130848,130835,130821,130807,130792,130776,130759,130742,130724,130705,130685, 130664,130642,130620,130596,130571,130545,130518,130490,130461,130430,130398,130365, 130331,130295,130257,130219,130178,130136,130093,130047,130000,129951,129901,129848, 129794,129737,129679,129618,129555,129490,129423,129353,129281,129207,129130,129050, 128968,128883,128795,128704,128611,128514,128415,128312,128206,128097,127985,127869, 127750,127627,127501,127371,127237,127100,126959,126813,126664,126510,126353,126191, 126025,125854,125679,125499,125315,125126,124933,124734,124531,124323,124110,123891, 123668,123439,123205,122965,122720,122470,122214,121952,121685,121412,121133,120849, 120558,120261,119959,119650,119335,119014,118687,118354,118014,117668,117315,116956, 116591,116219,115840,115455,115063,114665,114260,113849,113430,113005,112574,112135, 111690,111239,110780,110315,109843,109364,108879,108387,107888,107383,106871,106352, 105827,105295,104757,104212,103661,103104,102540,101970,101394,100812,100223,99629, 99028,98422,97810,97192,96568,95939,95305,94665,94020,93370,92714,92054,91389,90719, 90045,89366,88682,87995,87303,86607,85908,85205,84498,83788,83075,82358,81639,80916, 80191,79464,78734,78002,77268,76533,75795,75056,74316,73575,72833,72090,71346,70602, 69858,69114,68370,67626,66883,66140,65399,64658,63919,63181,62445,61711,60979,60249, 59521,58796,58074,57355,56639,55926,55217,54512,53810,53113,52419,51731,51046,50367, 49693,49023,48359,47701,47048,46400,45759,45124,44495,43872,43256,42646,42043,41447, 40858,40276,39702,39134,38575,38023,37478,36941,36413,35892,35379,34874,34378,33890, 33410,32938,32475,32020,31574,31137,30708,30288,29876,29473,29079,28693,28317,27948, 27589,27238,26896,26562,26238,25921,25613,25314,25023,24740,24466,24200,23942,23692, 23451,23217,22991,22773,22562,22359,22164,21975,21794,21621,21454,21294,21140,20994, 20853,20719,20592,20470,20354,20244,20139,20040,19946,19857,19774,19694,19620,19550, 19484,19422,19364,19310,19260,19213,19169,19128,19090,19054,19022,18991,18963,18936, 18912,18889,18867,18847,18828,18810,18792,18776,18759,18743,18727,18711,18695,18679, 18662,18644,18626,18607,18587,18565,18542,18518,18492,18465,18436,18404,18371,18336, 18298,18259,18216,18172,18124,18074,18022,17966,17908,17847,17783,17716,17646,17572, 17496,17416,17334,17248,17159,17066,16971,16872,16770,16664,16556,16444,16329,16211, 16090,15966,15839,15709,15576,15440,15301,15159,15015,14868,14718,14566,14412,14255, 14096,13935,13771,13606,13439,13270,13099,12927,12753,12578,12401,12224,12045,11866, 11685,11504,11322,11140,10958,10775,10592,10409,10226,10044,9862,9680,9499,9319,9139, 8961,8783,8607,8432,8258,8086,7915,7747,7580,7415,7252,7091,6932,6776,6622,6471, 6322,6176,6032,5892,5754,5619,5488,5359,5234,5111,4992,4877,4764,4655,4550,4448, 4349,4254,4163,4075,3990,3910,3832,3759,3689,3622,3560,3500,3445,3393,3344,3299, 3257,3219,3184,3153,3124,3099,3078,3059,3044,3031,3022,3015,3011,3010,3012,3016, 3023,3033,3044,3058,3075,3093,3113,3136,3160,3186,3213,3242,3273,3305,3338,3372, 3408,3444,3481,3520,3558,3597,3637,3677,3718,3758,3799,3839,3880,3920,3960,4000, 4039,4077,4115,4152,4188,4224,4258,4291,4323,4354,4384,4412,4439,4464,4488,4510, 4530,4549,4566,4581,4594,4606,4615,4623,4628,4631,4633,4632,4629,4624,4617,4608, 4597,4583,4568,4550,4530,4508,4484,4458,4429,4399,4366,4332,4296,4257,4217,4175, 4130,4085,4037,3988,3937,3884,3830,3774,3717,3658,3598,3537,3475,3411,3347,3281, 3215,3147,3079,3010,2940,2870,2799,2728,2657,2585,2513,2440,2368,2296,2224,2151, 2080,2008,1937,1866,1796,1726,1657,1589,1521,1454,1389,1324,1260,1197,1135,1075, 1016,958,901,846,792,740,689,640,592,546,502,459,419,379,342,307,273,241,211,183, 156,132,109,88,69,52,37,24,12,2,-5,-11,-16,-18,-19,-18,-16,-11,-6,2,11,21,33,47,61, 77,95,113,133,154,176,200,224,249,275,302,329,358,387,416,447,477,508,540,572,604, 636,669,702,734,767,800,832,864,896,928,960,991,1021,1051,1081,1110,1138,1166,1193, 1219,1245,1270,1293,1316,1338,1359,1379,1398,1416,1433,1448,1463,1476,1488,1499, 1509,1518,1525,1531,1536,1540,1542,1543,1543,1542,1539,1536,1530,1524,1517,1508, 1498,1487,1475,1462,1447,1432,1415,1397,1379,1359,1338,1317,1294,1271,1247,1222, 1196,1170,1143,1115,1086,1057,1028,998,967,936,905,874,842,809,777,744,712,679,646, 613,581,548,515,483,450,418,387,355,324,293,263,233,204,175,147,119,92,66,40,15, -10,-33,-56,-78,-99,-120,-139,-158,-176,-193,-209,-224,-238,-252,-264,-275,-286, -295,-304,-311,-318,-324,-329,-332,-335,-337,-338,-338,-338,-336,-333,-330,-326, -321,-315,-308,-301,-293,-284,-274,-264,-253,-242,-229,-217,-203,-190,-175,-161, -145,-130,-114,-98,-81,-64,-47,-29,-11,6,24,42,61,79,97,115,134,152,170,188,206,223, 241,258,275,291,308,324,340,355,370,384,399,412,425,438,450,462,473,484,494,503, 512,521,529,536,542,548,553,558,562,566,568,570,572,573,573,573,572,570,568,565, 562,558,553,548,543,537,530,523,515,507,498,489,479,469,459,448,437,426,414,402, 389,377,364,351,337,324,310,296,282,268,254,239,225,211,196,182,168,153,139,125, 111,97,83,70,56,43,30,17,5,-7,-19,-31,-42,-53,-64,-75,-85,-94,-104,-113,-121,-129, -137,-144,-151,-158,-164,-170,-175,-180,-184,-188,-192,-195,-198,-200,-202,-203, -204,-205,-205,-204,-204,-203,-201,-199,-197,-195,-192,-188,-185,-181,-176,-172, -167,-162,-156,-151,-145,-139,-132,-126,-119,-112,-104,-97,-90,-82,-74,-66,-59,-51, -42,-34,-26,-18,-10,-2,7,15,23,31,39,47,54,62,70,77,85,92,99,106,112,119,125,131, 137,143,148,154,159,163,168,172,176,180,183,187,190,192,195,197,199,201,202,203, 204,205,205,205,205,204,203,202,201,200,198,196,194,192,189,186,183,180,177,173, 169,165,161,157,153,148,143,139,134,129,124,119,113,108,103,97,92,86,81,75,70,64, 59,53,48,42,37,32,26,21,16,11,6,1,-4,-9,-13,-18,-22,-26,-30,-34,-38,-42,-46,-49, -52,-55,-58,-61,-64,-66,-69,-71,-73,-74,-76,-78,-79,-80,-81,-82,-82,-83,-83,-83, -83,-83,-83,-82,-82,-81,-80,-79,-78,-77,-75,-74,-72,-70,-68,-66,-64,-62,-60,-57, -55,-52,-50,-47,-44,-42,-39,-36,-33,-30,-27,-24,-21,-18,-15,-12,-9,-6,-3,0,3,6,8, 11,14,17,20,22,25,27,30,32,35,37,39,41,43,45,47,49,50,52,54,55,56,58,59,60,61,61, 62,63,63,64,64,65,65,65,65,65,64,64,64,63,63,62,61,61,60,59,58,57,56,55,53,52,51, 49,48,46,45,43,41,40,38,36,35,33,31,29,28,26,24,22,20,19,17,15,13,11,10,8,6,5,3,1, 0,-2,-3,-5,-6,-8,-9,-10,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-21,-22,-23,-23, -24,-24,-25,-25,-26,-26,-26,-26,-26,-26,-26,-26,-26,-26,-26,-26,-25,-25,-25,-24, -24,-23,-23,-22,-21,-21,-20,-19,-19,-18,-17,-16,-16,-15,-14,-13,-12,-11,-10,-10,-9, -8,-7,-6,-5,-4,-3,-2,-1,0,1,1,2,3,4,5,6,6,7,8,9,9,10,11,11,12,12,13,14,14,15,15, 15,16,16,16,17,17,17,17,18,18,18,18,18,18,18,18,18,18,18,18,18,17,17,17,17,16,16, 16,16,15,15,14,14,14,13,13,12,12,11,11,11,10,10,9,9,8,8,7,7,6,6,5,5,4,4,3,3,2,2,1, 1,0,0,-1,-1,-1,-2,-2,-3,-3,-3,-4,-4,-4,-4,-5,-5,-5,-5,-6,-6,-6,-6,-6,-6,-6,-7,-7, -7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-6,-6,-6,-6,-6,-6,-6,-6,-5,-5,-5,-5,-5,-4,-4,-4, -4,-4,-3,-3,-3,-3,-2,-2,-2,-2,-1,-1,-1,-1,-1,0,0,0,0,1,1,1,1,1,2,2,2,2,2,2,3,3,3, 3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3, 3,3,3,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { 131072,131072,131072,131072,131072,131072,131072,131072,131072,131072,131072, 131072,131071,131071,131071,131071,131071,131071,131071,131071,131071,131071,131071, 131071,131071,131071,131071,131071,131071,131071,131071,131071,131071,131071,131071, 131070,131070,131070,131070,131070,131070,131070,131070,131070,131070,131070,131070, 131070,131070,131070,131070,131070,131070,131070,131070,131070,131070,131069,131069, 131069,131069,131069,131069,131069,131069,131069,131069,131069,131069,131069,131069, 131069,131068,131068,131068,131068,131068,131068,131068,131068,131068,131068,131067, 131067,131067,131067,131067,131067,131067,131066,131066,131066,131066,131066,131065, 131065,131065,131065,131064,131064,131064,131064,131063,131063,131062,131062,131062, 131061,131061,131060,131060,131059,131059,131058,131058,131057,131056,131056,131055, 131054,131053,131052,131052,131051,131050,131049,131048,131046,131045,131044,131043, 131041,131040,131038,131037,131035,131034,131032,131030,131028,131026,131024,131022, 131020,131017,131015,131012,131010,131007,131004,131001,130998,130994,130991,130987, 130984,130980,130976,130972,130968,130963,130959,130954,130949,130944,130938,130933, 130927,130921,130915,130909,130902,130895,130888,130881,130873,130865,130857,130849, 130840,130831,130822,130813,130803,130793,130782,130771,130760,130749,130737,130725, 130712,130699,130685,130672,130657,130643,130628,130612,130596,130580,130563,130545, 130528,130509,130490,130471,130451,130430,130409,130388,130365,130343,130319,130295, 130270,130245,130219,130193,130165,130137,130109,130079,130049,130018,129987,129954, 129921,129887,129853,129817,129781,129744,129706,129667,129627,129587,129545,129503, 129459,129415,129370,129324,129276,129228,129179,129129,129078,129026,128972,128918, 128862,128806,128748,128690,128630,128569,128507,128443,128379,128313,128246,128178, 128109,128038,127966,127893,127819,127743,127667,127588,127509,127428,127346,127262, 127177,127091,127004,126915,126824,126732,126639,126545,126449,126351,126252,126152, 126050,125947,125842,125736,125628,125519,125408,125296,125182,125067,124950,124832, 124712,124591,124468,124344,124218,124090,123961,123830,123698,123564,123429,123292, 123154,123014,122872,122729,122585,122438,122291,122141,121990,121838,121684,121528, 121371,121212,121052,120891,120727,120562,120396,120228,120059,119888,119715,119541, 119366,119189,119011,118831,118649,118467,118282,118097,117909,117721,117531,117339, 117146,116952,116757,116560,116361,116161,115960,115758,115554,115349,115143,114935, 114726,114516,114305,114092,113878,113663,113447,113229,113011,112791,112570,112348, 112124,111900,111675,111448,111220,110992,110762,110531,110300,110067,109833,109598, 109363,109126,108889,108650,108411,108171,107930,107688,107445,107201,106957,106712, 106466,106219,105972,105723,105474,105225,104974,104723,104471,104219,103966,103712, 103458,103203,102948,102692,102435,102178,101920,101662,101403,101144,100885,100624, 100364,100103,99841,99579,99317,99054,98791,98527,98264,97999,97735,97470,97204,96939, 96673,96407,96140,95873,95606,95339,95071,94804,94536,94267,93999,93730,93461,93192, 92923,92653,92383,92114,91844,91573,91303,91033,90762,90491,90220,89949,89678,89407, 89136,88865,88593,88321,88050,87778,87506,87234,86962,86690,86418,86146,85874,85602, 85330,85057,84785,84513,84240,83968,83696,83423,83151,82878,82606,82333,82061,81789, 81516,81244,80971,80699,80427,80154,79882,79610,79337,79065,78793,78521,78249,77977, 77705,77433,77161,76889,76617,76345,76074,75802,75531,75259,74988,74717,74446,74175, 73904,73633,73362,73092,72821,72551,72280,72010,71740,71470,71201,70931,70661,70392, 70123,69854,69585,69317,69048,68780,68512,68244,67976,67709,67441,67174,66907,66641, 66374,66108,65842,65576,65311,65046,64781,64516,64252,63988,63724,63460,63197,62934, 62672,62409,62147,61886,61624,61363,61103,60843,60583,60323,60064,59805,59547,59289, 59031,58774,58517,58261,58005,57749,57494,57239,56985,56731,56478,56225,55973,55721, 55470,55219,54968,54718,54469,54220,53971,53724,53476,53229,52983,52737,52492,52247, 52003,51759,51516,51274,51032,50791,50550,50310,50070,49831,49593,49355,49118,48881, 48645,48410,48175,47941,47707,47474,47242,47010,46779,46549,46319,46090,45861,45633, 45406,45179,44953,44728,44503,44279,44056,43833,43611,43389,43168,42948,42728,42510, 42291,42074,41857,41640,41425,41210,40995,40782,40568,40356,40144,39933,39723,39513, 39304,39095,38887,38680,38473,38267,38062,37857,37653,37449,37247,37044,36843,36642, 36442,36242,36043,35845,35647,35450,35253,35057,34862,34667,34473,34280,34087,33894, 33703,33512,33321,33132,32942,32754,32566,32378,32192,32006,31820,31635,31451,31267, 31084,30901,30719,30538,30357,30177,29997,29818,29640,29462,29285,29108,28932,28756, 28581,28407,28233,28060,27888,27716,27545,27374,27204,27034,26865,26697,26529,26362, 26195,26029,25863,25699,25534,25371,25207,25045,24883,24722,24561,24401,24241,24082, 23924,23766,23609,23453,23297,23142,22987,22833,22679,22526,22374,22222,22071,21921, 21771,21622,21473,21325,21177,21031,20884,20739,20594,20449,20306,20162,20020,19878, 19737,19596,19456,19316,19178,19039,18902,18765,18628,18493,18358,18223,18089,17956, 17823,17691,17560,17429,17299,17169,17040,16912,16784,16657,16531,16405,16280,16155, 16031,15908,15785,15663,15541,15420,15300,15180,15061,14942,14824,14707,14590,14474, 14358,14243,14129,14015,13901,13789,13677,13565,13454,13344,13234,13125,13016,12908, 12801,12694,12588,12482,12377,12272,12168,12064,11961,11859,11757,11655,11554,11454, 11354,11255,11156,11058,10960,10863,10766,10670,10575,10480,10385,10291,10197,10104, 10012,9920,9828,9737,9646,9556,9466,9377,9289,9200,9113,9025,8939,8852,8766,8681, 8596,8512,8428,8344,8261,8178,8096,8014,7933,7852,7772,7692,7612,7533,7455,7376, 7299,7221,7144,7068,6992,6916,6841,6766,6692,6618,6544,6471,6398,6326,6254,6182, 6111,6041,5970,5901,5831,5762,5693,5625,5557,5490,5423,5356,5290,5224,5159,5093, 5029,4965,4901,4837,4774,4711,4649,4587,4525,4464,4404,4343,4283,4224,4164,4105, 4047,3989,3931,3874,3817,3760,3704,3648,3593,3538,3483,3429,3375,3321,3268,3215, 3163,3111,3059,3008,2957,2906,2856,2806,2756,2707,2658,2610,2562,2514,2466,2419, 2373,2326,2280,2235,2189,2144,2100,2056,2012,1968,1925,1882,1839,1797,1755,1714, 1672,1631,1591,1551,1511,1471,1432,1393,1354,1316,1278,1240,1203,1165,1129,1092, 1056,1020,984,949,914,879,845,811,777,743,710,677,644,612,580,548,516,485,454,423, 393,362,332,303,273,244,215,186,158,129,101,74,46,19,-8,-35,-61,-88,-114,-140,-165, -191,-216,-241,-265,-290,-314,-338,-362,-386,-409,-432,-455,-478,-501,-523,-545, -567,-589,-610,-632,-653,-674,-694,-715,-735,-756,-775,-795,-815,-834,-853,-872, -891,-910,-928,-947,-965,-983,-1000,-1018,-1035,-1052,-1069,-1086,-1103,-1119,-1136, -1152,-1168,-1184,-1199,-1215,-1230,-1245,-1260,-1275,-1289,-1304,-1318,-1332,-1346, -1360,-1373,-1387,-1400,-1413,-1426,-1439,-1452,-1464,-1477,-1489,-1501,-1513,-1524, -1536,-1547,-1558,-1570,-1581,-1591,-1602,-1612,-1623,-1633,-1643,-1653,-1663,-1672, -1682,-1691,-1700,-1709,-1718,-1727,-1735,-1744,-1752,-1760,-1768,-1776,-1784,-1792, -1799,-1807,-1814,-1821,-1828,-1835,-1842,-1848,-1855,-1861,-1867,-1873,-1879,-1885, -1891,-1896,-1902,-1907,-1913,-1918,-1923,-1928,-1932,-1937,-1942,-1946,-1950,-1955, -1959,-1963,-1967,-1971,-1974,-1978,-1981,-1985,-1988,-1991,-1994,-1997,-2000,-2003, -2006,-2009,-2011,-2013,-2016,-2018,-2020,-2022,-2024,-2026,-2028,-2030,-2032,-2033, -2035,-2036,-2037,-2039,-2040,-2041,-2042,-2043,-2044,-2045,-2045,-2046,-2047,-2047, -2048,-2048,-2048,-2049,-2049,-2049,-2049,-2049,-2049,-2049,-2049,-2048,-2048,-2048, -2047,-2047,-2046,-2046,-2045,-2044,-2043,-2043,-2042,-2041,-2040,-2039,-2038,-2036, -2035,-2034,-2033,-2031,-2030,-2028,-2027,-2025,-2024,-2022,-2020,-2019,-2017,-2015, -2013,-2011,-2009,-2007,-2005,-2003,-2001,-1998,-1996,-1994,-1992,-1989,-1987,-1984, -1982,-1979,-1977,-1974,-1971,-1969,-1966,-1963,-1960,-1957,-1954,-1952,-1949,-1946, -1942,-1939,-1936,-1933,-1930,-1927,-1923,-1920,-1917,-1913,-1910,-1906,-1903,-1899, -1896,-1892,-1889,-1885,-1881,-1878,-1874,-1870,-1866,-1863,-1859,-1855,-1851,-1847, -1843,-1839,-1835,-1831,-1827,-1823,-1819,-1814,-1810,-1806,-1802,-1798,-1793,-1789, -1785,-1780,-1776,-1771,-1767,-1763,-1758,-1754,-1749,-1745,-1740,-1736,-1731,-1726, -1722,-1717,-1713,-1708,-1703,-1698,-1694,-1689,-1684,-1680,-1675,-1670,-1665,-1660, -1656,-1651,-1646,-1641,-1636,-1631,-1626,-1622,-1617,-1612,-1607,-1602,-1597,-1592, -1587,-1582,-1577,-1572,-1567,-1562,-1557,-1552,-1547,-1542,-1537,-1532,-1527,-1522, -1517,-1512,-1507,-1502,-1497,-1492,-1487,-1482,-1477,-1471,-1466,-1461,-1456,-1451, -1446,-1441,-1436,-1431,-1426,-1421,-1416,-1411,-1406,-1401,-1395,-1390,-1385,-1380, -1375,-1370,-1365,-1360,-1355,-1350,-1345,-1340,-1335,-1330,-1325,-1320,-1315,-1310, -1305,-1300,-1295,-1290,-1285,-1280,-1275,-1270,-1265,-1260,-1255,-1250,-1245,-1240, -1235,-1230,-1225,-1220,-1215,-1210,-1205,-1200,-1195,-1190,-1185,-1180,-1175,-1171, -1166,-1161,-1156,-1151,-1146,-1141,-1136,-1131,-1127,-1122,-1117,-1112,-1107,-1102, -1098,-1093,-1088,-1083,-1078,-1074,-1069,-1064,-1059,-1055,-1050,-1045,-1040,-1036, -1031,-1026,-1022,-1017,-1012,-1007,-1003,-998,-994,-989,-984,-980,-975,-970,-966, -961,-957,-952,-948,-943,-938,-934,-929,-925,-920,-916,-911,-907,-902,-898,-894, -889,-885,-880,-876,-872,-867,-863,-858,-854,-850,-845,-841,-837,-833,-828,-824, -820,-816,-811,-807,-803,-799,-795,-790,-786,-782,-778,-774,-770,-766,-762,-757, -753,-749,-745,-741,-737,-733,-729,-725,-721,-717,-714,-710,-706,-702,-698,-694, -690,-686,-683,-679,-675,-671,-667,-664,-660,-656,-652,-649,-645,-641,-638,-634, -630,-627,-623,-620,-616,-612,-609,-605,-602,-598,-595,-591,-588,-584,-581,-577, -574,-571,-567,-564,-560,-557,-554,-550,-547,-544,-540,-537,-534,-530,-527,-524, -521,-518,-514,-511,-508,-505,-502,-499,-495,-492,-489,-486,-483,-480,-477,-474, -471,-468,-465,-462,-459,-456,-453,-450,-447,-444,-441,-438,-435,-433,-430,-427, -424,-421,-418,-416,-413,-410,-407,-405,-402,-399,-396,-394,-391,-388,-386,-383, -380,-378,-375,-373,-370,-367,-365,-362,-360,-357,-355,-352,-350,-347,-345,-342, -340,-337,-335,-333,-330,-328,-325,-323,-321,-318,-316,-314,-311,-309,-307,-305, -302,-300,-298,-296,-293,-291,-289,-287,-285,-282,-280,-278,-276,-274,-272,-270, -268,-266,-264,-261,-259,-257,-255,-253,-251,-249,-247,-246,-244,-242,-240,-238, -236,-234,-232,-230,-228,-227,-225,-223,-221,-219,-217,-216,-214,-212,-210,-209, -207,-205,-203,-202,-200,-198,-197,-195,-193,-192,-190,-188,-187,-185,-184,-182, -180,-179,-177,-176,-174,-173,-171,-170,-168,-167,-165,-164,-162,-161,-159,-158, -156,-155,-154,-152,-151,-149,-148,-147,-145,-144,-143,-141,-140,-139,-137,-136, -135,-133,-132,-131,-130,-128,-127,-126,-125,-123,-122,-121,-120,-119,-117,-116, -115,-114,-113,-112,-111,-109,-108,-107,-106,-105,-104,-103,-102,-101,-100,-99,-98, -97,-96,-95,-94,-93,-92,-91,-90,-89,-88,-87,-86,-85,-84,-83,-82,-81,-80,-79,-78, -78,-77,-76,-75,-74,-73,-72,-71,-71,-70,-69,-68,-67,-67,-66,-65,-64,-63,-63,-62, -61,-60,-60,-59,-58,-58,-57,-56,-55,-55,-54,-53,-53,-52,-51,-51,-50,-49,-49,-48, -47,-47,-46,-45,-45,-44,-44,-43,-42,-42,-41,-41,-40,-40,-39,-38,-38,-37,-37,-36, -36,-35,-35,-34,-34,-33,-33,-32,-32,-31,-31,-30,-30,-29,-29,-28,-28,-28,-27,-27, -26,-26,-25,-25,-25,-24,-24,-23,-23,-23,-22,-22,-21,-21,-21,-20,-20,-20,-19,-19, -19,-18,-18,-17,-17,-17,-17,-16,-16,-16,-15,-15,-15,-14,-14,-14,-13,-13,-13,-13, -12,-12,-12,-12,-11,-11,-11,-11,-10,-10,-10,-10,-9,-9,-9,-9,-9,-8,-8,-8,-8,-7,-7, -7,-7,-7,-7,-6,-6,-6,-6,-6,-5,-5,-5,-5,-5,-5,-5,-4,-4,-4,-4,-4,-4,-4,-3,-3,-3,-3, -3,-3,-3,-3,-3,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } }; State::State(uint32 sampleRate) { double amigaClocksPerSample = static_cast(PAULA_HZ) / sampleRate; numSteps = static_cast(amigaClocksPerSample / MINIMUM_INTERVAL); stepRemainder = SamplePosition::FromDouble(amigaClocksPerSample - numSteps * MINIMUM_INTERVAL); remainder = SamplePosition(0); activeBleps = 0; globalOutputLevel = 0; } void State::Reset() { remainder = SamplePosition(0); activeBleps = 0; globalOutputLevel = 0; } void State::InputSample(int16 sample) { if(sample != globalOutputLevel) { LimitMax(activeBleps, static_cast(mpt::size(blepState) - 1)); // Make room for new blep in the sorted list std::move_backward(blepState, blepState + activeBleps, blepState + activeBleps + 1); // Start a new blep: level is the difference, age (or phase) is 0 clocks. activeBleps++; blepState[0].age = 0; blepState[0].level = sample - globalOutputLevel; globalOutputLevel = sample; } } // Return output simulated as series of bleps int State::OutputSample(bool filter) { int output = globalOutputLevel * (1 << Paula::BLEP_SCALE); for(uint16 i = 0; i < activeBleps; i++) { const auto &blep = blepState[i]; output -= WinSincIntegral[filter][blep.age] * blep.level; } output /= (1 << (Paula::BLEP_SCALE - 2)); // - 2 to compensate for the fact that we reduced the input sample bit depth return output; } // Advance the simulation by given number of clock ticks void State::Clock(int cycles) { for(uint16 i = 0; i < activeBleps; i++) { blepState[i].age += static_cast(cycles); if(blepState[i].age >= mpt::size(WinSincIntegral[0])) { activeBleps = i; return; } } } } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/ContainerMMCMP.cpp0000644000372100037210000002316213161656666021341 00000000000000/* * ContainerMMCMP.cpp * ------------------ * Purpose: Handling of MMCMP compressed modules * Notes : (currently none) * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "../common/FileReader.h" #include "Container.h" #include "Sndfile.h" #include OPENMPT_NAMESPACE_BEGIN //#define MMCMP_LOG struct MMCMPFILEHEADER { char id[8]; // "ziRCONia" uint16le hdrsize; }; MPT_BINARY_STRUCT(MMCMPFILEHEADER, 10) struct MMCMPHEADER { uint16le version; uint16le nblocks; uint32le filesize; uint32le blktable; uint8le glb_comp; uint8le fmt_comp; }; MPT_BINARY_STRUCT(MMCMPHEADER, 14) struct MMCMPBLOCK { uint32le unpk_size; uint32le pk_size; uint32le xor_chk; uint16le sub_blk; uint16le flags; uint16le tt_entries; uint16le num_bits; }; MPT_BINARY_STRUCT(MMCMPBLOCK, 20) struct MMCMPSUBBLOCK { uint32le unpk_pos; uint32le unpk_size; }; MPT_BINARY_STRUCT(MMCMPSUBBLOCK, 8) #define MMCMP_COMP 0x0001 #define MMCMP_DELTA 0x0002 #define MMCMP_16BIT 0x0004 #define MMCMP_STEREO 0x0100 #define MMCMP_ABS16 0x0200 #define MMCMP_ENDIAN 0x0400 struct MMCMPBITBUFFER { uint32 bitcount; uint32 bitbuffer; const uint8 *pSrc; uint32 bytesLeft; uint32 GetBits(uint32 nBits); }; uint32 MMCMPBITBUFFER::GetBits(uint32 nBits) { uint32 d; if (!nBits) return 0; while (bitcount < 24) { if(bytesLeft) { bitbuffer |= *pSrc << bitcount; pSrc++; bytesLeft--; } bitcount += 8; } d = bitbuffer & ((1 << nBits) - 1); bitbuffer >>= nBits; bitcount -= nBits; return d; } static const uint8 MMCMP8BitCommands[8] = { 0x01, 0x03, 0x07, 0x0F, 0x1E, 0x3C, 0x78, 0xF8 }; static const uint8 MMCMP8BitFetch[8] = { 3, 3, 3, 3, 2, 1, 0, 0 }; static const uint16 MMCMP16BitCommands[16] = { 0x01, 0x03, 0x07, 0x0F, 0x1E, 0x3C, 0x78, 0xF0, 0x1F0, 0x3F0, 0x7F0, 0xFF0, 0x1FF0, 0x3FF0, 0x7FF0, 0xFFF0 }; static const uint8 MMCMP16BitFetch[16] = { 4, 4, 4, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; static bool MMCMP_IsDstBlockValid(const std::vector &unpackedData, uint32 pos, uint32 len) { if(pos >= unpackedData.size()) return false; if(len > unpackedData.size()) return false; if(len > unpackedData.size() - pos) return false; return true; } static bool MMCMP_IsDstBlockValid(const std::vector &unpackedData, const MMCMPSUBBLOCK &subblk) { return MMCMP_IsDstBlockValid(unpackedData, subblk.unpk_pos, subblk.unpk_size); } static bool ValidateHeader(const MMCMPFILEHEADER &mfh) { if(std::memcmp(mfh.id, "ziRCONia", 8) != 0) { return false; } if(mfh.hdrsize != sizeof(MMCMPHEADER)) { return false; } return true; } static bool ValidateHeader(const MMCMPHEADER &mmh) { if(mmh.nblocks == 0) { return false; } if(mmh.filesize == 0) { return false; } if(mmh.filesize > 0x80000000) { return false; } return true; } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderMMCMP(MemoryFileReader file, const uint64 *pfilesize) { MMCMPFILEHEADER mfh; if(!file.ReadStruct(mfh)) { return ProbeWantMoreData; } if(!ValidateHeader(mfh)) { return ProbeFailure; } MMCMPHEADER mmh; if(!file.ReadStruct(mmh)) { return ProbeWantMoreData; } if(!ValidateHeader(mmh)) { return ProbeFailure; } MPT_UNREFERENCED_PARAMETER(pfilesize); return ProbeSuccess; } bool UnpackMMCMP(std::vector &containerItems, FileReader &file, ContainerLoadingFlags loadFlags) { file.Rewind(); containerItems.clear(); MMCMPFILEHEADER mfh; if(!file.ReadStruct(mfh)) { return false; } if(!ValidateHeader(mfh)) { return false; } MMCMPHEADER mmh; if(!file.ReadStruct(mmh)) { return false; } if(!ValidateHeader(mmh)) { return false; } if(loadFlags == ContainerOnlyVerifyHeader) { return true; } if(mmh.blktable > file.GetLength()) return false; if(mmh.blktable + 4 * mmh.nblocks > file.GetLength()) return false; containerItems.emplace_back(); containerItems.back().data_cache = mpt::make_unique >(); std::vector & unpackedData = *(containerItems.back().data_cache); unpackedData.resize(mmh.filesize); // 8-bit deltas uint8 ptable[256] = { 0 }; for (uint32 nBlock=0; nBlock subblks(blk.sub_blk); for(uint32 i=0; i 0 ? subblks.data() : nullptr; if(blkPos + sizeof(MMCMPBLOCK) + blk.sub_blk * sizeof(MMCMPSUBBLOCK) >= file.GetLength()) return false; uint32 memPos = blkPos + sizeof(MMCMPBLOCK) + blk.sub_blk * sizeof(MMCMPSUBBLOCK); #ifdef MMCMP_LOG Log("block %d: flags=%04X sub_blocks=%d", nBlock, (uint32)pblk->flags, (uint32)pblk->sub_blk); Log(" pksize=%d unpksize=%d", pblk->pk_size, pblk->unpk_size); Log(" tt_entries=%d num_bits=%d\n", pblk->tt_entries, pblk->num_bits); #endif // Data is not packed if (!(blk.flags & MMCMP_COMP)) { for (uint32 i=0; iunpk_pos, psubblk->unpk_size); #endif if(!file.Seek(memPos)) return false; if(file.ReadRaw(&(unpackedData[psubblk->unpk_pos]), psubblk->unpk_size) != psubblk->unpk_size) return false; psubblk++; } } else // Data is 16-bit packed if (blk.flags & MMCMP_16BIT) { MMCMPBITBUFFER bb; uint32 subblk = 0; if(!psubblk) return false; if(!MMCMP_IsDstBlockValid(unpackedData, psubblk[subblk])) return false; char *pDest = &(unpackedData[psubblk[subblk].unpk_pos]); uint32 dwSize = psubblk[subblk].unpk_size; uint32 dwPos = 0; uint32 numbits = blk.num_bits; uint32 oldval = 0; #ifdef MMCMP_LOG Log(" 16-bit block: pos=%d size=%d ", psubblk->unpk_pos, psubblk->unpk_size); if (pblk->flags & MMCMP_DELTA) Log("DELTA "); if (pblk->flags & MMCMP_ABS16) Log("ABS16 "); Log("\n"); #endif bb.bitcount = 0; bb.bitbuffer = 0; if(!file.Seek(memPos + blk.tt_entries)) return false; if(!file.CanRead(blk.pk_size - blk.tt_entries)) return false; bb.pSrc = file.GetRawData(); bb.bytesLeft = blk.pk_size - blk.tt_entries; while (subblk < blk.sub_blk) { uint32 newval = 0x10000; uint32 d = bb.GetBits(numbits+1); uint32 command = MMCMP16BitCommands[numbits & 0x0F]; if (d >= command) { uint32 nFetch = MMCMP16BitFetch[numbits & 0x0F]; uint32 newbits = bb.GetBits(nFetch) + ((d - command) << nFetch); if (newbits != numbits) { numbits = newbits & 0x0F; } else { if ((d = bb.GetBits(4)) == 0x0F) { if (bb.GetBits(1)) break; newval = 0xFFFF; } else { newval = 0xFFF0 + d; } } } else { newval = d; } if (newval < 0x10000) { newval = (newval & 1) ? (uint32)(-(int32)((newval+1) >> 1)) : (uint32)(newval >> 1); if (blk.flags & MMCMP_DELTA) { newval += oldval; oldval = newval; } else if (!(blk.flags & MMCMP_ABS16)) { newval ^= 0x8000; } pDest[dwPos + 0] = (uint8)(((uint16)newval) & 0xFF); pDest[dwPos + 1] = (uint8)(((uint16)newval) >> 8); dwPos += 2; } if (dwPos >= dwSize) { subblk++; dwPos = 0; if(!(subblk < blk.sub_blk)) break; if(!MMCMP_IsDstBlockValid(unpackedData, psubblk[subblk])) return false; dwSize = psubblk[subblk].unpk_size; pDest = &(unpackedData[psubblk[subblk].unpk_pos]); } } } else // Data is 8-bit packed { MMCMPBITBUFFER bb; uint32 subblk = 0; if(!psubblk) return false; if(!MMCMP_IsDstBlockValid(unpackedData, psubblk[subblk])) return false; char *pDest = &(unpackedData[psubblk[subblk].unpk_pos]); uint32 dwSize = psubblk[subblk].unpk_size; uint32 dwPos = 0; uint32 numbits = blk.num_bits; uint32 oldval = 0; if(blk.tt_entries > sizeof(ptable) || !file.Seek(memPos) || file.ReadRaw(ptable, blk.tt_entries) < blk.tt_entries) return false; bb.bitcount = 0; bb.bitbuffer = 0; if(!file.CanRead(blk.pk_size - blk.tt_entries)) return false; bb.pSrc = file.GetRawData(); bb.bytesLeft = blk.pk_size - blk.tt_entries; while (subblk < blk.sub_blk) { uint32 newval = 0x100; uint32 d = bb.GetBits(numbits+1); uint32 command = MMCMP8BitCommands[numbits & 0x07]; if (d >= command) { uint32 nFetch = MMCMP8BitFetch[numbits & 0x07]; uint32 newbits = bb.GetBits(nFetch) + ((d - command) << nFetch); if (newbits != numbits) { numbits = newbits & 0x07; } else { if ((d = bb.GetBits(3)) == 7) { if (bb.GetBits(1)) break; newval = 0xFF; } else { newval = 0xF8 + d; } } } else { newval = d; } if (newval < sizeof(ptable)) { int n = ptable[newval]; if (blk.flags & MMCMP_DELTA) { n += oldval; oldval = n; } pDest[dwPos++] = (uint8)n; } if (dwPos >= dwSize) { subblk++; dwPos = 0; if(!(subblk < blk.sub_blk)) break; if(!MMCMP_IsDstBlockValid(unpackedData, psubblk[subblk])) return false; dwSize = psubblk[subblk].unpk_size; pDest = &(unpackedData[psubblk[subblk].unpk_pos]); } } } } containerItems.back().file = FileReader(mpt::byte_cast(mpt::as_span(unpackedData))); return true; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Load_stp.cpp0000644000372100037210000005153213235357756020374 00000000000000/* * Load_stp.cpp * ------------ * Purpose: STP (Soundtracker Pro II) module loader * Notes : A few exotic effects aren't supported. * Multiple sample loops are supported, but only the first 10 can be used as cue points * (with 16xx and 18xx). * Fractional speed values and combined auto effects are handled whenever possible, * but some effects may be omitted (and there may be tempo accuracy issues). * Authors: Devin Acker * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. * * Wisdom from the Soundtracker Pro II manual: * "To create shorter patterns, simply create shorter patterns." */ #include "stdafx.h" #include "Loaders.h" OPENMPT_NAMESPACE_BEGIN // File header struct STPFileHeader { char magic[4]; uint16be version; uint8be numOrders; uint8be patternLength; uint8be orderList[128]; uint16be speed; uint16be speedFrac; uint16be timerCount; uint16be flags; uint32be reserved; uint16be midiCount; // always 50 uint8be midi[50]; uint16be numSamples; uint16be sampleStructSize; }; MPT_BINARY_STRUCT(STPFileHeader, 204) // Sample header (common part between all versions) struct STPSampleHeader { uint32be length; uint8be volume; uint8be reserved1; uint32be loopStart; uint32be loopLength; uint16be defaultCommand; // Default command to put next to note when editing patterns; not relevant for playback // The following 4 bytes are reserved in version 0 and 1. uint16be defaultPeriod; uint8be finetune; uint8be reserved2; void ConvertToMPT(ModSample &mptSmp) const { mptSmp.nLength = length; mptSmp.nVolume = 4u * std::min(volume, 64); mptSmp.nLoopStart = loopStart; mptSmp.nLoopEnd = loopStart + loopLength; if(mptSmp.nLoopStart >= mptSmp.nLength) { mptSmp.nLoopStart = mptSmp.nLength - 1; } if(mptSmp.nLoopEnd > mptSmp.nLength) { mptSmp.nLoopEnd = mptSmp.nLength; } if(mptSmp.nLoopStart > mptSmp.nLoopEnd) { mptSmp.nLoopStart = 0; mptSmp.nLoopEnd = 0; } else if(mptSmp.nLoopEnd > mptSmp.nLoopStart) { mptSmp.uFlags.set(CHN_LOOP); mptSmp.cues[0] = mptSmp.nLoopStart; } } }; MPT_BINARY_STRUCT(STPSampleHeader, 20) struct STPLoopInfo { SmpLength loopStart; SmpLength loopLength; SAMPLEINDEX looped; SAMPLEINDEX nonLooped; }; typedef std::vector STPLoopList; static TEMPO ConvertTempo(uint16 ciaSpeed) { // 3546 is the resulting CIA timer value when using 4F7D (tempo 125 bpm) command in STProII return TEMPO((125.0 * 3546.0) / ciaSpeed); } static void ConvertLoopSlice(ModSample &src, ModSample &dest, SmpLength start, SmpLength len, bool loop) { if(!src.HasSampleData() || start >= src.nLength || src.nLength - start < len) { return; } dest.FreeSample(); dest = src; dest.nLength = len; dest.pSample = nullptr; if(!dest.AllocateSample()) { return; } // only preserve cue points if the target sample length is the same if(len != src.nLength) MemsetZero(dest.cues); std::memcpy(dest.pSample8, src.pSample8 + start, len); dest.uFlags.set(CHN_LOOP, loop); if(loop) { dest.nLoopStart = 0; dest.nLoopEnd = len; } else { dest.nLoopStart = 0; dest.nLoopEnd = 0; } } static void ConvertLoopSequence(ModSample &smp, STPLoopList &loopList) { // This should only modify a sample if it has more than one loop // (otherwise, it behaves like a normal sample loop) if(!smp.HasSampleData() || loopList.size() < 2) return; ModSample newSmp = smp; newSmp.nLength = 0; newSmp.pSample = nullptr; size_t numLoops = loopList.size(); // Get the total length of the sample after combining all looped sections for(size_t i = 0; i < numLoops; i++) { STPLoopInfo &info = loopList[i]; // If adding this loop would cause the sample length to exceed maximum, // then limit and bail out if(info.loopStart >= smp.nLength || smp.nLength - info.loopStart < info.loopLength || newSmp.nLength > MAX_SAMPLE_LENGTH - info.loopLength) { numLoops = i; break; } newSmp.nLength += info.loopLength; } if(!newSmp.AllocateSample()) { return; } // start copying the looped sample data parts SmpLength start = 0; for(size_t i = 0; i < numLoops; i++) { STPLoopInfo &info = loopList[i]; memcpy(newSmp.pSample8 + start, smp.pSample8 + info.loopStart, info.loopLength); // update loop info based on position in edited sample info.loopStart = start; if(i > 0 && i <= mpt::size(newSmp.cues)) { newSmp.cues[i - 1] = start; } start += info.loopLength; } // replace old sample with new one smp.FreeSample(); smp = newSmp; smp.nLoopStart = 0; smp.nLoopEnd = smp.nLength; smp.uFlags.set(CHN_LOOP); } static bool ValidateHeader(const STPFileHeader &fileHeader) { if(std::memcmp(fileHeader.magic, "STP3", 4) || fileHeader.version > 2 || fileHeader.numOrders > 128 || fileHeader.numSamples >= MAX_SAMPLES || fileHeader.timerCount == 0 || fileHeader.midiCount != 50) { return false; } return true; } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderSTP(MemoryFileReader file, const uint64 *pfilesize) { STPFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return ProbeWantMoreData; } if(!ValidateHeader(fileHeader)) { return ProbeFailure; } MPT_UNREFERENCED_PARAMETER(pfilesize); return ProbeSuccess; } bool CSoundFile::ReadSTP(FileReader &file, ModLoadingFlags loadFlags) { file.Rewind(); STPFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return false; } if(!ValidateHeader(fileHeader)) { return false; } if(loadFlags == onlyVerifyHeader) { return true; } InitializeGlobals(MOD_TYPE_STP); m_nChannels = 4; m_nSamples = 0; m_nDefaultSpeed = fileHeader.speed; m_nDefaultTempo = ConvertTempo(fileHeader.timerCount); m_nMinPeriod = 14 * 4; m_nMaxPeriod = 3424 * 4; ReadOrderFromArray(Order(), fileHeader.orderList, fileHeader.numOrders); std::vector loopInfo; // Non-looped versions of samples with loops (when needed) std::vector nonLooped; // Load sample headers SAMPLEINDEX samplesInFile = 0; for(SAMPLEINDEX smp = 0; smp < fileHeader.numSamples; smp++) { SAMPLEINDEX actualSmp = file.ReadUint16BE(); if(actualSmp == 0 || actualSmp >= MAX_SAMPLES) return false; uint32 chunkSize = fileHeader.sampleStructSize; if(fileHeader.version == 2) chunkSize = file.ReadUint32BE() - 2; FileReader chunk = file.ReadChunk(chunkSize); samplesInFile = m_nSamples = std::max(m_nSamples, actualSmp); ModSample &mptSmp = Samples[actualSmp]; mptSmp.Initialize(MOD_TYPE_MOD); if(fileHeader.version < 2) { // Read path chunk.ReadString(mptSmp.filename, 31); // Ignore flags, they are all not relevant for us chunk.Skip(1); // Read filename / sample text chunk.ReadString(m_szNames[actualSmp], 30); } else { std::string str; // Read path chunk.ReadNullString(str, 257); mpt::String::Copy(mptSmp.filename, str); // Ignore flags, they are all not relevant for us chunk.Skip(1); // Read filename / sample text chunk.ReadNullString(str, 31); mpt::String::Copy(m_szNames[actualSmp], str); // Seek to even boundary if(chunk.GetPosition() % 2u) chunk.Skip(1); } STPSampleHeader sampleHeader; chunk.ReadStruct(sampleHeader); sampleHeader.ConvertToMPT(mptSmp); if(fileHeader.version == 2) { mptSmp.nFineTune = static_cast(sampleHeader.finetune << 3); } if(fileHeader.version >= 1) { nonLooped.resize(samplesInFile); loopInfo.resize(samplesInFile); STPLoopList &loopList = loopInfo[actualSmp - 1]; loopList.clear(); uint16 numLoops = file.ReadUint16BE(); loopList.reserve(numLoops); STPLoopInfo loop; loop.looped = loop.nonLooped = 0; if(numLoops == 0 && mptSmp.uFlags[CHN_LOOP]) { loop.loopStart = mptSmp.nLoopStart; loop.loopLength = mptSmp.nLoopEnd - mptSmp.nLoopStart; loopList.push_back(loop); } else for(uint16 i = 0; i < numLoops; i++) { loop.loopStart = file.ReadUint32BE(); loop.loopLength = file.ReadUint32BE(); loopList.push_back(loop); } } } // Load patterns uint16 numPatterns = 128; if(fileHeader.version == 0) numPatterns = file.ReadUint16BE(); uint16 patternLength = fileHeader.patternLength; CHANNELINDEX channels = 4; if(fileHeader.version > 0) { // Scan for total number of channels FileReader::off_t patOffset = file.GetPosition(); for(uint16 pat = 0; pat < numPatterns; pat++) { PATTERNINDEX actualPat = file.ReadUint16BE(); if(actualPat == 0xFFFF) break; patternLength = file.ReadUint16BE(); channels = file.ReadUint16BE(); m_nChannels = std::max(m_nChannels, channels); file.Skip(channels * patternLength * 4u); } file.Seek(patOffset); if(m_nChannels > MAX_BASECHANNELS) return false; } struct ChannelMemory { uint8 autoFinePorta, autoPortaUp, autoPortaDown, autoVolSlide, autoVibrato; uint8 vibratoMem, autoTremolo, autoTonePorta, tonePortaMem; }; std::vector channelMemory(m_nChannels); uint8 globalVolSlide = 0; uint8 speedFrac = static_cast(fileHeader.speedFrac); for(uint16 pat = 0; pat < numPatterns; pat++) { PATTERNINDEX actualPat = pat; if(fileHeader.version > 0) { actualPat = file.ReadUint16BE(); if(actualPat == 0xFFFF) break; patternLength = file.ReadUint16BE(); channels = file.ReadUint16BE(); } if(!(loadFlags & loadPatternData) || !Patterns.Insert(actualPat, patternLength)) { file.Skip(channels * patternLength * 4u); continue; } for(ROWINDEX row = 0; row < patternLength; row++) { auto rowBase = Patterns[actualPat].GetRow(row); bool didGlobalVolSlide = false; // if a fractional speed value is in use then determine if we should stick a fine pattern delay somewhere bool shouldDelay; switch(speedFrac & 3) { default: shouldDelay = false; break; // 1/4 case 1: shouldDelay = (row & 3) == 0; break; // 1/2 case 2: shouldDelay = (row & 1) == 0; break; // 3/4 case 3: shouldDelay = (row & 3) != 3; break; } for(CHANNELINDEX chn = 0; chn < channels; chn++) { ChannelMemory &chnMem = channelMemory[chn]; ModCommand &m = rowBase[chn]; uint8 data[4]; file.ReadArray(data); m.instr = data[0]; m.note = data[1]; m.command = data[2]; m.param = data[3]; if(m.note) { m.note += 24 + NOTE_MIN; chnMem = ChannelMemory(); } // this is a nibble-swapped param value used for auto fine volside // and auto global fine volside uint8 swapped = (m.param >> 4) | (m.param << 4); if((m.command & 0xF0) == 0xF0) { // 12-bit CIA tempo uint16 ciaTempo = (static_cast(m.command & 0x0F) << 8) | m.param; if(ciaTempo) { m.param = mpt::saturate_cast(Util::Round(ConvertTempo(ciaTempo).ToDouble())); m.command = CMD_TEMPO; } else { m.command = CMD_NONE; } } else switch(m.command) { case 0x00: // arpeggio if(m.param) m.command = CMD_ARPEGGIO; break; case 0x01: // portamento up m.command = CMD_PORTAMENTOUP; break; case 0x02: // portamento down m.command = CMD_PORTAMENTODOWN; break; case 0x03: // auto fine portamento up chnMem.autoFinePorta = 0x10 | std::min(m.param, ModCommand::PARAM(15)); chnMem.autoPortaUp = 0; chnMem.autoPortaDown = 0; chnMem.autoTonePorta = 0; m.command = CMD_NONE; break; case 0x04: // auto fine portamento down chnMem.autoFinePorta = 0x20 | std::min(m.param, ModCommand::PARAM(15)); chnMem.autoPortaUp = 0; chnMem.autoPortaDown = 0; chnMem.autoTonePorta = 0; m.command = CMD_NONE; break; case 0x05: // auto portamento up chnMem.autoFinePorta = 0; chnMem.autoPortaUp = m.param; chnMem.autoPortaDown = 0; chnMem.autoTonePorta = 0; m.command = CMD_NONE; break; case 0x06: // auto portamento down chnMem.autoFinePorta = 0; chnMem.autoPortaUp = 0; chnMem.autoPortaDown = m.param; chnMem.autoTonePorta = 0; m.command = CMD_NONE; break; case 0x07: // set global volume m.command = CMD_GLOBALVOLUME; globalVolSlide = 0; break; case 0x08: // auto global fine volume slide globalVolSlide = swapped; m.command = CMD_NONE; break; case 0x09: // fine portamento up m.command = CMD_MODCMDEX; m.param = 0x10 | std::min(m.param, ModCommand::PARAM(15)); break; case 0x0A: // fine portamento down m.command = CMD_MODCMDEX; m.param = 0x20 | std::min(m.param, ModCommand::PARAM(15)); break; case 0x0B: // auto fine volume slide chnMem.autoVolSlide = swapped; m.command = CMD_NONE; break; case 0x0C: // set volume m.volcmd = VOLCMD_VOLUME; m.vol = m.param; chnMem.autoVolSlide = 0; m.command = CMD_NONE; break; case 0x0D: // volume slide (param is swapped compared to .mod) if(m.param & 0xF0) { m.volcmd = VOLCMD_VOLSLIDEDOWN; m.vol = m.param >> 4; } else if(m.param & 0x0F) { m.volcmd = VOLCMD_VOLSLIDEUP; m.vol = m.param & 0xF; } chnMem.autoVolSlide = 0; m.command = CMD_NONE; break; case 0x0E: // set filter (also uses opposite value compared to .mod) m.command = CMD_MODCMDEX; m.param = 1 ^ (m.param ? 1 : 0); break; case 0x0F: // set speed m.command = CMD_SPEED; speedFrac = m.param & 0x0F; m.param >>= 4; break; case 0x10: // auto vibrato chnMem.autoVibrato = m.param; chnMem.vibratoMem = 0; m.command = CMD_NONE; break; case 0x11: // auto tremolo if(m.param & 0xF) chnMem.autoTremolo = m.param; else chnMem.autoTremolo = 0; m.command = CMD_NONE; break; case 0x12: // pattern break m.command = CMD_PATTERNBREAK; break; case 0x13: // auto tone portamento chnMem.autoFinePorta = 0; chnMem.autoPortaUp = 0; chnMem.autoPortaDown = 0; chnMem.autoTonePorta = m.param; chnMem.tonePortaMem = 0; m.command = CMD_NONE; break; case 0x14: // position jump m.command = CMD_POSITIONJUMP; break; case 0x16: // start loop sequence if(m.instr && m.instr <= loopInfo.size()) { STPLoopList &loopList = loopInfo[m.instr - 1]; m.param--; if(m.param < std::min(mpt::size(ModSample().cues), loopList.size())) { m.volcmd = VOLCMD_OFFSET; m.vol = m.param; } } m.command = CMD_NONE; break; case 0x17: // play only loop nn if(m.instr && m.instr <= loopInfo.size()) { STPLoopList &loopList = loopInfo[m.instr - 1]; m.param--; if(m.param < loopList.size()) { if(!loopList[m.param].looped && m_nSamples < MAX_SAMPLES - 1) loopList[m.param].looped = ++m_nSamples; m.instr = static_cast(loopList[m.param].looped); } } m.command = CMD_NONE; break; case 0x18: // play sequence without loop if(m.instr && m.instr <= loopInfo.size()) { STPLoopList &loopList = loopInfo[m.instr - 1]; m.param--; if(m.param < std::min(mpt::size(ModSample().cues), loopList.size())) { m.volcmd = VOLCMD_OFFSET; m.vol = m.param; } // switch to non-looped version of sample and create it if needed if(!nonLooped[m.instr - 1] && m_nSamples < MAX_SAMPLES - 1) nonLooped[m.instr - 1] = ++m_nSamples; m.instr = static_cast(nonLooped[m.instr - 1]); } m.command = CMD_NONE; break; case 0x19: // play only loop nn without loop if(m.instr && m.instr <= loopInfo.size()) { STPLoopList &loopList = loopInfo[m.instr - 1]; m.param--; if(m.param < loopList.size()) { if(!loopList[m.param].nonLooped && m_nSamples < MAX_SAMPLES-1) loopList[m.param].nonLooped = ++m_nSamples; m.instr = static_cast(loopList[m.param].nonLooped); } } m.command = CMD_NONE; break; case 0x1D: // fine volume slide (nibble order also swapped) m.command = CMD_VOLUMESLIDE; m.param = swapped; if(m.param & 0xF0) // slide down m.param |= 0x0F; else if(m.param & 0x0F) m.param |= 0xF0; break; case 0x20: // "delayed fade" // just behave like either a normal fade or a notecut // depending on the speed if(m.param & 0xF0) { chnMem.autoVolSlide = m.param >> 4; m.command = CMD_NONE; } else { m.command = CMD_MODCMDEX; m.param = 0xC0 | (m.param & 0xF); } break; case 0x21: // note delay m.command = CMD_MODCMDEX; m.param = 0xD0 | std::min(m.param, ModCommand::PARAM(15)); break; case 0x22: // retrigger note m.command = CMD_MODCMDEX; m.param = 0x90 | std::min(m.param, ModCommand::PARAM(15)); break; case 0x49: // set sample offset m.command = CMD_OFFSET; break; case 0x4E: // other protracker commands (pattern loop / delay) if((m.param & 0xF0) == 0x60 || (m.param & 0xF0) == 0xE0) m.command = CMD_MODCMDEX; else m.command = CMD_NONE; break; case 0x4F: // set speed/tempo if(m.param < 0x20) { m.command = CMD_SPEED; speedFrac = 0; } else { m.command = CMD_TEMPO; } break; default: m.command = CMD_NONE; break; } bool didVolSlide = false; // try to put volume slide in volume command if(chnMem.autoVolSlide && m.volcmd == VOLCMD_NONE) { if(chnMem.autoVolSlide & 0xF0) { m.volcmd = VOLCMD_FINEVOLUP; m.vol = chnMem.autoVolSlide >> 4; } else { m.volcmd = VOLCMD_FINEVOLDOWN; m.vol = chnMem.autoVolSlide & 0xF; } didVolSlide = true; } // try to place/combine all remaining running effects. if(m.command == CMD_NONE) { if(chnMem.autoPortaUp) { m.command = CMD_PORTAMENTOUP; m.param = chnMem.autoPortaUp; } else if(chnMem.autoPortaDown) { m.command = CMD_PORTAMENTODOWN; m.param = chnMem.autoPortaDown; } else if(chnMem.autoFinePorta) { m.command = CMD_MODCMDEX; m.param = chnMem.autoFinePorta; } else if(chnMem.autoTonePorta) { m.command = CMD_TONEPORTAMENTO; m.param = chnMem.tonePortaMem = chnMem.autoTonePorta; } else if(chnMem.autoVibrato) { m.command = CMD_VIBRATO; m.param = chnMem.vibratoMem = chnMem.autoVibrato; } else if(!didVolSlide && chnMem.autoVolSlide) { m.command = CMD_VOLUMESLIDE; m.param = chnMem.autoVolSlide; // convert to a "fine" value by setting the other nibble to 0xF if(m.param & 0x0F) m.param |= 0xF0; else if(m.param & 0xF0) m.param |= 0x0F; didVolSlide = true; } else if(chnMem.autoTremolo) { m.command = CMD_TREMOLO; m.param = chnMem.autoTremolo; } else if(shouldDelay) { // insert a fine pattern delay here m.command = CMD_S3MCMDEX; m.param = 0x61; shouldDelay = false; } else if(!didGlobalVolSlide && globalVolSlide) { m.command = CMD_GLOBALVOLSLIDE; m.param = globalVolSlide; // convert to a "fine" value by setting the other nibble to 0xF if(m.param & 0x0F) m.param |= 0xF0; else if(m.param & 0xF0) m.param |= 0x0F; didGlobalVolSlide = true; } } } // TODO: create/use extra channels for global volslide/delay if needed } } // after we know how many channels there really are... m_nSamplePreAmp = 256 / m_nChannels; // Setup channel pan positions and volume SetupMODPanning(true); // Skip over scripts and drumpad info if(fileHeader.version > 0) { while(file.CanRead(2)) { uint16 scriptNum = file.ReadUint16BE(); if(scriptNum == 0xFFFF) break; file.Skip(2); uint32 length = file.ReadUint32BE(); file.Skip(length); } // Skip drumpad stuff file.Skip(17 * 2); } // Reading samples if(loadFlags & loadSampleData) { for(SAMPLEINDEX smp = 1; smp <= samplesInFile; smp++) if(Samples[smp].nLength) { SampleIO( SampleIO::_8bit, SampleIO::mono, SampleIO::littleEndian, SampleIO::signedPCM) .ReadSample(Samples[smp], file); if(smp > loopInfo.size()) continue; ConvertLoopSequence(Samples[smp], loopInfo[smp - 1]); // make a non-looping duplicate of this sample if needed if(nonLooped[smp - 1]) { ConvertLoopSlice(Samples[smp], Samples[nonLooped[smp - 1]], 0, Samples[smp].nLength, false); } for(const auto &info : loopInfo[smp - 1]) { // make duplicate samples for this individual section if needed if(info.looped) { ConvertLoopSlice(Samples[smp], Samples[info.looped], info.loopStart, info.loopLength, true); } if(info.nonLooped) { ConvertLoopSlice(Samples[smp], Samples[info.nonLooped], info.loopStart, info.loopLength, false); } } } } return true; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/SampleIO.cpp0000644000372100037210000011641713161656666020304 00000000000000/* * SampleIO.cpp * ------------ * Purpose: Central code for reading and writing samples. Create your SampleIO object and have a go at the ReadSample and WriteSample functions! * Notes : Not all combinations of possible sample format combinations are implemented, especially for WriteSample. * Using the existing generic functions, it should be quite easy to extend the code, though. * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" #include "SampleIO.h" #include "../soundbase/SampleFormatConverters.h" #include "../soundbase/SampleFormatCopy.h" #include "ModSampleCopy.h" #include "ITCompression.h" #include "../common/mptIO.h" #ifndef MODPLUG_NO_FILESAVE #include "../common/mptFileIO.h" #endif #include OPENMPT_NAMESPACE_BEGIN // Sample decompression routines in other source files void AMSUnpack(const int8 * const source, size_t sourceSize, void * const dest, const size_t destSize, char packCharacter); uint8 MDLReadBits(uint32 &bitbuf, int32 &bitnum, const uint8 *(&ibuf), size_t &bytesLeft, int8 n); uintptr_t DMFUnpack(uint8 *psample, const uint8 *ibuf, const uint8 *ibufmax, uint32 maxlen); // Read a sample from memory size_t SampleIO::ReadSample(ModSample &sample, FileReader &file) const { if(!file.IsValid()) { return 0; } LimitMax(sample.nLength, MAX_SAMPLE_LENGTH); FileReader::off_t bytesRead = 0; // Amount of memory that has been read from file FileReader::off_t filePosition = file.GetPosition(); const mpt::byte * sourceBuf = nullptr; FileReader::PinnedRawDataView restrictedSampleDataView; FileReader::off_t fileSize = 0; if(UsesFileReaderForDecoding()) { sourceBuf = nullptr; fileSize = file.BytesLeft(); } else if(!IsVariableLengthEncoded()) { restrictedSampleDataView = file.GetPinnedRawDataView(CalculateEncodedSize(sample.nLength)); sourceBuf = restrictedSampleDataView.data(); fileSize = restrictedSampleDataView.size(); } else { // Only DMF sample compression encoding should fall in this case, MPT_ASSERT(GetEncoding() == DMF); // file is guaranteed by the caller to be ONLY data for this sample, // it is thus efficient to create a view to the whole file object. // See MPT_ASSERT with fileSize below. restrictedSampleDataView = file.GetPinnedRawDataView(); sourceBuf = restrictedSampleDataView.data(); fileSize = restrictedSampleDataView.size(); } if(!IsVariableLengthEncoded() && sample.nLength > 0x40000) { // Limit sample length to available bytes in file to avoid excessive memory allocation. // However, for ProTracker MODs we need to support samples exceeding the end of file // (see the comment about MOD.shorttune2 in Load_mod.cpp), so as a semi-arbitrary threshold, // we do not apply this limit to samples shorter than 256K. size_t maxLength = fileSize - std::min(GetEncodedHeaderSize(), fileSize); uint8 bps = GetEncodedBitsPerSample(); if(bps % 8u != 0) { MPT_ASSERT(GetEncoding() == ADPCM && bps == 4); if(Util::MaxValueOfType(maxLength) / 2u >= maxLength) maxLength *= 2; else maxLength = Util::MaxValueOfType(maxLength); } else { size_t encodedBytesPerSample = GetNumChannels() * GetEncodedBitsPerSample() / 8u; // Check if we can round up without overflowing if(Util::MaxValueOfType(maxLength) - maxLength >= (encodedBytesPerSample - 1u)) maxLength += encodedBytesPerSample - 1u; else maxLength = Util::MaxValueOfType(maxLength); maxLength /= encodedBytesPerSample; } LimitMax(sample.nLength, mpt::saturate_cast(maxLength)); } if(sample.nLength < 1) { return 0; } sample.uFlags.set(CHN_16BIT, GetBitDepth() >= 16); sample.uFlags.set(CHN_STEREO, GetChannelFormat() != mono); size_t sampleSize = sample.AllocateSample(); // Target sample size in bytes if(sampleSize == 0) { sample.nLength = 0; return 0; } MPT_ASSERT(sampleSize >= sample.GetSampleSizeInBytes()); ////////////////////////////////////////////////////// // Compressed samples if(*this == SampleIO(_8bit, mono, littleEndian, ADPCM)) { // 4-Bit ADPCM data int8 compressionTable[16]; // ADPCM Compression LUT if(file.ReadArray(compressionTable)) { size_t readLength = (sample.nLength + 1) / 2; LimitMax(readLength, file.BytesLeft()); const uint8 *inBuf = mpt::byte_cast(sourceBuf) + sizeof(compressionTable); int8 *outBuf = sample.pSample8; int8 delta = 0; for(size_t i = readLength; i != 0; i--) { delta += compressionTable[*inBuf & 0x0F]; *(outBuf++) = delta; delta += compressionTable[(*inBuf >> 4) & 0x0F]; *(outBuf++) = delta; inBuf++; } bytesRead = sizeof(compressionTable) + readLength; } } else if(GetEncoding() == IT214 || GetEncoding() == IT215) { // IT 2.14 / 2.15 compressed samples ITDecompression(file, sample, GetEncoding() == IT215); bytesRead = file.GetPosition() - filePosition; } else if(GetEncoding() == AMS && GetChannelFormat() == mono) { // AMS compressed samples if(fileSize > 9) { file.Skip(4); // Target sample size (we already know this) uint32 sourceSize = file.ReadUint32LE(); int8 packCharacter = file.ReadUint8(); bytesRead += 9; FileReader::PinnedRawDataView packedDataView = file.ReadPinnedRawDataView(sourceSize); LimitMax(sourceSize, mpt::saturate_cast(packedDataView.size())); bytesRead += sourceSize; AMSUnpack(reinterpret_cast(packedDataView.data()), packedDataView.size(), sample.pSample, sample.GetSampleSizeInBytes(), packCharacter); } } else if(GetEncoding() == PTM8Dto16 && GetChannelFormat() == mono && GetBitDepth() == 16) { // PTM 8-Bit delta to 16-Bit sample bytesRead = CopyMonoSample(sample, sourceBuf, fileSize); } else if(GetEncoding() == MDL && GetChannelFormat() == mono && GetBitDepth() <= 16) { // Huffman MDL compressed samples if(file.CanRead(8) && (fileSize = file.ReadUint32LE()) >= 4) { FileReader chunk = file.ReadChunk(fileSize); bytesRead = chunk.GetLength() + 4; uint32 bitBuf = chunk.ReadUint32LE(); int32 bitNum = 32; restrictedSampleDataView = chunk.GetPinnedRawDataView(); sourceBuf = restrictedSampleDataView.data(); const uint8 *inBuf = reinterpret_cast(sourceBuf); size_t bytesLeft = chunk.BytesLeft(); uint8 dlt = 0, lowbyte = 0; const bool is16bit = GetBitDepth() == 16; try { for(SmpLength j = 0; j < sample.nLength; j++) { uint8 hibyte; if(is16bit) { lowbyte = MDLReadBits(bitBuf, bitNum, inBuf, bytesLeft, 8); } bool sign = MDLReadBits(bitBuf, bitNum, inBuf, bytesLeft, 1) != 0; if(MDLReadBits(bitBuf, bitNum, inBuf, bytesLeft, 1)) { hibyte = MDLReadBits(bitBuf, bitNum, inBuf, bytesLeft, 3); } else { hibyte = 8; while(!MDLReadBits(bitBuf, bitNum, inBuf, bytesLeft, 1)) { hibyte += 0x10; } hibyte += MDLReadBits(bitBuf, bitNum, inBuf, bytesLeft, 4); } if(sign) { hibyte = ~hibyte; } dlt += hibyte; if(!is16bit) { sample.pSample8[j] = dlt; } else { sample.pSample16[j] = lowbyte | (dlt << 8); } } } catch(const std::range_error &) { // Data is not sufficient to decode the whole sample //AddToLog(LogWarning, "Truncated MDL sample block"); } } } else if(GetEncoding() == DMF && GetChannelFormat() == mono && GetBitDepth() <= 16) { // DMF Huffman compression if(fileSize > 4) { const uint8 *inBuf = mpt::byte_cast(sourceBuf); const uint8 *inBufMax = inBuf + fileSize; uint8 *outBuf = static_cast(sample.pSample); bytesRead = DMFUnpack(outBuf, inBuf, inBufMax, sample.GetSampleSizeInBytes()); // This assertion ensures that, when using variable length samples, // the caller actually provided a trimmed chunk to read the sample data from. // This is required as we cannot know the encoded sample data size upfront // to construct a properly sized pinned view. MPT_ASSERT(bytesRead == fileSize); } #ifdef MODPLUG_TRACKER } else if((GetEncoding() == uLaw || GetEncoding() == aLaw) && GetBitDepth() == 16 && (GetChannelFormat() == mono || GetChannelFormat() == stereoInterleaved)) { // 8-to-16 bit G.711 u-law / a-law static const int16 uLawTable[256] = { -32124,-31100,-30076,-29052,-28028,-27004,-25980,-24956, -23932,-22908,-21884,-20860,-19836,-18812,-17788,-16764, -15996,-15484,-14972,-14460,-13948,-13436,-12924,-12412, -11900,-11388,-10876,-10364, -9852, -9340, -8828, -8316, -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140, -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092, -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004, -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980, -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436, -1372, -1308, -1244, -1180, -1116, -1052, -988, -924, -876, -844, -812, -780, -748, -716, -684, -652, -620, -588, -556, -524, -492, -460, -428, -396, -372, -356, -340, -324, -308, -292, -276, -260, -244, -228, -212, -196, -180, -164, -148, -132, -120, -112, -104, -96, -88, -80, -72, -64, -56, -48, -40, -32, -24, -16, -8, -1, 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956, 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764, 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412, 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316, 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140, 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092, 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004, 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980, 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436, 1372, 1308, 1244, 1180, 1116, 1052, 988, 924, 876, 844, 812, 780, 748, 716, 684, 652, 620, 588, 556, 524, 492, 460, 428, 396, 372, 356, 340, 324, 308, 292, 276, 260, 244, 228, 212, 196, 180, 164, 148, 132, 120, 112, 104, 96, 88, 80, 72, 64, 56, 48, 40, 32, 24, 16, 8, 0, }; static const int16 aLawTable[256] = { -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736, -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784, -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368, -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392, -22016,-20992,-24064,-23040,-17920,-16896,-19968,-18944, -30208,-29184,-32256,-31232,-26112,-25088,-28160,-27136, -11008,-10496,-12032,-11520, -8960, -8448, -9984, -9472, -15104,-14592,-16128,-15616,-13056,-12544,-14080,-13568, -344, -328, -376, -360, -280, -264, -312, -296, -472, -456, -504, -488, -408, -392, -440, -424, -88, -72, -120, -104, -24, -8, -56, -40, -216, -200, -248, -232, -152, -136, -184, -168, -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184, -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696, -688, -656, -752, -720, -560, -528, -624, -592, -944, -912, -1008, -976, -816, -784, -880, -848, 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736, 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784, 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368, 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392, 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944, 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136, 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472, 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568, 344, 328, 376, 360, 280, 264, 312, 296, 472, 456, 504, 488, 408, 392, 440, 424, 88, 72, 120, 104, 24, 8, 56, 40, 216, 200, 248, 232, 152, 136, 184, 168, 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184, 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696, 688, 656, 752, 720, 560, 528, 624, 592, 944, 912, 1008, 976, 816, 784, 880, 848, }; const int16 *lut = GetEncoding() == uLaw ? uLawTable : aLawTable; SmpLength readLength = sample.nLength * GetNumChannels(); LimitMax(readLength, file.BytesLeft()); bytesRead = readLength; const uint8 *inBuf = mpt::byte_cast(sourceBuf); int16 *outBuf = sample.pSample16; while(readLength--) { *(outBuf++) = lut[*(inBuf++)]; } #endif // MODPLUG_TRACKER } ///////////////////////// // Uncompressed samples ////////////////////////////////////////////////////// // 8-Bit / Mono / PCM else if(GetBitDepth() == 8 && GetChannelFormat() == mono) { switch(GetEncoding()) { case signedPCM: // 8-Bit / Mono / Signed / PCM bytesRead = CopyMonoSample(sample, sourceBuf, fileSize); break; case unsignedPCM: // 8-Bit / Mono / Unsigned / PCM bytesRead = CopyMonoSample(sample, sourceBuf, fileSize); break; case deltaPCM: // 8-Bit / Mono / Delta / PCM case MT2: bytesRead = CopyMonoSample(sample, sourceBuf, fileSize); break; case PCM7to8: // 7 Bit stored as 8-Bit with highest bit unused / Mono / Signed / PCM bytesRead = CopyMonoSample(sample, sourceBuf, fileSize); break; default: MPT_ASSERT_NOTREACHED(); break; } } ////////////////////////////////////////////////////// // 8-Bit / Stereo Split / PCM else if(GetBitDepth() == 8 && GetChannelFormat() == stereoSplit) { switch(GetEncoding()) { case signedPCM: // 8-Bit / Stereo Split / Signed / PCM bytesRead = CopyStereoSplitSample(sample, sourceBuf, fileSize); break; case unsignedPCM: // 8-Bit / Stereo Split / Unsigned / PCM bytesRead = CopyStereoSplitSample(sample, sourceBuf, fileSize); break; case deltaPCM: // 8-Bit / Stereo Split / Delta / PCM bytesRead = CopyStereoSplitSample(sample, sourceBuf, fileSize); break; case MT2: // same as deltaPCM, but right channel is stored as a difference from the left channel bytesRead = CopyStereoSplitSample(sample, sourceBuf, fileSize); for(SmpLength i = 0; i < sample.nLength * 2; i += 2) { sample.pSample8[i + 1] = static_cast(static_cast(sample.pSample8[i + 1]) + static_cast(sample.pSample8[i])); } break; default: MPT_ASSERT_NOTREACHED(); break; } } ////////////////////////////////////////////////////// // 8-Bit / Stereo Interleaved / PCM else if(GetBitDepth() == 8 && GetChannelFormat() == stereoInterleaved) { switch(GetEncoding()) { case signedPCM: // 8-Bit / Stereo Interleaved / Signed / PCM bytesRead = CopyStereoInterleavedSample(sample, sourceBuf, fileSize); break; case unsignedPCM: // 8-Bit / Stereo Interleaved / Unsigned / PCM bytesRead = CopyStereoInterleavedSample(sample, sourceBuf, fileSize); break; case deltaPCM: // 8-Bit / Stereo Interleaved / Delta / PCM bytesRead = CopyStereoInterleavedSample(sample, sourceBuf, fileSize); break; default: MPT_ASSERT_NOTREACHED(); break; } } ////////////////////////////////////////////////////// // 16-Bit / Mono / Little Endian / PCM else if(GetBitDepth() == 16 && GetChannelFormat() == mono && GetEndianness() == littleEndian) { switch(GetEncoding()) { case signedPCM: // 16-Bit / Stereo Interleaved / Signed / PCM bytesRead = CopyMonoSample >(sample, sourceBuf, fileSize); break; case unsignedPCM: // 16-Bit / Stereo Interleaved / Unsigned / PCM bytesRead = CopyMonoSample >(sample, sourceBuf, fileSize); break; case deltaPCM: // 16-Bit / Stereo Interleaved / Delta / PCM case MT2: bytesRead = CopyMonoSample >(sample, sourceBuf, fileSize); break; default: MPT_ASSERT_NOTREACHED(); break; } } ////////////////////////////////////////////////////// // 16-Bit / Mono / Big Endian / PCM else if(GetBitDepth() == 16 && GetChannelFormat() == mono && GetEndianness() == bigEndian) { switch(GetEncoding()) { case signedPCM: // 16-Bit / Mono / Signed / PCM bytesRead = CopyMonoSample >(sample, sourceBuf, fileSize); break; case unsignedPCM: // 16-Bit / Mono / Unsigned / PCM bytesRead = CopyMonoSample >(sample, sourceBuf, fileSize); break; case deltaPCM: // 16-Bit / Mono / Delta / PCM bytesRead = CopyMonoSample >(sample, sourceBuf, fileSize); break; default: MPT_ASSERT_NOTREACHED(); break; } } ////////////////////////////////////////////////////// // 16-Bit / Stereo Split / Little Endian / PCM else if(GetBitDepth() == 16 && GetChannelFormat() == stereoSplit && GetEndianness() == littleEndian) { switch(GetEncoding()) { case signedPCM: // 16-Bit / Stereo Split / Signed / PCM bytesRead = CopyStereoSplitSample >(sample, sourceBuf, fileSize); break; case unsignedPCM: // 16-Bit / Stereo Split / Unsigned / PCM bytesRead = CopyStereoSplitSample >(sample, sourceBuf, fileSize); break; case deltaPCM: // 16-Bit / Stereo Split / Delta / PCM bytesRead = CopyStereoSplitSample >(sample, sourceBuf, fileSize); break; case MT2: // same as deltaPCM, but right channel is stored as a difference from the left channel bytesRead = CopyStereoSplitSample >(sample, sourceBuf, fileSize); for(SmpLength i = 0; i < sample.nLength * 2; i += 2) { sample.pSample16[i + 1] = static_cast(static_cast(sample.pSample16[i + 1]) + static_cast(sample.pSample16[i])); } break; default: MPT_ASSERT_NOTREACHED(); break; } } ////////////////////////////////////////////////////// // 16-Bit / Stereo Split / Big Endian / PCM else if(GetBitDepth() == 16 && GetChannelFormat() == stereoSplit && GetEndianness() == bigEndian) { switch(GetEncoding()) { case signedPCM: // 16-Bit / Stereo Split / Signed / PCM bytesRead = CopyStereoSplitSample >(sample, sourceBuf, fileSize); break; case unsignedPCM: // 16-Bit / Stereo Split / Unsigned / PCM bytesRead = CopyStereoSplitSample >(sample, sourceBuf, fileSize); break; case deltaPCM: // 16-Bit / Stereo Split / Delta / PCM bytesRead = CopyStereoSplitSample >(sample, sourceBuf, fileSize); break; default: MPT_ASSERT_NOTREACHED(); break; } } ////////////////////////////////////////////////////// // 16-Bit / Stereo Interleaved / Little Endian / PCM else if(GetBitDepth() == 16 && GetChannelFormat() == stereoInterleaved && GetEndianness() == littleEndian) { switch(GetEncoding()) { case signedPCM: // 16-Bit / Stereo Interleaved / Signed / PCM bytesRead = CopyStereoInterleavedSample >(sample, sourceBuf, fileSize); break; case unsignedPCM: // 16-Bit / Stereo Interleaved / Unsigned / PCM bytesRead = CopyStereoInterleavedSample >(sample, sourceBuf, fileSize); break; case deltaPCM: // 16-Bit / Stereo Interleaved / Delta / PCM bytesRead = CopyStereoInterleavedSample >(sample, sourceBuf, fileSize); break; default: MPT_ASSERT_NOTREACHED(); break; } } ////////////////////////////////////////////////////// // 16-Bit / Stereo Interleaved / Big Endian / PCM else if(GetBitDepth() == 16 && GetChannelFormat() == stereoInterleaved && GetEndianness() == bigEndian) { switch(GetEncoding()) { case signedPCM: // 16-Bit / Stereo Interleaved / Signed / PCM bytesRead = CopyStereoInterleavedSample >(sample, sourceBuf, fileSize); break; case unsignedPCM: // 16-Bit / Stereo Interleaved / Unsigned / PCM bytesRead = CopyStereoInterleavedSample >(sample, sourceBuf, fileSize); break; case deltaPCM: // 16-Bit / Stereo Interleaved / Delta / PCM bytesRead = CopyStereoInterleavedSample >(sample, sourceBuf, fileSize); break; default: MPT_ASSERT_NOTREACHED(); break; } } ////////////////////////////////////////////////////// // 24-Bit / Signed / Mono / PCM else if(GetBitDepth() == 24 && GetChannelFormat() == mono && GetEncoding() == signedPCM) { if(GetEndianness() == littleEndian) { bytesRead = CopyMonoSample, SC::DecodeInt24<0, littleEndian24> > >(sample, sourceBuf, fileSize); } else { bytesRead = CopyMonoSample, SC::DecodeInt24<0, bigEndian24> > >(sample, sourceBuf, fileSize); } } ////////////////////////////////////////////////////// // 24-Bit / Signed / Stereo Interleaved / PCM else if(GetBitDepth() == 24 && GetChannelFormat() == stereoInterleaved && GetEncoding() == signedPCM) { if(GetEndianness() == littleEndian) { bytesRead = CopyStereoInterleavedSample, SC::DecodeInt24<0, littleEndian24> > >(sample, sourceBuf, fileSize); } else { bytesRead = CopyStereoInterleavedSample, SC::DecodeInt24<0, bigEndian24> > >(sample, sourceBuf, fileSize); } } ////////////////////////////////////////////////////// // 32-Bit / Signed / Mono / PCM else if(GetBitDepth() == 32 && GetChannelFormat() == mono && GetEncoding() == signedPCM) { if(GetEndianness() == littleEndian) { bytesRead = CopyMonoSample, SC::DecodeInt32<0, littleEndian32> > >(sample, sourceBuf, fileSize); } else { bytesRead = CopyMonoSample, SC::DecodeInt32<0, bigEndian32> > >(sample, sourceBuf, fileSize); } } ////////////////////////////////////////////////////// // 32-Bit / Signed / Stereo Interleaved / PCM else if(GetBitDepth() == 32 && GetChannelFormat() == stereoInterleaved && GetEncoding() == signedPCM) { if(GetEndianness() == littleEndian) { bytesRead = CopyStereoInterleavedSample, SC::DecodeInt32<0, littleEndian32> > >(sample, sourceBuf, fileSize); } else { bytesRead = CopyStereoInterleavedSample, SC::DecodeInt32<0, bigEndian32> > >(sample, sourceBuf, fileSize); } } ////////////////////////////////////////////////////// // 64-Bit / Signed / Mono / PCM else if(GetBitDepth() == 64 && GetChannelFormat() == mono && GetEncoding() == signedPCM) { if(GetEndianness() == littleEndian) { bytesRead = CopyMonoSample, SC::DecodeInt64<0, littleEndian64> > >(sample, sourceBuf, fileSize); } else { bytesRead = CopyMonoSample, SC::DecodeInt64<0, bigEndian64> > >(sample, sourceBuf, fileSize); } } ////////////////////////////////////////////////////// // 64-Bit / Signed / Stereo Interleaved / PCM else if(GetBitDepth() == 64 && GetChannelFormat() == stereoInterleaved && GetEncoding() == signedPCM) { if(GetEndianness() == littleEndian) { bytesRead = CopyStereoInterleavedSample, SC::DecodeInt64<0, littleEndian64> > >(sample, sourceBuf, fileSize); } else { bytesRead = CopyStereoInterleavedSample, SC::DecodeInt64<0, bigEndian64> > >(sample, sourceBuf, fileSize); } } ////////////////////////////////////////////////////// // 32-Bit / Float / Mono / PCM else if(GetBitDepth() == 32 && GetChannelFormat() == mono && GetEncoding() == floatPCM) { if(GetEndianness() == littleEndian) { bytesRead = CopyMonoSample, SC::DecodeFloat32 > >(sample, sourceBuf, fileSize); } else { bytesRead = CopyMonoSample, SC::DecodeFloat32 > >(sample, sourceBuf, fileSize); } } ////////////////////////////////////////////////////// // 32-Bit / Float / Stereo Interleaved / PCM else if(GetBitDepth() == 32 && GetChannelFormat() == stereoInterleaved && GetEncoding() == floatPCM) { if(GetEndianness() == littleEndian) { bytesRead = CopyStereoInterleavedSample, SC::DecodeFloat32 > >(sample, sourceBuf, fileSize); } else { bytesRead = CopyStereoInterleavedSample, SC::DecodeFloat32 > >(sample, sourceBuf, fileSize); } } ////////////////////////////////////////////////////// // 64-Bit / Float / Mono / PCM else if(GetBitDepth() == 64 && GetChannelFormat() == mono && GetEncoding() == floatPCM) { if(GetEndianness() == littleEndian) { bytesRead = CopyMonoSample, SC::DecodeFloat64 > >(sample, sourceBuf, fileSize); } else { bytesRead = CopyMonoSample, SC::DecodeFloat64 > >(sample, sourceBuf, fileSize); } } ////////////////////////////////////////////////////// // 64-Bit / Float / Stereo Interleaved / PCM else if(GetBitDepth() == 64 && GetChannelFormat() == stereoInterleaved && GetEncoding() == floatPCM) { if(GetEndianness() == littleEndian) { bytesRead = CopyStereoInterleavedSample, SC::DecodeFloat64 > >(sample, sourceBuf, fileSize); } else { bytesRead = CopyStereoInterleavedSample, SC::DecodeFloat64 > >(sample, sourceBuf, fileSize); } } ////////////////////////////////////////////////////// // 24-Bit / Signed / Mono, Stereo Interleaved / PCM else if(GetBitDepth() == 24 && (GetChannelFormat() == mono || GetChannelFormat() == stereoInterleaved) && GetEncoding() == signedPCMnormalize) { // Normalize to 16-Bit uint32 srcPeak = uint32(1)<<31; if(GetEndianness() == littleEndian) { bytesRead = CopyAndNormalizeSample, SC::DecodeInt24<0, littleEndian24> > >(sample, sourceBuf, fileSize, &srcPeak); } else { bytesRead = CopyAndNormalizeSample, SC::DecodeInt24<0, bigEndian24> > >(sample, sourceBuf, fileSize, &srcPeak); } if(bytesRead && srcPeak != uint32(1)<<31) { // Adjust sample volume so we do not affect relative volume of the sample. Normalizing is only done to increase precision. sample.nGlobalVol = static_cast(Clamp(Util::muldivr_unsigned(sample.nGlobalVol, srcPeak, uint32(1)<<31), uint32(1), uint32(64))); sample.uFlags.set(SMP_MODIFIED); } } ////////////////////////////////////////////////////// // 32-Bit / Signed / Mono, Stereo Interleaved / PCM else if(GetBitDepth() == 32 && (GetChannelFormat() == mono || GetChannelFormat() == stereoInterleaved) && GetEncoding() == signedPCMnormalize) { // Normalize to 16-Bit uint32 srcPeak = uint32(1)<<31; if(GetEndianness() == littleEndian) { bytesRead = CopyAndNormalizeSample, SC::DecodeInt32<0, littleEndian32> > >(sample, sourceBuf, fileSize, &srcPeak); } else { bytesRead = CopyAndNormalizeSample, SC::DecodeInt32<0, bigEndian32> > >(sample, sourceBuf, fileSize, &srcPeak); } if(bytesRead && srcPeak != uint32(1)<<31) { // Adjust sample volume so we do not affect relative volume of the sample. Normalizing is only done to increase precision. sample.nGlobalVol = static_cast(Clamp(Util::muldivr_unsigned(sample.nGlobalVol, srcPeak, uint32(1)<<31), uint32(1), uint32(64))); sample.uFlags.set(SMP_MODIFIED); } } ////////////////////////////////////////////////////// // 32-Bit / Float / Mono, Stereo Interleaved / PCM else if(GetBitDepth() == 32 && (GetChannelFormat() == mono || GetChannelFormat() == stereoInterleaved) && GetEncoding() == floatPCMnormalize) { // Normalize to 16-Bit float32 srcPeak = 1.0f; if(GetEndianness() == littleEndian) { bytesRead = CopyAndNormalizeSample, SC::DecodeFloat32 > >(sample, sourceBuf, fileSize, &srcPeak); } else { bytesRead = CopyAndNormalizeSample, SC::DecodeFloat32 > >(sample, sourceBuf, fileSize, &srcPeak); } if(bytesRead && srcPeak != 1.0f) { // Adjust sample volume so we do not affect relative volume of the sample. Normalizing is only done to increase precision. sample.nGlobalVol = Util::Round(Clamp(sample.nGlobalVol * srcPeak, 1.0f, 64.0f)); sample.uFlags.set(SMP_MODIFIED); } } ////////////////////////////////////////////////////// // 64-Bit / Float / Mono, Stereo Interleaved / PCM else if(GetBitDepth() == 64 && (GetChannelFormat() == mono || GetChannelFormat() == stereoInterleaved) && GetEncoding() == floatPCMnormalize) { // Normalize to 16-Bit float64 srcPeak = 1.0; if(GetEndianness() == littleEndian) { bytesRead = CopyAndNormalizeSample, SC::DecodeFloat64 > >(sample, sourceBuf, fileSize, &srcPeak); } else { bytesRead = CopyAndNormalizeSample, SC::DecodeFloat64 > >(sample, sourceBuf, fileSize, &srcPeak); } if(bytesRead && srcPeak != 1.0) { // Adjust sample volume so we do not affect relative volume of the sample. Normalizing is only done to increase precision. sample.nGlobalVol = Util::Round(Clamp(sample.nGlobalVol * srcPeak, 1.0f, 64.0f)); sample.uFlags.set(SMP_MODIFIED); } } ////////////////////////////////////////////////////// // 32-Bit / Float / Mono / PCM / full scale 2^15 else if(GetBitDepth() == 32 && GetChannelFormat() == mono && GetEncoding() == floatPCM15) { if(GetEndianness() == littleEndian) { bytesRead = CopyMonoSample (sample, sourceBuf, fileSize, SC::ConversionChain, SC::DecodeScaledFloat32 > (SC::Convert(), SC::DecodeScaledFloat32(1.0f / static_cast(1<<15))) ); } else { bytesRead = CopyMonoSample (sample, sourceBuf, fileSize, SC::ConversionChain, SC::DecodeScaledFloat32 > (SC::Convert(), SC::DecodeScaledFloat32(1.0f / static_cast(1<<15))) ); } } ////////////////////////////////////////////////////// // 32-Bit / Float / Stereo Interleaved / PCM / full scale 2^15 else if(GetBitDepth() == 32 && GetChannelFormat() == stereoInterleaved && GetEncoding() == floatPCM15) { if(GetEndianness() == littleEndian) { bytesRead = CopyStereoInterleavedSample (sample, sourceBuf, fileSize, SC::ConversionChain, SC::DecodeScaledFloat32 > (SC::Convert(), SC::DecodeScaledFloat32(1.0f / static_cast(1<<15))) ); } else { bytesRead = CopyStereoInterleavedSample (sample, sourceBuf, fileSize, SC::ConversionChain, SC::DecodeScaledFloat32 > (SC::Convert(), SC::DecodeScaledFloat32(1.0f / static_cast(1<<15))) ); } } ////////////////////////////////////////////////////// // 32-Bit / Float / Stereo Interleaved / PCM / full scale 2^23 else if(GetBitDepth() == 32 && GetChannelFormat() == mono && GetEncoding() == floatPCM23) { if(GetEndianness() == littleEndian) { bytesRead = CopyMonoSample (sample, sourceBuf, fileSize, SC::ConversionChain, SC::DecodeScaledFloat32 > (SC::Convert(), SC::DecodeScaledFloat32(1.0f / static_cast(1<<23))) ); } else { bytesRead = CopyMonoSample (sample, sourceBuf, fileSize, SC::ConversionChain, SC::DecodeScaledFloat32 > (SC::Convert(), SC::DecodeScaledFloat32(1.0f / static_cast(1<<23))) ); } } ////////////////////////////////////////////////////// // 32-Bit / Float / Stereo Interleaved / PCM / full scale 2^23 else if(GetBitDepth() == 32 && GetChannelFormat() == stereoInterleaved && GetEncoding() == floatPCM23) { if(GetEndianness() == littleEndian) { bytesRead = CopyStereoInterleavedSample (sample, sourceBuf, fileSize, SC::ConversionChain, SC::DecodeScaledFloat32 > (SC::Convert(), SC::DecodeScaledFloat32(1.0f / static_cast(1<<23))) ); } else { bytesRead = CopyStereoInterleavedSample (sample, sourceBuf, fileSize, SC::ConversionChain, SC::DecodeScaledFloat32 > (SC::Convert(), SC::DecodeScaledFloat32(1.0f / static_cast(1<<23))) ); } } //////////////// // Unsupported else { MPT_ASSERT_NOTREACHED(); } MPT_ASSERT(filePosition + bytesRead <= file.GetLength()); file.Seek(filePosition + bytesRead); return bytesRead; } #ifndef MODPLUG_NO_FILESAVE // Write a sample to file size_t SampleIO::WriteSample(std::ostream *f, const ModSample &sample, SmpLength maxSamples) const { if(!sample.HasSampleData()) return 0; union { int8 buffer8[8192]; int16 buffer16[4096]; }; const void *const pSampleVoid = sample.pSample; const int8 *const pSample8 = sample.pSample8; const int16 *const pSample16 = sample.pSample16; SmpLength numSamples = sample.nLength; if(maxSamples && numSamples > maxSamples) numSamples = maxSamples; size_t len = CalculateEncodedSize(numSamples), bufcount = 0; if(GetBitDepth() == 16 && GetChannelFormat() == mono && GetEndianness() == littleEndian && (GetEncoding() == signedPCM || GetEncoding() == unsignedPCM || GetEncoding() == deltaPCM)) { // 16-bit little-endian mono samples MPT_ASSERT(len == numSamples * 2); if(!f) return len; const int16 *p = pSample16; int s_old = 0; const int s_ofs = (GetEncoding() == unsignedPCM) ? 0x8000 : 0; for(SmpLength j = 0; j < numSamples; j++) { int s_new = *p; p++; if(sample.uFlags[CHN_STEREO]) { // Downmix stereo s_new = (s_new + (*p) + 1) / 2; p++; } if(GetEncoding() == deltaPCM) { buffer16[bufcount] = SwapBytesLE((int16)(s_new - s_old)); s_old = s_new; } else { buffer16[bufcount] = SwapBytesLE((int16)(s_new + s_ofs)); } bufcount++; if(bufcount >= mpt::size(buffer16)) { mpt::IO::WriteRaw(*f, reinterpret_cast(buffer16), bufcount * 2); bufcount = 0; } } if (bufcount) mpt::IO::WriteRaw(*f, reinterpret_cast(buffer16), bufcount * 2); } else if(GetBitDepth() == 8 && GetChannelFormat() == stereoSplit && (GetEncoding() == signedPCM || GetEncoding() == unsignedPCM || GetEncoding() == deltaPCM)) { // 8-bit Stereo samples (not interleaved) MPT_ASSERT(len == numSamples * 2); if(!f) return len; const int s_ofs = (GetEncoding() == unsignedPCM) ? 0x80 : 0; for (uint32 iCh=0; iCh<2; iCh++) { const int8 *p = pSample8 + iCh; int s_old = 0; bufcount = 0; for (uint32 j=0; j= mpt::size(buffer8)) { mpt::IO::WriteRaw(*f, reinterpret_cast(buffer8), bufcount); bufcount = 0; } } if (bufcount) mpt::IO::WriteRaw(*f, reinterpret_cast(buffer8), bufcount); } } else if(GetBitDepth() == 16 && GetChannelFormat() == stereoSplit && GetEndianness() == littleEndian && (GetEncoding() == signedPCM || GetEncoding() == unsignedPCM || GetEncoding() == deltaPCM)) { // 16-bit little-endian Stereo samples (not interleaved) MPT_ASSERT(len == numSamples * 4); if(!f) return len; const int s_ofs = (GetEncoding() == unsignedPCM) ? 0x8000 : 0; for (uint32 iCh=0; iCh<2; iCh++) { const int16 *p = pSample16 + iCh; int s_old = 0; bufcount = 0; for (SmpLength j=0; j= mpt::size(buffer16)) { mpt::IO::WriteRaw(*f, reinterpret_cast(buffer16), bufcount * 2); bufcount = 0; } } if (bufcount) mpt::IO::WriteRaw(*f, reinterpret_cast(buffer16), bufcount * 2); } } else if((GetBitDepth() == 8 || (GetBitDepth() == 16 && GetEndianness() == GetNativeEndianness())) && GetChannelFormat() == stereoInterleaved && GetEncoding() == signedPCM) { // Stereo signed interleaved if(f) mpt::IO::WriteRaw(*f, mpt::void_cast(pSampleVoid), len); } else if(GetBitDepth() == 8 && GetChannelFormat() == stereoInterleaved && GetEncoding() == unsignedPCM) { // Stereo unsigned interleaved MPT_ASSERT(len == numSamples * 2); if(!f) return len; for(SmpLength j = 0; j < len; j++) { buffer8[bufcount] = (int8)((uint8)(pSample8[j]) + 0x80); bufcount++; if(bufcount >= mpt::size(buffer8)) { mpt::IO::WriteRaw(*f, reinterpret_cast(buffer8), bufcount); bufcount = 0; } } if (bufcount) mpt::IO::WriteRaw(*f, reinterpret_cast(buffer8), bufcount); } else if(GetEncoding() == IT214 || GetEncoding() == IT215) { // IT2.14-encoded samples ITCompression its(sample, GetEncoding() == IT215, f, numSamples); len = its.GetCompressedSize(); } // Default: assume 8-bit PCM data else { MPT_ASSERT(GetBitDepth() == 8); MPT_ASSERT(len == numSamples); if(!f) return len; const int8 *p = pSample8; int sinc = sample.GetElementarySampleSize(); int s_old = 0; const int s_ofs = (GetEncoding() == unsignedPCM) ? 0x80 : 0; MPT_MAYBE_CONSTANT_IF(mpt::endian_is_little()) { if (sample.uFlags[CHN_16BIT]) p++; } for (SmpLength j = 0; j < len; j++) { int s_new = (int8)(*p); p += sinc; if (sample.uFlags[CHN_STEREO]) { s_new = (s_new + ((int)*p) + 1) / 2; p += sinc; } if (GetEncoding() == deltaPCM) { buffer8[bufcount++] = (int8)(s_new - s_old); s_old = s_new; } else { buffer8[bufcount++] = (int8)(s_new + s_ofs); } if(bufcount >= mpt::size(buffer8)) { mpt::IO::WriteRaw(*f, reinterpret_cast(buffer8), bufcount); bufcount = 0; } } if (bufcount) mpt::IO::WriteRaw(*f, reinterpret_cast(buffer8), bufcount); } return len; } // Write a sample to file size_t SampleIO::WriteSample(std::ostream &f, const ModSample &sample, SmpLength maxSamples) const { return WriteSample(&f, sample, maxSamples); } // Write a sample to file size_t SampleIO::WriteSample(FILE *f, const ModSample &sample, SmpLength maxSamples) const { mpt::FILE_ostream s(f); return WriteSample(f ? &s : nullptr, sample, maxSamples); } #endif // MODPLUG_NO_FILESAVE OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/WAVTools.h0000644000372100037210000002657713161656666017765 00000000000000/* * WAVTools.h * ---------- * Purpose: Definition of WAV file structures and helper functions * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "ChunkReader.h" #include "Loaders.h" #include "../common/mptUUID.h" OPENMPT_NAMESPACE_BEGIN struct FileTags; // RIFF header struct RIFFHeader { // 32-Bit chunk identifiers enum RIFFMagic { idRIFF = MAGIC4LE('R','I','F','F'), // magic for WAV files idLIST = MAGIC4LE('L','I','S','T'), // magic for samples in DLS banks idWAVE = MAGIC4LE('W','A','V','E'), // type for WAV files idwave = MAGIC4LE('w','a','v','e'), // type for samples in DLS banks }; uint32le magic; // RIFF (in WAV files) or LIST (in DLS banks) uint32le length; // Size of the file, not including magic and length uint32le type; // WAVE (in WAV files) or wave (in DLS banks) }; MPT_BINARY_STRUCT(RIFFHeader, 12) // General RIFF Chunk header struct RIFFChunk { // 32-Bit chunk identifiers enum ChunkIdentifiers { idfmt_ = MAGIC4LE('f','m','t',' '), // Sample format information iddata = MAGIC4LE('d','a','t','a'), // Sample data idpcm_ = MAGIC4LE('p','c','m',' '), // IMA ADPCM samples idfact = MAGIC4LE('f','a','c','t'), // Compressed samples idsmpl = MAGIC4LE('s','m','p','l'), // Sampler and loop information idinst = MAGIC4LE('i','n','s','t'), // Instrument information idLIST = MAGIC4LE('L','I','S','T'), // List of chunks idxtra = MAGIC4LE('x','t','r','a'), // OpenMPT extra infomration idcue_ = MAGIC4LE('c','u','e',' '), // Cue points idwsmp = MAGIC4LE('w','s','m','p'), // DLS bank samples id____ = 0x00000000, // Found when loading buggy MPT samples // Identifiers in "LIST" chunk idINAM = MAGIC4LE('I','N','A','M'), // title idISFT = MAGIC4LE('I','S','F','T'), // software idICOP = MAGIC4LE('I','C','O','P'), // copyright idIART = MAGIC4LE('I','A','R','T'), // artist idIPRD = MAGIC4LE('I','P','R','D'), // product (album) idICMT = MAGIC4LE('I','C','M','T'), // comment idIENG = MAGIC4LE('I','E','N','G'), // engineer idISBJ = MAGIC4LE('I','S','B','J'), // subject idIGNR = MAGIC4LE('I','G','N','R'), // genre idICRD = MAGIC4LE('I','C','R','D'), // date created idYEAR = MAGIC4LE('Y','E','A','R'), // year idTRCK = MAGIC4LE('T','R','C','K'), // track number idTURL = MAGIC4LE('T','U','R','L'), // url }; uint32le id; // See ChunkIdentifiers uint32le length; // Chunk size without header size_t GetLength() const { return length; } ChunkIdentifiers GetID() const { return static_cast(id.get()); } }; MPT_BINARY_STRUCT(RIFFChunk, 8) // Format Chunk struct WAVFormatChunk { // Sample formats enum SampleFormats { fmtPCM = 1, fmtFloat = 3, fmtALaw = 6, fmtULaw = 7, fmtIMA_ADPCM = 17, fmtMP3 = 85, fmtExtensible = 0xFFFE, }; uint16le format; // Sample format, see SampleFormats uint16le numChannels; // Number of audio channels uint32le sampleRate; // Sample rate in Hz uint32le byteRate; // Bytes per second (should be freqHz * blockAlign) uint16le blockAlign; // Size of a sample, in bytes (do not trust this value, it's incorrect in some files) uint16le bitsPerSample; // Bits per sample }; MPT_BINARY_STRUCT(WAVFormatChunk, 16) // Extension of the WAVFormatChunk structure, used if format == formatExtensible struct WAVFormatChunkExtension { uint16le size; uint16le validBitsPerSample; uint32le channelMask; GUIDms subFormat; }; MPT_BINARY_STRUCT(WAVFormatChunkExtension, 24) // Sample information chunk struct WAVSampleInfoChunk { uint32le manufacturer; uint32le product; uint32le samplePeriod; // 1000000000 / sampleRate uint32le baseNote; // MIDI base note of sample uint32le pitchFraction; uint32le SMPTEFormat; uint32le SMPTEOffset; uint32le numLoops; // number of loops uint32le samplerData; // Set up information void ConvertToWAV(uint32 freq, uint8 rootNote) { manufacturer = 0; product = 0; samplePeriod = 1000000000 / freq; if(rootNote != 0) baseNote = rootNote - NOTE_MIN; else baseNote = NOTE_MIDDLEC - NOTE_MIN; pitchFraction = 0; SMPTEFormat = 0; SMPTEOffset = 0; numLoops = 0; samplerData = 0; } }; MPT_BINARY_STRUCT(WAVSampleInfoChunk, 36) // Sample loop information chunk (found after WAVSampleInfoChunk in "smpl" chunk) struct WAVSampleLoop { // Sample Loop Types enum LoopType { loopForward = 0, loopBidi = 1, loopBackward = 2, }; uint32le identifier; uint32le loopType; // See LoopType uint32le loopStart; // Loop start in samples uint32le loopEnd; // Loop end in samples uint32le fraction; uint32le playCount; // Loop Count, 0 = infinite // Apply WAV loop information to a mod sample. void ApplyToSample(SmpLength &start, SmpLength &end, SmpLength sampleLength, SampleFlags &flags, ChannelFlags enableFlag, ChannelFlags bidiFlag, bool mptLoopFix) const; // Convert internal loop information into a WAV loop. void ConvertToWAV(SmpLength start, SmpLength end, bool bidi); }; MPT_BINARY_STRUCT(WAVSampleLoop, 24) // Instrument information chunk struct WAVInstrumentChunk { uint8 unshiftedNote; // Root key of sample, 0...127 int8 finetune; // Finetune of root key in cents int8 gain; // in dB uint8 lowNote; // Note range, 0...127 uint8 highNote; uint8 lowVelocity; // Velocity range, 0...127 uint8 highVelocity; }; MPT_BINARY_STRUCT(WAVInstrumentChunk, 7) // MPT-specific "xtra" chunk struct WAVExtraChunk { enum Flags { setPanning = 0x20, }; uint32le flags; uint16le defaultPan; uint16le defaultVolume; uint16le globalVolume; uint16le reserved; uint8le vibratoType; uint8le vibratoSweep; uint8le vibratoDepth; uint8le vibratoRate; // Set up sample information void ConvertToWAV(const ModSample &sample, MODTYPE modType) { if(sample.uFlags[CHN_PANNING]) { flags = WAVExtraChunk::setPanning; } else { flags = 0; } defaultPan = sample.nPan; defaultVolume = sample.nVolume; globalVolume = sample.nGlobalVol; vibratoType = sample.nVibType; vibratoSweep = sample.nVibSweep; vibratoDepth = sample.nVibDepth; vibratoRate = sample.nVibRate; if((modType & MOD_TYPE_XM) && (vibratoDepth | vibratoRate)) { // XM vibrato is upside down vibratoSweep = 255 - vibratoSweep; } } }; MPT_BINARY_STRUCT(WAVExtraChunk, 16) // Sample cue point structure for the "cue " chunk struct WAVCuePoint { uint32le id; // Unique identification value uint32le position; // Play order position uint32le riffChunkID; // RIFF ID of corresponding data chunk uint32le chunkStart; // Byte Offset of Data Chunk uint32le blockStart; // Byte Offset to sample of First Channel uint32le offset; // Byte Offset to sample byte of First Channel // Set up sample information void ConvertToWAV(uint32 id_, SmpLength offset_) { id = id_; position = offset_; riffChunkID = static_cast(RIFFChunk::iddata); chunkStart = 0; // we use no Wave List Chunk (wavl) as we have only one data block, so this should be 0. blockStart = 0; // ditto offset = offset_; } }; MPT_BINARY_STRUCT(WAVCuePoint, 24) class WAVReader { protected: ChunkReader file; FileReader sampleData, smplChunk, instChunk, xtraChunk, wsmpChunk, cueChunk; ChunkReader::ChunkList infoChunk; FileReader::off_t sampleLength; WAVFormatChunk formatInfo; uint16 subFormat; bool isDLS; bool mayBeCoolEdit16_8; public: WAVReader(FileReader &inputFile); bool IsValid() const { return sampleData.IsValid(); } void FindMetadataChunks(ChunkReader::ChunkList &chunks); // Self-explanatory getters. WAVFormatChunk::SampleFormats GetSampleFormat() const { return IsExtensibleFormat() ? static_cast(subFormat) : static_cast(formatInfo.format.get()); } uint16 GetNumChannels() const { return formatInfo.numChannels; } uint16 GetBitsPerSample() const { return formatInfo.bitsPerSample; } uint32 GetSampleRate() const { return formatInfo.sampleRate; } uint16 GetBlockAlign() const { return formatInfo.blockAlign; } FileReader GetSampleData() const { return sampleData; } FileReader GetWsmpChunk() const { return wsmpChunk; } bool IsExtensibleFormat() const { return formatInfo.format == WAVFormatChunk::fmtExtensible; } bool MayBeCoolEdit16_8() const { return mayBeCoolEdit16_8; } // Get size of a single sample point, in bytes. uint16 GetSampleSize() const { return ((GetNumChannels() * GetBitsPerSample()) + 7) / 8; } // Get sample length (in samples) SmpLength GetSampleLength() const { return mpt::saturate_cast(sampleLength); } // Apply sample settings from file (loop points, MPT extra settings, ...) to a sample. void ApplySampleSettings(ModSample &sample, char (&sampleName)[MAX_SAMPLENAME]); }; #ifndef MODPLUG_NO_FILESAVE class WAVWriter { protected: // When writing to a stream: Stream pointer std::ostream *s; // When writing to memory: Memory address + length uint8 *memory; size_t memSize; // Cursor position size_t position; // Total number of bytes written to file / memory size_t totalSize; // Currently written chunk size_t chunkStartPos; RIFFChunk chunkHeader; public: // Output to stream: Initialize with std::ostream*. WAVWriter(std::ostream *stream); // Output to clipboard: Initialize with pointer to memory and size of reserved memory. WAVWriter(void *mem, size_t size); ~WAVWriter(); // Check if anything can be written to the file. bool IsValid() const { return s != nullptr || memory != nullptr; } // Finalize the file by closing the last open chunk and updating the file header. Returns total size of file. size_t Finalize(); // Begin writing a new chunk to the file. void StartChunk(RIFFChunk::ChunkIdentifiers id); // Skip some bytes... For example after writing sample data. void Skip(size_t numBytes) { Seek(position + numBytes); } // Get position in file (not counting any changes done to the file from outside this class, i.e. through GetFile()) size_t GetPosition() const { return position; } // Shrink file size to current position. void Truncate() { totalSize = position; } // Write some data to the file. template void Write(const T &data) { Write(&data, sizeof(T)); } // Write a buffer to the file. void WriteBuffer(const char *data, size_t size) { Write(data, size); } // Write an array to the file. template void WriteArray(const T (&data)[size]) { Write(data, sizeof(T) * size); } // Write the WAV format to the file. void WriteFormat(uint32 sampleRate, uint16 bitDepth, uint16 numChannels, WAVFormatChunk::SampleFormats encoding); // Write text tags to the file. void WriteMetatags(const FileTags &tags); // Write a sample loop information chunk to the file. void WriteLoopInformation(const ModSample &sample); // Write a sample's cue points to the file. void WriteCueInformation(const ModSample &sample); // Write MPT's sample information chunk to the file. void WriteExtraInformation(const ModSample &sample, MODTYPE modType, const char *sampleName = nullptr); protected: void Init(); // Seek to a position in file. void Seek(size_t pos); // End current chunk by updating the chunk header and writing a padding byte if necessary. void FinalizeChunk(); // Write some data to the file. void Write(const void *data, size_t numBytes); // Write a single tag into a open idLIST chunk void WriteTag(RIFFChunk::ChunkIdentifiers id, const mpt::ustring &utext); }; #endif // MODPLUG_NO_FILESAVE OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/modsmp_ctrl.cpp0000644000372100037210000006601613201261241021125 00000000000000/* * ModSmp_Ctrl.cpp * --------------- * Purpose: Basic sample editing code (resizing, adding silence, normalizing, ...). * Notes : Could be merged with ModSample.h / ModSample.cpp at some point. * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "modsmp_ctrl.h" #include "AudioCriticalSection.h" #include "Sndfile.h" #include "../soundbase/SampleFormatConverters.h" #include "../soundbase/SampleFormatCopy.h" OPENMPT_NAMESPACE_BEGIN namespace ctrlSmp { void ReplaceSample(ModSample &smp, void *pNewSample, const SmpLength nNewLength, CSoundFile &sndFile) { void * const pOldSmp = smp.pSample; FlagSet setFlags, resetFlags; setFlags.set(CHN_16BIT, smp.uFlags[CHN_16BIT]); resetFlags.set(CHN_16BIT, !smp.uFlags[CHN_16BIT]); setFlags.set(CHN_STEREO, smp.uFlags[CHN_STEREO]); resetFlags.set(CHN_STEREO, !smp.uFlags[CHN_STEREO]); CriticalSection cs; ctrlChn::ReplaceSample(sndFile, smp, pNewSample, nNewLength, setFlags, resetFlags); smp.pSample = pNewSample; smp.nLength = nNewLength; ModSample::FreeSample(pOldSmp); } SmpLength InsertSilence(ModSample &smp, const SmpLength nSilenceLength, const SmpLength nStartFrom, CSoundFile &sndFile) { if(nSilenceLength == 0 || nSilenceLength > MAX_SAMPLE_LENGTH || smp.nLength > MAX_SAMPLE_LENGTH - nSilenceLength || nStartFrom > smp.nLength) return smp.nLength; const bool wasEmpty = smp.nLength == 0 || smp.pSample == nullptr; const SmpLength newLength = smp.nLength + nSilenceLength; char *pNewSmp = nullptr; pNewSmp = static_cast(ModSample::AllocateSample(newLength, smp.GetBytesPerSample())); if(pNewSmp == nullptr) return smp.nLength; //Sample allocation failed. if(!wasEmpty) { // Copy over old sample const SmpLength silenceOffset = nStartFrom * smp.GetBytesPerSample(); const SmpLength silenceBytes = nSilenceLength * smp.GetBytesPerSample(); if(nStartFrom > 0) { memcpy(pNewSmp, smp.pSample, silenceOffset); } if(nStartFrom < smp.nLength) { memcpy(pNewSmp + silenceOffset + silenceBytes, static_cast(smp.pSample) + silenceOffset, smp.GetSampleSizeInBytes() - silenceOffset); } // Update loop points if necessary. if(smp.nLoopStart >= nStartFrom) smp.nLoopStart += nSilenceLength; if(smp.nLoopEnd >= nStartFrom) smp.nLoopEnd += nSilenceLength; if(smp.nSustainStart >= nStartFrom) smp.nSustainStart += nSilenceLength; if(smp.nSustainEnd >= nStartFrom) smp.nSustainEnd += nSilenceLength; for(std::size_t i = 0; i < CountOf(smp.cues); i++) { if(smp.cues[i] >= nStartFrom) smp.cues[i] += nSilenceLength; } } else { // Set loop points automatically smp.nLoopStart = 0; smp.nLoopEnd = newLength; smp.uFlags.set(CHN_LOOP); } ReplaceSample(smp, pNewSmp, newLength, sndFile); PrecomputeLoops(smp, sndFile, true); return smp.nLength; } namespace { // Update loop points and cues after deleting a sample selection static void AdjustLoopPoints(SmpLength selStart, SmpLength selEnd, SmpLength &loopStart, SmpLength &loopEnd, SmpLength length) { Util::DeleteRange(selStart, selEnd - 1, loopStart, loopEnd); LimitMax(loopEnd, length); if(loopStart + 2 >= loopEnd) { loopStart = loopEnd = 0; } } } SmpLength RemoveRange(ModSample &smp, SmpLength selStart, SmpLength selEnd, CSoundFile &sndFile) { LimitMax(selEnd, smp.nLength); if(selEnd <= selStart) { return smp.nLength; } const uint8 bps = smp.GetBytesPerSample(); memmove(smp.pSample8 + selStart * bps, smp.pSample8 + selEnd * bps, (smp.nLength - selEnd) * bps); smp.nLength -= (selEnd - selStart); // Did loops or cue points cover the deleted selection? AdjustLoopPoints(selStart, selEnd, smp.nLoopStart, smp.nLoopEnd, smp.nLength); AdjustLoopPoints(selStart, selEnd, smp.nSustainStart, smp.nSustainEnd, smp.nLength); if(smp.nLoopEnd == 0) smp.uFlags.reset(CHN_LOOP | CHN_PINGPONGLOOP); if(smp.nSustainEnd == 0) smp.uFlags.reset(CHN_SUSTAINLOOP | CHN_PINGPONGSUSTAIN); for(std::size_t i = 0; i < CountOf(smp.cues); i++) { Util::DeleteItem(selStart, selEnd - 1, smp.cues[i]); } smp.PrecomputeLoops(sndFile); return smp.nLength; } SmpLength ResizeSample(ModSample &smp, const SmpLength nNewLength, CSoundFile &sndFile) { // Invalid sample size if(nNewLength > MAX_SAMPLE_LENGTH || nNewLength == smp.nLength) return smp.nLength; // New sample will be bigger so we'll just use "InsertSilence" as it's already there. if(nNewLength > smp.nLength) return InsertSilence(smp, nNewLength - smp.nLength, smp.nLength, sndFile); // Else: Shrink sample const SmpLength nNewSmpBytes = nNewLength * smp.GetBytesPerSample(); void *pNewSmp = ModSample::AllocateSample(nNewLength, smp.GetBytesPerSample()); if(pNewSmp == nullptr) return smp.nLength; //Sample allocation failed. // Copy over old data and replace sample by the new one memcpy(pNewSmp, smp.pSample, nNewSmpBytes); ReplaceSample(smp, pNewSmp, nNewLength, sndFile); // Adjust loops if(smp.nLoopStart > nNewLength) { smp.nLoopStart = smp.nLoopEnd = 0; smp.uFlags.reset(CHN_LOOP); } if(smp.nLoopEnd > nNewLength) smp.nLoopEnd = nNewLength; if(smp.nSustainStart > nNewLength) { smp.nSustainStart = smp.nSustainEnd = 0; smp.uFlags.reset(CHN_SUSTAINLOOP); } if(smp.nSustainEnd > nNewLength) smp.nSustainEnd = nNewLength; PrecomputeLoops(smp, sndFile); return smp.nLength; } namespace // Unnamed namespace for local implementation functions. { template class PrecomputeLoop { protected: T *target; const T *sampleData; SmpLength loopEnd; int numChannels; bool pingpong; bool ITPingPongMode; public: PrecomputeLoop(T *target, const T *sampleData, SmpLength loopEnd, int numChannels, bool pingpong, bool ITPingPongMode) : target(target), sampleData(sampleData), loopEnd(loopEnd), numChannels(numChannels), pingpong(pingpong), ITPingPongMode(ITPingPongMode) { if(loopEnd > 0) { CopyLoop(true); CopyLoop(false); } } void CopyLoop(bool direction) const { // Direction: true = start reading and writing forward, false = start reading and writing backward (write direction never changes) const int numSamples = 2 * InterpolationMaxLookahead + (direction ? 1 : 0); // Loop point is included in forward loop expansion T *dest = target + numChannels * (2 * InterpolationMaxLookahead - 1); // Write buffer offset SmpLength readPosition = loopEnd - 1; const int writeIncrement = direction ? 1 : -1; int readIncrement = writeIncrement; for(int i = 0; i < numSamples; i++) { // Copy sample over to lookahead buffer for(int c = 0; c < numChannels; c++) { dest[c] = sampleData[readPosition * numChannels + c]; } dest += writeIncrement * numChannels; if(readPosition == loopEnd - 1 && readIncrement > 0) { // Reached end of loop while going forward if(pingpong) { readIncrement = -1; if(ITPingPongMode && readPosition > 0) { readPosition--; } } else { readPosition = 0; } } else if(readPosition == 0 && readIncrement < 0) { // Reached start of loop while going backward if(pingpong) { readIncrement = 1; } else { readPosition = loopEnd - 1; } } else { readPosition += readIncrement; } } } }; template void PrecomputeLoopsImpl(ModSample &smp, const CSoundFile &sndFile) { const int numChannels = smp.GetNumChannels(); const int copySamples = numChannels * InterpolationMaxLookahead; T *sampleData = static_cast(smp.pSample); T *afterSampleStart = sampleData + smp.nLength * numChannels; T *loopLookAheadStart = afterSampleStart + copySamples; T *sustainLookAheadStart = loopLookAheadStart + 4 * copySamples; // Hold sample on the same level as the last sampling point at the end to prevent extra pops with interpolation. // Do the same at the sample start, too. for(int i = 0; i < (int)InterpolationMaxLookahead; i++) { for(int c = 0; c < numChannels; c++) { afterSampleStart[i * numChannels + c] = afterSampleStart[-numChannels + c]; sampleData[-(i + 1) * numChannels + c] = sampleData[c]; } } if(smp.uFlags[CHN_LOOP]) { PrecomputeLoop(loopLookAheadStart, sampleData + smp.nLoopStart * numChannels, smp.nLoopEnd - smp.nLoopStart, numChannels, smp.uFlags[CHN_PINGPONGLOOP], sndFile.m_playBehaviour[kITPingPongMode]); } if(smp.uFlags[CHN_SUSTAINLOOP]) { PrecomputeLoop(sustainLookAheadStart, sampleData + smp.nSustainStart * numChannels, smp.nSustainEnd - smp.nSustainStart, numChannels, smp.uFlags[CHN_PINGPONGSUSTAIN], sndFile.m_playBehaviour[kITPingPongMode]); } } } // unnamed namespace. bool PrecomputeLoops(ModSample &smp, CSoundFile &sndFile, bool updateChannels) { if(smp.nLength == 0 || smp.pSample == nullptr) return false; smp.SanitizeLoops(); // Update channels with possibly changed loop values if(updateChannels) { UpdateLoopPoints(smp, sndFile); } if(smp.GetElementarySampleSize() == 2) PrecomputeLoopsImpl(smp, sndFile); else if(smp.GetElementarySampleSize() == 1) PrecomputeLoopsImpl(smp, sndFile); return true; } // Propagate loop point changes to player bool UpdateLoopPoints(const ModSample &smp, CSoundFile &sndFile) { if(!smp.HasSampleData()) return false; CriticalSection cs; // Update channels with new loop values for(auto &chn : sndFile.m_PlayState.Chn) if((chn.pModSample == &smp) && chn.nLength != 0) { bool looped = false, bidi = false; if(smp.nSustainStart < smp.nSustainEnd && smp.nSustainEnd <= smp.nLength && smp.uFlags[CHN_SUSTAINLOOP] && !chn.dwFlags[CHN_KEYOFF]) { // Sustain loop is active chn.nLoopStart = smp.nSustainStart; chn.nLoopEnd = smp.nSustainEnd; chn.nLength = smp.nSustainEnd; looped = true; bidi = smp.uFlags[CHN_PINGPONGSUSTAIN]; } else if(smp.nLoopStart < smp.nLoopEnd && smp.nLoopEnd <= smp.nLength && smp.uFlags[CHN_LOOP]) { // Normal loop is active chn.nLoopStart = smp.nLoopStart; chn.nLoopEnd = smp.nLoopEnd; chn.nLength = smp.nLoopEnd; looped = true; bidi = smp.uFlags[CHN_PINGPONGLOOP]; } chn.dwFlags.set(CHN_LOOP, looped); chn.dwFlags.set(CHN_PINGPONGLOOP, looped && bidi); if(chn.position.GetUInt() > chn.nLength) { chn.position.Set(chn.nLoopStart); chn.dwFlags.reset(CHN_PINGPONGFLAG); } if(!bidi) { chn.dwFlags.reset(CHN_PINGPONGFLAG); } if(!looped) { chn.nLength = smp.nLength; } } return true; } void ResetSamples(CSoundFile &sndFile, ResetFlag resetflag, SAMPLEINDEX minSample, SAMPLEINDEX maxSample) { if(minSample == SAMPLEINDEX_INVALID) { minSample = 1; } if(maxSample == SAMPLEINDEX_INVALID) { maxSample = sndFile.GetNumSamples(); } Limit(minSample, SAMPLEINDEX(1), SAMPLEINDEX(MAX_SAMPLES - 1)); Limit(maxSample, SAMPLEINDEX(1), SAMPLEINDEX(MAX_SAMPLES - 1)); if(minSample > maxSample) { std::swap(minSample, maxSample); } for(SAMPLEINDEX i = minSample; i <= maxSample; i++) { ModSample &sample = sndFile.GetSample(i); switch(resetflag) { case SmpResetInit: strcpy(sndFile.m_szNames[i], ""); strcpy(sample.filename, ""); sample.nC5Speed = 8363; // note: break is left out intentionally. keep this order or c&p the stuff from below if you change anything! MPT_FALLTHROUGH; case SmpResetCompo: sample.nPan = 128; sample.nGlobalVol = 64; sample.nVolume = 256; sample.nVibDepth = 0; sample.nVibRate = 0; sample.nVibSweep = 0; sample.nVibType = 0; sample.uFlags.reset(CHN_PANNING | SMP_NODEFAULTVOLUME); break; case SmpResetVibrato: sample.nVibDepth = 0; sample.nVibRate = 0; sample.nVibSweep = 0; sample.nVibType = 0; break; default: break; } } } namespace { struct OffsetData { double dMax, dMin, dOffset; }; // Returns maximum sample amplitude for given sample type (int8/int16). template double GetMaxAmplitude() {return 1.0 + (std::numeric_limits::max)();} // Calculates DC offset and returns struct with DC offset, max and min values. // DC offset value is average of [-1.0, 1.0[-normalized offset values. template OffsetData CalculateOffset(const T *pStart, const SmpLength nLength) { OffsetData offsetVals = {0,0,0}; if(nLength < 1) return offsetVals; const double dMaxAmplitude = GetMaxAmplitude(); double dMax = -1, dMin = 1, dSum = 0; const T *p = pStart; for(SmpLength i = 0; i < nLength; i++, p++) { const double dVal = double(*p) / dMaxAmplitude; dSum += dVal; if(dVal > dMax) dMax = dVal; if(dVal < dMin) dMin = dVal; } offsetVals.dMax = dMax; offsetVals.dMin = dMin; offsetVals.dOffset = (-dSum / (double)(nLength)); return offsetVals; } template void RemoveOffsetAndNormalize(T *pStart, const SmpLength nLength, const double dOffset, const double dAmplify) { T *p = pStart; for(SmpLength i = 0; i < nLength; i++, p++) { double dVal = (*p) * dAmplify + dOffset; *p = mpt::saturate_cast(dVal); } } } // Remove DC offset float RemoveDCOffset(ModSample &smp, SmpLength iStart, SmpLength iEnd, const MODTYPE modtype, CSoundFile &sndFile) { if(!smp.HasSampleData()) return 0; if (iEnd > smp.nLength) iEnd = smp.nLength; if (iStart > iEnd) iStart = iEnd; if (iStart == iEnd) { iStart = 0; iEnd = smp.nLength; } iStart *= smp.GetNumChannels(); iEnd *= smp.GetNumChannels(); const double dMaxAmplitude = (smp.GetElementarySampleSize() == 2) ? GetMaxAmplitude() : GetMaxAmplitude(); // step 1: Calculate offset. OffsetData oData = {0,0,0}; if(smp.GetElementarySampleSize() == 2) oData = CalculateOffset(smp.pSample16 + iStart, iEnd - iStart); else if(smp.GetElementarySampleSize() == 1) oData = CalculateOffset(smp.pSample8 + iStart, iEnd - iStart); double dMin = oData.dMin, dMax = oData.dMax, dOffset = oData.dOffset; const float fReportOffset = (float)dOffset; if((int)(dOffset * dMaxAmplitude) == 0) return 0; // those will be changed... dMax += dOffset; dMin += dOffset; // ... and that might cause distortion, so we will normalize this. const double dAmplify = 1 / std::max(dMax, -dMin); // step 2: centralize + normalize sample dOffset *= dMaxAmplitude * dAmplify; if(smp.GetElementarySampleSize() == 2) RemoveOffsetAndNormalize(smp.pSample16 + iStart, iEnd - iStart, dOffset, dAmplify); else if(smp.GetElementarySampleSize() == 1) RemoveOffsetAndNormalize(smp.pSample8 + iStart, iEnd - iStart, dOffset, dAmplify); // step 3: adjust global vol (if available) if((modtype & (MOD_TYPE_IT | MOD_TYPE_MPT)) && (iStart == 0) && (iEnd == smp.nLength * smp.GetNumChannels())) { CriticalSection cs; smp.nGlobalVol = std::min(Util::Round(smp.nGlobalVol / dAmplify), uint16(64)); for(auto &chn : sndFile.m_PlayState.Chn) { if(chn.pModSample == &smp) { chn.UpdateInstrumentVolume(&smp, chn.pModInstrument); } } } PrecomputeLoops(smp, sndFile, false); return fReportOffset; } template static void ReverseSampleImpl(T *pStart, const SmpLength nLength) { for(SmpLength i = 0; i < nLength / 2; i++) { std::swap(pStart[i], pStart[nLength - 1 - i]); } } // Reverse sample data bool ReverseSample(ModSample &smp, SmpLength iStart, SmpLength iEnd, CSoundFile &sndFile) { if(!smp.HasSampleData()) return false; if(iEnd == 0 || iStart > smp.nLength || iEnd > smp.nLength) { iStart = 0; iEnd = smp.nLength; } if(iEnd - iStart < 2) return false; STATIC_ASSERT(MaxSamplingPointSize <= 4); if(smp.GetBytesPerSample() == 4) // 16 bit stereo ReverseSampleImpl(static_cast(smp.pSample) + iStart, iEnd - iStart); else if(smp.GetBytesPerSample() == 2) // 16 bit mono / 8 bit stereo ReverseSampleImpl(smp.pSample16 + iStart, iEnd - iStart); else if(smp.GetBytesPerSample() == 1) // 8 bit mono ReverseSampleImpl(smp.pSample8 + iStart, iEnd - iStart); else return false; PrecomputeLoops(smp, sndFile, false); return true; } template static void UnsignSampleImpl(T *pStart, const SmpLength nLength) { const T offset = (std::numeric_limits::min)(); for(SmpLength i = 0; i < nLength; i++) { pStart[i] += offset; } } // Virtually unsign sample data bool UnsignSample(ModSample &smp, SmpLength iStart, SmpLength iEnd, CSoundFile &sndFile) { if(!smp.HasSampleData()) return false; if(iEnd == 0 || iStart > smp.nLength || iEnd > smp.nLength) { iStart = 0; iEnd = smp.nLength; } iStart *= smp.GetNumChannels(); iEnd *= smp.GetNumChannels(); if(smp.GetElementarySampleSize() == 2) UnsignSampleImpl(smp.pSample16 + iStart, iEnd - iStart); else if(smp.GetElementarySampleSize() == 1) UnsignSampleImpl(smp.pSample8 + iStart, iEnd - iStart); else return false; PrecomputeLoops(smp, sndFile, false); return true; } template static void InvertSampleImpl(T *pStart, const SmpLength nLength) { for(SmpLength i = 0; i < nLength; i++) { pStart[i] = ~pStart[i]; } } // Invert sample data (flip by 180 degrees) bool InvertSample(ModSample &smp, SmpLength iStart, SmpLength iEnd, CSoundFile &sndFile) { if(!smp.HasSampleData()) return false; if(iEnd == 0 || iStart > smp.nLength || iEnd > smp.nLength) { iStart = 0; iEnd = smp.nLength; } iStart *= smp.GetNumChannels(); iEnd *= smp.GetNumChannels(); if(smp.GetElementarySampleSize() == 2) InvertSampleImpl(smp.pSample16 + iStart, iEnd - iStart); else if(smp.GetElementarySampleSize() == 1) InvertSampleImpl(smp.pSample8 + iStart, iEnd - iStart); else return false; PrecomputeLoops(smp, sndFile, false); return true; } template static void XFadeSampleImpl(const T *srcIn, const T *srcOut, T *output, const SmpLength fadeLength, double e) { const double length = 1.0 / static_cast(fadeLength); for(SmpLength i = 0; i < fadeLength; i++, srcIn++, srcOut++, output++) { double fact1 = std::pow(i * length, e); double fact2 = std::pow((fadeLength - i) * length, e); int32 val = static_cast( static_cast(*srcIn) * fact1 + static_cast(*srcOut) * fact2); *output = mpt::saturate_cast(val); } } // X-Fade sample data to create smooth loop transitions bool XFadeSample(ModSample &smp, SmpLength fadeLength, int fadeLaw, bool afterloopFade, bool useSustainLoop, CSoundFile &sndFile) { if(!smp.HasSampleData()) return false; const SmpLength loopStart = useSustainLoop ? smp.nSustainStart : smp.nLoopStart; const SmpLength loopEnd = useSustainLoop ? smp.nSustainEnd : smp.nLoopEnd; if(loopEnd <= loopStart || loopEnd > smp.nLength) return false; if(loopStart < fadeLength) return false; const SmpLength start = (loopStart - fadeLength) * smp.GetNumChannels(); const SmpLength end = (loopEnd - fadeLength) * smp.GetNumChannels(); const SmpLength afterloopStart = loopStart * smp.GetNumChannels(); const SmpLength afterloopEnd = loopEnd * smp.GetNumChannels(); const SmpLength afterLoopLength = std::min(smp.nLength - loopEnd, fadeLength) * smp.GetNumChannels(); fadeLength *= smp.GetNumChannels(); // e=0.5: constant power crossfade (for uncorrelated samples), e=1.0: constant volume crossfade (for perfectly correlated samples) const double e = 1.0 - fadeLaw / 200000.0; if(smp.GetElementarySampleSize() == 2) { XFadeSampleImpl(smp.pSample16 + start, smp.pSample16 + end, smp.pSample16 + end, fadeLength, e); if(afterloopFade) XFadeSampleImpl(smp.pSample16 + afterloopEnd, smp.pSample16 + afterloopStart, smp.pSample16 + afterloopEnd, afterLoopLength, e); } else if(smp.GetElementarySampleSize() == 1) { XFadeSampleImpl(smp.pSample8 + start, smp.pSample8 + end, smp.pSample8 + end, fadeLength, e); if(afterloopFade) XFadeSampleImpl(smp.pSample8 + afterloopEnd, smp.pSample8 + afterloopStart, smp.pSample8 + afterloopEnd, afterLoopLength, e); } else return false; PrecomputeLoops(smp, sndFile, true); return true; } template static void SilenceSampleImpl(T *p, SmpLength length, SmpLength inc, bool fromStart, bool toEnd) { const int dest = toEnd ? 0 : p[(length - 1) * inc]; const int base = fromStart ? 0 :p[0]; const int delta = dest - base; const int64 len_m1 = length - 1; for(SmpLength i = 0; i < length; i++) { int n = base + static_cast((static_cast(delta) * static_cast(i)) / len_m1); *p = static_cast(n); p += inc; } } // X-Fade sample data to create smooth loop transitions bool SilenceSample(ModSample &smp, SmpLength start, SmpLength end, CSoundFile &sndFile) { LimitMax(end, smp.nLength); if(!smp.HasSampleData() || start >= end) return false; const SmpLength length = end - start; const bool fromStart = start == 0; const bool toEnd = end == smp.nLength; const uint8 numChn = smp.GetNumChannels(); for(uint8 chn = 0; chn < numChn; chn++) { if(smp.GetElementarySampleSize() == 2) SilenceSampleImpl(smp.pSample16 + start * numChn + chn, length, numChn, fromStart, toEnd); else if(smp.GetElementarySampleSize() == 1) SilenceSampleImpl(smp.pSample8 + start * numChn + chn, length, numChn, fromStart, toEnd); else return false; } PrecomputeLoops(smp, sndFile, false); return true; } template static void StereoSepSampleImpl(T *p, SmpLength length, int32 separation) { const int32 fac1 = static_cast(32768 + separation / 2), fac2 = static_cast(32768 - separation / 2); while(length--) { const int32 l = p[0], r = p[1]; p[0] = mpt::saturate_cast((Util::mul32to64(l, fac1) + Util::mul32to64(r, fac2)) >> 16); p[1] = mpt::saturate_cast((Util::mul32to64(l, fac2) + Util::mul32to64(r, fac1)) >> 16); p += 2; } } // X-Fade sample data to create smooth loop transitions bool StereoSepSample(ModSample &smp, SmpLength start, SmpLength end, double separation, CSoundFile &sndFile) { LimitMax(end, smp.nLength); if(!smp.HasSampleData() || start >= end || smp.GetNumChannels() != 2) return false; const SmpLength length = end - start; const uint8 numChn = smp.GetNumChannels(); const int32 sep32 = Util::Round(separation * (65536.0 / 100.0)); if(smp.GetElementarySampleSize() == 2) StereoSepSampleImpl(smp.pSample16 + start * numChn, length, sep32); else if(smp.GetElementarySampleSize() == 1) StereoSepSampleImpl(smp.pSample8 + start * numChn, length, sep32); else return false; PrecomputeLoops(smp, sndFile, false); return true; } template static void ConvertStereoToMonoMixImpl(T *pDest, const SmpLength length) { const T *pEnd = pDest + length; for(T *pSource = pDest; pDest != pEnd; pDest++, pSource += 2) { *pDest = (pSource[0] + pSource[1] + 1) >> 1; } } template static void ConvertStereoToMonoOneChannelImpl(T *pDest, const SmpLength length) { const T *pEnd = pDest + length; for(T *pSource = pDest; pDest != pEnd; pDest++, pSource += 2) { *pDest = *pSource; } } // Convert a multichannel sample to mono (currently only implemented for stereo) bool ConvertToMono(ModSample &smp, CSoundFile &sndFile, StereoToMonoMode conversionMode) { if(!smp.HasSampleData() || smp.GetNumChannels() != 2) return false; // Note: Sample is overwritten in-place! Unused data is not deallocated! if(conversionMode == mixChannels) { if(smp.GetElementarySampleSize() == 2) ConvertStereoToMonoMixImpl(smp.pSample16, smp.nLength); else if(smp.GetElementarySampleSize() == 1) ConvertStereoToMonoMixImpl(smp.pSample8, smp.nLength); else return false; } else { if(conversionMode == splitSample) { conversionMode = onlyLeft; } if(smp.GetElementarySampleSize() == 2) ConvertStereoToMonoOneChannelImpl(smp.pSample16 + (conversionMode == onlyLeft ? 0 : 1), smp.nLength); else if(smp.GetElementarySampleSize() == 1) ConvertStereoToMonoOneChannelImpl(smp.pSample8 + (conversionMode == onlyLeft ? 0 : 1), smp.nLength); else return false; } CriticalSection cs; smp.uFlags.reset(CHN_STEREO); for(auto &chn : sndFile.m_PlayState.Chn) { if(chn.pModSample == &smp) { chn.dwFlags.reset(CHN_STEREO); } } PrecomputeLoops(smp, sndFile, false); return true; } template static void ConvertMonoToStereoImpl(const T * MPT_RESTRICT src, T * MPT_RESTRICT dst, SmpLength length) { while(length--) { dst[0] = *src; dst[1] = *src; dst += 2; src++; } } // Convert a multichannel sample to mono (currently only implemented for stereo) bool ConvertToStereo(ModSample &smp, CSoundFile &sndFile) { if(!smp.HasSampleData() || smp.GetNumChannels() != 1) return false; void *newSample = ModSample::AllocateSample(smp.nLength, smp.GetBytesPerSample() * 2); if(newSample == nullptr) { return 0; } if(smp.GetElementarySampleSize() == 2) ConvertMonoToStereoImpl(smp.pSample16, (int16 *)newSample, smp.nLength); else if(smp.GetElementarySampleSize() == 1) ConvertMonoToStereoImpl(smp.pSample8, (int8 *)newSample, smp.nLength); else return false; CriticalSection cs; smp.uFlags.set(CHN_STEREO); ReplaceSample(smp, newSample, smp.nLength, sndFile); PrecomputeLoops(smp, sndFile, false); return true; } // Convert 16-bit sample to 8-bit bool ConvertTo8Bit(ModSample &smp, CSoundFile &sndFile) { if(!smp.HasSampleData() || smp.GetElementarySampleSize() != 2) return false; CopySample, SC::DecodeIdentity > >(smp.pSample8, smp.nLength * smp.GetNumChannels(), 1, smp.pSample16, smp.GetSampleSizeInBytes(), 1); smp.uFlags.reset(CHN_16BIT); for(auto &chn : sndFile.m_PlayState.Chn) if(chn.pModSample == &smp) { chn.dwFlags.reset(CHN_16BIT); } smp.PrecomputeLoops(sndFile, false); return true; } // Convert 8-bit sample to 16-bit bool ConvertTo16Bit(ModSample &smp, CSoundFile &sndFile) { if(!smp.HasSampleData() || smp.GetElementarySampleSize() != 1) return false; int16 *newSample = static_cast(ModSample::AllocateSample(smp.nLength, 2 * smp.GetNumChannels())); if(newSample == nullptr) return false; CopySample, SC::DecodeIdentity > >(newSample, smp.nLength * smp.GetNumChannels(), 1, smp.pSample8, smp.GetSampleSizeInBytes(), 1); smp.uFlags.set(CHN_16BIT); ctrlSmp::ReplaceSample(smp, newSample, smp.nLength, sndFile); smp.PrecomputeLoops(sndFile, false); return true; } } // namespace ctrlSmp namespace ctrlChn { void ReplaceSample( CSoundFile &sndFile, const ModSample &sample, const void * const pNewSample, const SmpLength nNewLength, FlagSet setFlags, FlagSet resetFlags) { const bool periodIsFreq = sndFile.PeriodsAreFrequencies(); auto begin = sndFile.m_PlayState.Chn, end = sndFile.m_PlayState.Chn + CountOf(sndFile.m_PlayState.Chn); for (auto chn = begin; chn != end; chn++) { if (chn->pModSample == &sample) { if (chn->pCurrentSample != nullptr) chn->pCurrentSample = pNewSample; if (chn->position.GetUInt() > nNewLength) chn->position.Set(0); if (chn->nLength > 0) LimitMax(chn->nLength, nNewLength); if(chn->InSustainLoop()) { chn->nLoopStart = sample.nSustainStart; chn->nLoopEnd = sample.nSustainEnd; } else { chn->nLoopStart = sample.nLoopStart; chn->nLoopEnd = sample.nLoopEnd; } chn->dwFlags.set(setFlags); chn->dwFlags.reset(resetFlags); if(chn->nC5Speed && sample.nC5Speed && !sndFile.UseFinetuneAndTranspose()) { if(periodIsFreq) chn->nPeriod = Util::muldivr_unsigned(chn->nPeriod, sample.nC5Speed, chn->nC5Speed); else chn->nPeriod = Util::muldivr_unsigned(chn->nPeriod, chn->nC5Speed, sample.nC5Speed); } chn->nC5Speed = sample.nC5Speed; } } } } // namespace ctrlChn OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/tuningcollection.h0000644000372100037210000000407513161656666021654 00000000000000/* * tuningCollection.h * ------------------ * Purpose: Alternative sample tuning collection class. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "tuning.h" #include #include OPENMPT_NAMESPACE_BEGIN namespace Tuning { class CTuningCollection { public: static const char s_FileExtension[4]; // OpenMPT <= 1.26 had to following limits: // * 255 built-in tunings (only 2 were ever actually provided) // * 255 local tunings // * 255 tune-specific tunings // As 1.27 copies all used tunings into the module, the limit of 255 is no // longer sufficient. In the worst case scenario, the module contains 255 // unused tunings and uses 255 local ones. In addition to that, allow the // user to additionally import both built-in tunings. // Older OpenMPT versions will silently skip loading tunings beyond index // 255. static const size_t s_nMaxTuningCount = 255 + 255 + 2; public: //Note: Given pointer is deleted by CTuningCollection //at some point. bool AddTuning(CTuning *pT); bool AddTuning(std::istream& inStrm); bool Remove(const std::size_t i); bool Remove(const CTuning *pT); CTuning& GetTuning(size_t i) {return *m_Tunings.at(i).get();} const CTuning& GetTuning(size_t i) const {return *m_Tunings.at(i).get();} CTuning* GetTuning(const std::string& name); const CTuning* GetTuning(const std::string& name) const; size_t GetNumTunings() const {return m_Tunings.size();} Tuning::SerializationResult Serialize(std::ostream&, const std::string &name) const; Tuning::SerializationResult Deserialize(std::istream&, std::string &name); private: std::vector > m_Tunings; private: Tuning::SerializationResult DeserializeOLD(std::istream&, std::string &name); }; #ifdef MODPLUG_TRACKER bool UnpackTuningCollection(const CTuningCollection &tc, const mpt::PathString &prefix); #endif } // namespace Tuning typedef Tuning::CTuningCollection CTuningCollection; OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Mixer.h0000644000372100037210000000270212771332174017342 00000000000000/* * Mixer.h * ------- * Purpose: Basic mixer constants * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once OPENMPT_NAMESPACE_BEGIN #define MPT_INTMIXER #ifdef MPT_INTMIXER typedef int32 mixsample_t; enum { MIXING_FILTER_PRECISION = 16 }; // Fixed point resonant filter bits #else typedef float mixsample_t; #endif #define MIXBUFFERSIZE 512 #define VOLUMERAMPPRECISION 12 // Fractional bits in volume ramp variables enum { MIXING_ATTENUATION = 4 }; enum { MIXING_FRACTIONAL_BITS = 32 - 1 - MIXING_ATTENUATION }; enum { MIXING_CLIPMAX = ((1<(1 << MIXING_FRACTIONAL_BITS); // The absolute maximum number of sampling points any interpolation algorithm is going to look at in any direction from the current sampling point // Currently, the maximum is 4 sampling points forwards and 3 sampling points backwards (Polyphase / FIR algorithms). // Hence, this value must be at least 4. // Note that choosing a higher value (e.g. 16) will reduce CPU usage when using many extremely short (length < 16) samples. #define InterpolationMaxLookahead 16u // Maximum size of a sampling point of a sample, in bytes. // The biggest sampling point size is currently 16-bit stereo = 2 * 2 bytes. #define MaxSamplingPointSize 4u OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Load_it.cpp0000644000372100037210000023311113161656666020175 00000000000000/* * Load_it.cpp * ----------- * Purpose: IT (Impulse Tracker) module loader / saver * Notes : Also handles MPTM loading / saving, as the formats are almost identical. * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" #include "tuningcollection.h" #include "mod_specifications.h" #ifdef MODPLUG_TRACKER #include "../mptrack/Moddoc.h" #include "../mptrack/TrackerSettings.h" #endif // MODPLUG_TRACKER #ifdef MPT_EXTERNAL_SAMPLES #include "../common/mptPathString.h" #endif // MPT_EXTERNAL_SAMPLES #include "../common/mptIO.h" #include "../common/serialization_utils.h" #ifndef MODPLUG_NO_FILESAVE #include "../common/mptFileIO.h" #endif // MODPLUG_NO_FILESAVE #include "plugins/PlugInterface.h" #include "../common/mptBufferIO.h" #include "../common/version.h" #include "ITTools.h" OPENMPT_NAMESPACE_BEGIN #define str_tooMuchPatternData ("Warning: File format limit was reached. Some pattern data may not get written to file.") #define str_pattern ("pattern") #define str_PatternSetTruncationNote ("The module contains %1 patterns but only %2 patterns can be loaded in this OpenMPT version.") #define str_LoadingIncompatibleVersion "The file informed that it is incompatible with this version of OpenMPT. Loading was terminated." #define str_LoadingMoreRecentVersion "The loaded file was made with a more recent OpenMPT version and this version may not be able to load all the features or play the file correctly." const uint16 verMptFileVer = 0x891; const uint16 verMptFileVerLoadLimit = 0x1000; // If cwtv-field is greater or equal to this value, // the MPTM file will not be loaded. /* MPTM version history for cwtv-field in "IT" header (only for MPTM files!): 0x890(1.18.02.00) -> 0x891(1.19.00.00): Pattern-specific time signatures Fixed behaviour of Pattern Loop command for rows > 255 (r617) 0x88F(1.18.01.00) -> 0x890(1.18.02.00): Removed volume command velocity :xy, added delay-cut command :xy. 0x88E(1.17.02.50) -> 0x88F(1.18.01.00): Numerous changes 0x88D(1.17.02.49) -> 0x88E(1.17.02.50): Changed ID to that of IT and undone the orderlist change done in 0x88A->0x88B. Now extended orderlist is saved as extension. 0x88C(1.17.02.48) -> 0x88D(1.17.02.49): Some tuning related changes - that part fails to read on older versions. 0x88B -> 0x88C: Changed type in which tuning number is printed to file: size_t -> uint16. 0x88A -> 0x88B: Changed order-to-pattern-index table type from uint8-array to vector. */ #ifndef MODPLUG_NO_FILESAVE static bool AreNonDefaultTuningsUsed(CSoundFile& sf) { const INSTRUMENTINDEX iCount = sf.GetNumInstruments(); for(INSTRUMENTINDEX i = 1; i <= iCount; i++) { if(sf.Instruments[i] != nullptr && sf.Instruments[i]->pTuning != 0) return true; } return false; } static void WriteTuningCollection(std::ostream& oStrm, const CTuningCollection& tc) { tc.Serialize(oStrm, "Tune specific tunings"); } static void WriteTuningMap(std::ostream& oStrm, const CSoundFile& sf) { if(sf.GetNumInstruments() > 0) { //Writing instrument tuning data: first creating //tuning name <-> tuning id number map, //and then writing the tuning id for every instrument. //For example if there are 6 instruments and //first half use tuning 'T1', and the other half //tuning 'T2', the output would be something like //T1 1 T2 2 1 1 1 2 2 2 //Creating the tuning address <-> tuning id number map. std::map tNameToShort_Map; unsigned short figMap = 0; for(INSTRUMENTINDEX i = 1; i <= sf.GetNumInstruments(); i++) { CTuning *pTuning = nullptr; if(sf.Instruments[i] != nullptr) { pTuning = sf.Instruments[i]->pTuning; } auto iter = tNameToShort_Map.find(pTuning); if(iter != tNameToShort_Map.end()) continue; //Tuning already mapped. tNameToShort_Map[pTuning] = figMap; figMap++; } //...and write the map with tuning names replacing //the addresses. const uint16 tuningMapSize = static_cast(tNameToShort_Map.size()); mpt::IO::WriteIntLE(oStrm, tuningMapSize); for(auto &iter : tNameToShort_Map) { if(iter.first) mpt::IO::WriteSizedStringLE(oStrm, iter.first->GetName()); else //Case: Using original IT tuning. mpt::IO::WriteSizedStringLE(oStrm, "->MPT_ORIGINAL_IT<-"); mpt::IO::WriteIntLE(oStrm, iter.second); } //Writing tuning data for instruments. for(INSTRUMENTINDEX i = 1; i <= sf.GetNumInstruments(); i++) { CTuning *pTuning = nullptr; if(sf.Instruments[i] != nullptr) { pTuning = sf.Instruments[i]->pTuning; } auto iter = tNameToShort_Map.find(pTuning); if(iter == tNameToShort_Map.end()) //Should never happen { sf.AddToLog("Error: 210807_1"); return; } mpt::IO::WriteIntLE(oStrm, iter->second); } } } #endif // MODPLUG_NO_FILESAVE static void ReadTuningCollection(std::istream& iStrm, CTuningCollection& tc, const size_t) { std::string name; tc.Deserialize(iStrm, name); } template static bool ReadTuningMapTemplate(std::istream& iStrm, std::map& shortToTNameMap, const size_t maxNum = 500) { TUNNUMTYPE numTuning = 0; mpt::IO::ReadIntLE(iStrm, numTuning); if(numTuning > maxNum) return true; for(size_t i = 0; i < numTuning; i++) { std::string temp; uint16 ui = 0; if(!mpt::IO::ReadSizedStringLE(iStrm, temp, 255)) return true; mpt::IO::ReadIntLE(iStrm, ui); shortToTNameMap[ui] = temp; } if(iStrm.good()) return false; else return true; } static void ReadTuningMapImpl(std::istream& iStrm, CSoundFile& csf, const size_t = 0, bool old = false) { std::map shortToTNameMap; if(old) { ReadTuningMapTemplate(iStrm, shortToTNameMap); } else { ReadTuningMapTemplate(iStrm, shortToTNameMap); } // Read & set tunings for instruments std::vector notFoundTunings; for(INSTRUMENTINDEX i = 1; i<=csf.GetNumInstruments(); i++) { uint16 ui = 0; mpt::IO::ReadIntLE(iStrm, ui); auto iter = shortToTNameMap.find(ui); if(csf.Instruments[i] && iter != shortToTNameMap.end()) { const std::string str = iter->second; if(str == "->MPT_ORIGINAL_IT<-") { csf.Instruments[i]->pTuning = nullptr; continue; } csf.Instruments[i]->pTuning = csf.GetTuneSpecificTunings().GetTuning(str); if(csf.Instruments[i]->pTuning) continue; #ifdef MODPLUG_TRACKER CTuning *localTuning = TrackerSettings::Instance().oldLocalTunings->GetTuning(str); if(localTuning) { CTuning* pNewTuning = new CTuning(*localTuning); if(!csf.GetTuneSpecificTunings().AddTuning(pNewTuning)) { csf.AddToLog("Local tunings are deprecated and no longer supported. Tuning '" + str + "' found in Local tunings has been copied to Tune-specific tunings and will be saved in the module file."); csf.Instruments[i]->pTuning = pNewTuning; if(csf.GetpModDoc() != nullptr) { csf.GetpModDoc()->SetModified(); } continue; } else { delete pNewTuning; csf.AddToLog("Copying Local tuning '" + str + "' to Tune-specific tunings failed."); } } #endif if(str == "12TET [[fs15 1.17.02.49]]" || str == "12TET") { CTuning* pNewTuning = csf.CreateTuning12TET(str); if(!csf.GetTuneSpecificTunings().AddTuning(pNewTuning)) { #ifdef MODPLUG_TRACKER csf.AddToLog("Built-in tunings will no longer be used. Tuning '" + str + "' has been copied to Tune-specific tunings and will be saved in the module file."); csf.Instruments[i]->pTuning = pNewTuning; if(csf.GetpModDoc() != nullptr) { csf.GetpModDoc()->SetModified(); } #endif continue; } else { delete pNewTuning; #ifdef MODPLUG_TRACKER csf.AddToLog("Copying Built-in tuning '" + str + "' to Tune-specific tunings failed."); #endif } } // Checking if not found tuning already noticed. if(std::find(notFoundTunings.begin(), notFoundTunings.end(), str) == notFoundTunings.end()) { notFoundTunings.push_back(str); csf.AddToLog("Tuning '" + str + "' used by the module was not found."); #ifdef MODPLUG_TRACKER if(csf.GetpModDoc() != nullptr) { csf.GetpModDoc()->SetModified(); // The tuning is changed so the modified flag is set. } #endif // MODPLUG_TRACKER } csf.Instruments[i]->pTuning = csf.GetDefaultTuning(); } else { //This 'else' happens probably only in case of corrupted file. if(csf.Instruments[i]) csf.Instruments[i]->pTuning = csf.GetDefaultTuning(); } } //End read&set instrument tunings } static void ReadTuningMap(std::istream& iStrm, CSoundFile& csf, const size_t dummy = 0) { ReadTuningMapImpl(iStrm, csf, dummy, false); } ////////////////////////////////////////////////////////// // Impulse Tracker IT file support size_t CSoundFile::ITInstrToMPT(FileReader &file, ModInstrument &ins, uint16 trkvers) { if(trkvers < 0x0200) { // Load old format (IT 1.xx) instrument (early IT 2.xx modules may have cmwt set to 1.00 for backwards compatibility) ITOldInstrument instrumentHeader; if(!file.ReadStruct(instrumentHeader)) { return 0; } else { instrumentHeader.ConvertToMPT(ins); return sizeof(ITOldInstrument); } } else { const FileReader::off_t offset = file.GetPosition(); // Try loading extended instrument... instSize will differ between normal and extended instruments. ITInstrumentEx instrumentHeader; file.ReadStructPartial(instrumentHeader); size_t instSize = instrumentHeader.ConvertToMPT(ins, GetType()); file.Seek(offset + instSize); // Try reading modular instrument data. // Yes, it is completely idiotic that we have both this and LoadExtendedInstrumentProperties. // This is only required for files saved with *really* old OpenMPT versions (pre-1.17-RC1). // This chunk was also written in later versions (probably to maintain compatibility with // those ancient versions), but this also means that redundant information is stored in the file. // Starting from OpenMPT 1.25.02.07, this chunk is no longer written. if(file.ReadMagic("MSNI")) { //...the next piece of data must be the total size of the modular data FileReader modularData = file.ReadChunk(file.ReadUint32LE()); instSize += 8 + modularData.GetLength(); if(modularData.ReadMagic("GULP")) { ins.nMixPlug = modularData.ReadUint8(); if(ins.nMixPlug > MAX_MIXPLUGINS) ins.nMixPlug = 0; } } return instSize; } } static void CopyPatternName(CPattern &pattern, FileReader &file) { char name[MAX_PATTERNNAME] = ""; file.ReadString(name, MAX_PATTERNNAME); pattern.SetName(name); } // Date calculation derived from https://alcor.concordia.ca/~gpkatch/gdate-algorithm.html template struct SchismVersionFromDate { static const int32 mm = (m + 9) % 12; static const int32 yy = y - mm / 10; static const int32 date = yy * 365 + yy / 4 - yy / 100 + yy / 400 + (mm * 306 + 5) / 10 + (d - 1); static constexpr int32 Version() { return 0x1050 + date - SchismVersionFromDate<2009, 10, 31>::date; } }; // Get version of Schism Tracker that was used to create an IT/S3M file. mpt::ustring CSoundFile::GetSchismTrackerVersion(uint16 cwtv) { // Schism Tracker version information in a nutshell: // < 0x020: a proper version (files saved by such versions are likely very rare) // = 0x020: any version between the 0.2a release (2005-04-29?) and 2007-04-17 // = 0x050: anywhere from 2007-04-17 to 2009-10-31 // > 0x050: the number of days since 2009-10-31 cwtv &= 0xFFF; mpt::ustring version; if(cwtv > 0x050) { int32 date = SchismVersionFromDate<2009, 10, 31>::date + cwtv - 0x050; int32 y = static_cast((Util::mul32to64(10000, date) + 14780) / 3652425); int32 ddd = date - (365 * y + y / 4 - y / 100 + y / 400); if(ddd < 0) { y--; ddd = date - (365 * y + y / 4 - y / 100 + y / 400); } int32 mi = (100 * ddd + 52) / 3060; version = mpt::format(MPT_USTRING("Schism Tracker %1-%2-%3"))( mpt::ufmt::dec0<4>(y + (mi + 2) / 12), mpt::ufmt::dec0<2>((mi + 2) % 12 + 1), mpt::ufmt::dec0<2>(ddd - (mi * 306 + 5) / 10 + 1)); } else { version = mpt::format(MPT_USTRING("Schism Tracker 0.%1"))(mpt::ufmt::hex(cwtv)); } return version; } static bool ValidateHeader(const ITFileHeader &fileHeader) { if((std::memcmp(fileHeader.id, "IMPM", 4) && std::memcmp(fileHeader.id, "tpm.", 4)) || fileHeader.insnum > 0xFF || fileHeader.smpnum >= MAX_SAMPLES ) { return false; } return true; } static uint64 GetHeaderMinimumAdditionalSize(const ITFileHeader &fileHeader) { return fileHeader.ordnum + (fileHeader.insnum + fileHeader.smpnum + fileHeader.patnum) * 4; } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderIT(MemoryFileReader file, const uint64 *pfilesize) { ITFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return ProbeWantMoreData; } if(!ValidateHeader(fileHeader)) { return ProbeFailure; } return ProbeAdditionalSize(file, pfilesize, GetHeaderMinimumAdditionalSize(fileHeader)); } bool CSoundFile::ReadIT(FileReader &file, ModLoadingFlags loadFlags) { file.Rewind(); ITFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return false; } if(!ValidateHeader(fileHeader)) { return false; } if(!file.CanRead(mpt::saturate_cast(GetHeaderMinimumAdditionalSize(fileHeader)))) { return false; } if(loadFlags == onlyVerifyHeader) { return true; } InitializeGlobals(MOD_TYPE_IT); bool interpretModPlugMade = false; // OpenMPT crap at the end of file size_t mptStartPos = 0; if(!memcmp(fileHeader.id, "tpm.", 4)) { // Legacy MPTM files (old 1.17.02.4x releases) SetType(MOD_TYPE_MPT); file.Seek(file.GetLength() - 4); mptStartPos = file.ReadUint32LE(); } else { if(fileHeader.cwtv > 0x888 && fileHeader.cwtv <= 0xFFF) { file.Seek(file.GetLength() - 4); mptStartPos = file.ReadUint32LE(); if(mptStartPos >= 0x100 && mptStartPos < file.GetLength()) { if(file.Seek(mptStartPos) && file.ReadMagic("228")) { SetType(MOD_TYPE_MPT); if(fileHeader.cwtv >= verMptFileVerLoadLimit) { AddToLog(str_LoadingIncompatibleVersion); return false; } else if(fileHeader.cwtv > verMptFileVer) { AddToLog(str_LoadingMoreRecentVersion); } } } } if(GetType() == MOD_TYPE_IT) { // Which tracker was used to make this? if((fileHeader.cwtv & 0xF000) == 0x5000) { // OpenMPT Version number (Major.Minor) // This will only be interpreted as "made with ModPlug" (i.e. disable compatible playback etc) if the "reserved" field is set to "OMPT" - else, compatibility was used. m_dwLastSavedWithVersion = (fileHeader.cwtv & 0x0FFF) << 16; if(!memcmp(&fileHeader.reserved, "OMPT", 4)) interpretModPlugMade = true; } else if(fileHeader.cmwt == 0x888 || fileHeader.cwtv == 0x888) { // OpenMPT 1.17.02.26 (r122) to 1.18 (raped IT format) // Exact version number will be determined later. interpretModPlugMade = true; m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 17, 00, 00); } else if(fileHeader.cwtv == 0x0217 && fileHeader.cmwt == 0x0200 && fileHeader.reserved == 0) { if(memchr(fileHeader.chnpan, 0xFF, sizeof(fileHeader.chnpan)) != nullptr) { // ModPlug Tracker 1.16 (semi-raped IT format) or BeRoTracker (will be determined later) m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 16, 00, 00); m_madeWithTracker = MPT_USTRING("ModPlug Tracker 1.09 - 1.16"); } else { // OpenMPT 1.17 disguised as this in compatible mode, // but never writes 0xFF in the pan map for unused channels (which is an invalid value). m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 17, 00, 00); m_madeWithTracker = MPT_USTRING("OpenMPT 1.17 (compatibility export)"); } interpretModPlugMade = true; } else if(fileHeader.cwtv == 0x0214 && fileHeader.cmwt == 0x0202 && fileHeader.reserved == 0) { // ModPlug Tracker b3.3 - 1.09, instruments 557 bytes apart m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 09, 00, 00); m_madeWithTracker = MPT_USTRING("ModPlug Tracker b3.3 - 1.09"); interpretModPlugMade = true; } else if(fileHeader.cwtv == 0x0300 && fileHeader.cmwt == 0x0300 && fileHeader.reserved == 0 && fileHeader.ordnum == 256 && fileHeader.sep == 128 && fileHeader.pwd == 0) { // A rare variant used from OpenMPT 1.17.02.20 (r113) to 1.17.02.25 (r121), found e.g. in xTr1m-SD.it m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 17, 02, 20); interpretModPlugMade = true; } } } m_SongFlags.set(SONG_LINEARSLIDES, (fileHeader.flags & ITFileHeader::linearSlides) != 0); m_SongFlags.set(SONG_ITOLDEFFECTS, (fileHeader.flags & ITFileHeader::itOldEffects) != 0); m_SongFlags.set(SONG_ITCOMPATGXX, (fileHeader.flags & ITFileHeader::itCompatGxx) != 0); m_SongFlags.set(SONG_EXFILTERRANGE, (fileHeader.flags & ITFileHeader::extendedFilterRange) != 0); mpt::String::Read(m_songName, fileHeader.songname); // Read row highlights if((fileHeader.special & ITFileHeader::embedPatternHighlights)) { // MPT 1.09 and older (and maybe also newer) versions leave this blank (0/0), but have the "special" flag set. // Newer versions of MPT and OpenMPT 1.17 *always* write 4/16 here. // Thus, we will just ignore those old versions. // Note: OpenMPT 1.17.03.02 was the first version to properly make use of the time signature in the IT header. // This poses a small unsolvable problem: // - In compatible mode, we cannot distinguish this version from earlier 1.17 releases. // Thus we cannot know when to read this field or not (m_dwLastSavedWithVersion will always be 1.17.00.00). // Luckily OpenMPT 1.17.03.02 should not be very wide-spread. // - In normal mode the time signature is always present in the song extensions anyway. So it's okay if we read // the signature here and maybe overwrite it later when parsing the song extensions. if(m_dwLastSavedWithVersion == 0 || m_dwLastSavedWithVersion >= MAKE_VERSION_NUMERIC(1, 17, 03, 02)) { m_nDefaultRowsPerBeat = fileHeader.highlight_minor; m_nDefaultRowsPerMeasure = fileHeader.highlight_major; } } // Global Volume m_nDefaultGlobalVolume = fileHeader.globalvol << 1; if(m_nDefaultGlobalVolume > MAX_GLOBAL_VOLUME) m_nDefaultGlobalVolume = MAX_GLOBAL_VOLUME; if(fileHeader.speed) m_nDefaultSpeed = fileHeader.speed; m_nDefaultTempo.Set(std::max(31, fileHeader.tempo)); m_nSamplePreAmp = std::min(fileHeader.mv, 128); // Reading Channels Pan Positions for(CHANNELINDEX i = 0; i < 64; i++) if(fileHeader.chnpan[i] != 0xFF) { ChnSettings[i].Reset(); ChnSettings[i].nVolume = Clamp(fileHeader.chnvol[i], 0, 64); if(fileHeader.chnpan[i] & 0x80) ChnSettings[i].dwFlags.set(CHN_MUTE); uint8 n = fileHeader.chnpan[i] & 0x7F; if(n <= 64) ChnSettings[i].nPan = n * 4; if(n == 100) ChnSettings[i].dwFlags.set(CHN_SURROUND); } // Reading orders file.Seek(sizeof(ITFileHeader)); if(GetType() == MOD_TYPE_MPT && fileHeader.cwtv > 0x88A && fileHeader.cwtv <= 0x88D) { // Deprecated format used for MPTm files created with OpenMPT 1.17.02.46 - 1.17.02.48. uint16 version = file.ReadUint16LE(); if(version != 0) return false; uint32 numOrd = file.ReadUint32LE(); if(numOrd > ModSpecs::mptm.ordersMax || !ReadOrderFromFile(Order(), file, numOrd)) return false; } else { ReadOrderFromFile(Order(), file, fileHeader.ordnum, 0xFF, 0xFE); } // Reading instrument, sample and pattern offsets std::vector insPos, smpPos, patPos; if(!file.ReadVector(insPos, fileHeader.insnum) || !file.ReadVector(smpPos, fileHeader.smpnum) || !file.ReadVector(patPos, fileHeader.patnum)) { return false; } // Find the first parapointer. // This is used for finding out whether the edit history is actually stored in the file or not, // as some early versions of Schism Tracker set the history flag, but didn't save anything. // We will consider the history invalid if it ends after the first parapointer. uint32 minPtr = Util::MaxValueOfType(minPtr); for(uint32 pos : insPos) { if(pos > 0) minPtr = std::min(minPtr, pos); } for(uint32 pos : smpPos) { if(pos > 0) minPtr = std::min(minPtr, pos); } for(uint32 pos : patPos) { if(pos > 0) minPtr = std::min(minPtr, pos); } if(fileHeader.special & ITFileHeader::embedSongMessage) { minPtr = std::min(minPtr, fileHeader.msgoffset); } const bool possiblyUNMO3 = fileHeader.cmwt == 0x0214 && fileHeader.cwtv == 0x0214 && fileHeader.highlight_major == 0 && fileHeader.highlight_minor == 0 && fileHeader.pwd == 0 && fileHeader.reserved == 0 && (fileHeader.flags & (ITFileHeader::useMIDIPitchController | ITFileHeader::reqEmbeddedMIDIConfig)) == 0; if(possiblyUNMO3 && fileHeader.insnum == 0 && fileHeader.smpnum > 0 && file.GetPosition() + 4 * smpPos.size() + 2 <= minPtr) { // UNMO3 < v2.4.0.1 reserves some space for instrument parapointers even in sample mode. // This makes reading MIDI macros and plugin information impossible. // Note: While UNMO3 and CheeseTracker header fingerprints are almost identical, we cannot mis-detect CheeseTracker here, // as it always sets the instrument mode flag and writes non-zero row highlights. bool oldUNMO3 = true; for(uint16 i = 0; i < fileHeader.smpnum; i++) { if(file.ReadUint32LE() != 0) { oldUNMO3 = false; file.SkipBack(4 + i * 4); break; } } if(oldUNMO3) { m_madeWithTracker = MPT_USTRING("UNMO3 <= 2.4"); } } // Reading IT Edit History Info // This is only supposed to be present if bit 1 of the special flags is set. // However, old versions of Schism and probably other trackers always set this bit // even if they don't write the edit history count. So we have to filter this out... // This is done by looking at the parapointers. If the history data ends after // the first parapointer, we assume that it's actually no history data. if(fileHeader.special & ITFileHeader::embedEditHistory) { const uint16 nflt = file.ReadUint16LE(); if(file.CanRead(nflt * sizeof(ITHistoryStruct)) && file.GetPosition() + nflt * sizeof(ITHistoryStruct) <= minPtr) { m_FileHistory.resize(nflt); for(auto &mptHistory : m_FileHistory) { ITHistoryStruct itHistory; file.ReadStruct(itHistory); itHistory.ConvertToMPT(mptHistory); } if(possiblyUNMO3 && nflt == 0) { if(fileHeader.special & ITFileHeader::embedPatternHighlights) m_madeWithTracker = MPT_USTRING("UNMO3 <= 2.4.0.1"); // Set together with MIDI macro embed flag else m_madeWithTracker = MPT_USTRING("UNMO3"); // Either 2.4.0.2+ or no MIDI macros embedded } } else { // Oops, we were not supposed to read this. file.SkipBack(2); } } else if(possiblyUNMO3 && fileHeader.special <= 1) { // UNMO3 < v2.4.0.1 will set the edit history special bit iff the MIDI macro embed bit is also set, // but it always writes the two extra bytes for the edit history length (zeroes). // If MIDI macros are embedded, we are fine and end up in the first case of the if statement (read edit history). // Otherwise we end up here and might have to read the edit history length. if(file.ReadUint16LE() == 0) { m_madeWithTracker = MPT_USTRING("UNMO3 <= 2.4"); } else { // These were not zero bytes, but potentially belong to the upcoming MIDI config - need to skip back. // I think the only application that could end up here is CheeseTracker, if it allows to write 0 for both row highlight values. // IT 2.14 itself will always write the edit history. file.SkipBack(2); } } // Reading MIDI Output & Macros bool hasMidiConfig = (fileHeader.flags & ITFileHeader::reqEmbeddedMIDIConfig) || (fileHeader.special & ITFileHeader::embedMIDIConfiguration); if(hasMidiConfig && file.ReadStruct(m_MidiCfg)) { m_MidiCfg.Sanitize(); } // Ignore MIDI data. Fixes some files like denonde.it that were made with old versions of Impulse Tracker (which didn't support Zxx filters) and have Zxx effects in the patterns. if(fileHeader.cwtv < 0x0214) { m_MidiCfg.ClearZxxMacros(); } // Read pattern names: "PNAM" FileReader patNames; if(file.ReadMagic("PNAM")) { patNames = file.ReadChunk(file.ReadUint32LE()); } m_nChannels = 1; // Read channel names: "CNAM" if(file.ReadMagic("CNAM")) { FileReader chnNames = file.ReadChunk(file.ReadUint32LE()); const CHANNELINDEX readChns = std::min(MAX_BASECHANNELS, static_cast(chnNames.GetLength() / MAX_CHANNELNAME)); m_nChannels = readChns; for(CHANNELINDEX i = 0; i < readChns; i++) { chnNames.ReadString(ChnSettings[i].szName, MAX_CHANNELNAME); } } // Read mix plugins information FileReader pluginChunk = file.ReadChunk((minPtr >= file.GetPosition()) ? minPtr - file.GetPosition() : file.BytesLeft()); LoadMixPlugins(pluginChunk); // Read Song Message if((fileHeader.special & ITFileHeader::embedSongMessage) && fileHeader.msglength > 0 && file.Seek(fileHeader.msgoffset)) { // Generally, IT files should use CR for line endings. However, ChibiTracker uses LF. One could do... // if(itHeader.cwtv == 0x0214 && itHeader.cmwt == 0x0214 && itHeader.reserved == ITFileHeader::chibiMagic) --> Chibi detected. // But we'll just use autodetection here: m_songMessage.Read(file, fileHeader.msglength, SongMessage::leAutodetect); } // Reading Instruments m_nInstruments = 0; if(fileHeader.flags & ITFileHeader::instrumentMode) { m_nInstruments = std::min(fileHeader.insnum, MAX_INSTRUMENTS - 1); } for(INSTRUMENTINDEX i = 0; i < GetNumInstruments(); i++) { if(insPos[i] > 0 && file.Seek(insPos[i]) && file.CanRead(fileHeader.cmwt < 0x200 ? sizeof(ITOldInstrument) : sizeof(ITInstrument))) { ModInstrument *instrument = AllocateInstrument(i + 1); if(instrument != nullptr) { ITInstrToMPT(file, *instrument, fileHeader.cmwt); // MIDI Pitch Wheel Depth is a global setting in IT. Apply it to all instruments. instrument->midiPWD = fileHeader.pwd; } } } // In order to properly compute the position, in file, of eventual extended settings // such as "attack" we need to keep the "real" size of the last sample as those extra // setting will follow this sample in the file FileReader::off_t lastSampleOffset = 0; if(fileHeader.smpnum > 0) { lastSampleOffset = smpPos[fileHeader.smpnum - 1] + sizeof(ITSample); } bool possibleXMconversion = false; // Reading Samples m_nSamples = std::min(fileHeader.smpnum, MAX_SAMPLES - 1); bool lastSampleCompressed = false; for(SAMPLEINDEX i = 0; i < GetNumSamples(); i++) { ITSample sampleHeader; if(smpPos[i] > 0 && file.Seek(smpPos[i]) && file.ReadStruct(sampleHeader)) { // IT does not check for the IMPS magic, and some bad XM->IT converter out there doesn't write the magic bytes for empty sample slots. ModSample &sample = Samples[i + 1]; size_t sampleOffset = sampleHeader.ConvertToMPT(sample); mpt::String::Read(m_szNames[i + 1], sampleHeader.name); if(!file.Seek(sampleOffset)) continue; lastSampleCompressed = false; if(!sample.uFlags[SMP_KEEPONDISK]) { SampleIO sampleIO = sampleHeader.GetSampleFormat(fileHeader.cwtv); if(loadFlags & loadSampleData) { sampleIO.ReadSample(sample, file); } else { if(sampleIO.IsVariableLengthEncoded()) lastSampleCompressed = true; else file.Skip(sampleIO.CalculateEncodedSize(sample.nLength)); } if(sampleIO.GetEncoding() == SampleIO::unsignedPCM && sample.nLength != 0) { // There is some XM to IT converter (don't know which one) and it identifies as IT 2.04. // The only safe way to distinguish it from an IT-saved file are the unsigned samples. possibleXMconversion = true; } } else { // External sample in MPTM file size_t strLen; file.ReadVarInt(strLen); if(loadFlags & loadSampleData) { std::string filenameU8; file.ReadString(filenameU8, strLen); #if defined(MPT_EXTERNAL_SAMPLES) SetSamplePath(i + 1, mpt::PathString::FromUTF8(filenameU8)); #elif !defined(LIBOPENMPT_BUILD_TEST) AddToLog(LogWarning, mpt::format(MPT_USTRING("Loading external sample %1 ('%2') failed: External samples are not supported."))(i, mpt::ToUnicode(mpt::CharsetUTF8, filenameU8))); #endif // MPT_EXTERNAL_SAMPLES } else { file.Skip(strLen); } } lastSampleOffset = std::max(lastSampleOffset, file.GetPosition()); } } m_nSamples = std::max(SAMPLEINDEX(1), GetNumSamples()); if(possibleXMconversion && fileHeader.cwtv == 0x0204 && fileHeader.cmwt == 0x0200 && fileHeader.special == 0 && fileHeader.reserved == 0 && (fileHeader.flags & ~ITFileHeader::linearSlides) == (ITFileHeader::useStereoPlayback | ITFileHeader::instrumentMode | ITFileHeader::itOldEffects) && fileHeader.globalvol == 128 && fileHeader.mv == 48 && fileHeader.sep == 128 && fileHeader.pwd == 0 && fileHeader.msglength == 0) { for(uint8 pan : fileHeader.chnpan) { if(pan != 0x20 && pan != 0xA0) possibleXMconversion = false; } for(uint8 vol : fileHeader.chnvol) { if(vol != 0x40) possibleXMconversion = false; } for(size_t i = 20; i < mpt::size(fileHeader.songname); i++) { if(fileHeader.songname[i] != 0) possibleXMconversion = false; } if(possibleXMconversion) m_madeWithTracker = MPT_USTRING("XM Conversion"); } m_nMinPeriod = 0; m_nMaxPeriod = int32_max; PATTERNINDEX numPats = std::min(static_cast(patPos.size()), GetModSpecifications().patternsMax); if(numPats != patPos.size()) { // Hack: Notify user here if file contains more patterns than what can be read. AddToLog(mpt::format(str_PatternSetTruncationNote)(patPos.size(), numPats)); } if(!(loadFlags & loadPatternData)) { numPats = 0; } // Checking for number of used channels, which is not explicitely specified in the file. for(PATTERNINDEX pat = 0; pat < numPats; pat++) { if(patPos[pat] == 0 || !file.Seek(patPos[pat])) continue; uint16 len = file.ReadUint16LE(); ROWINDEX numRows = file.ReadUint16LE(); if(numRows < 1 || numRows > MAX_PATTERN_ROWS || !file.Skip(4)) continue; FileReader patternData = file.ReadChunk(len); ROWINDEX row = 0; std::vector chnMask(GetNumChannels()); while(row < numRows && patternData.CanRead(1)) { uint8 b = patternData.ReadUint8(); if(!b) { row++; continue; } CHANNELINDEX ch = (b & IT_bitmask_patternChanField_c); // 0x7f We have some data grab a byte keeping only 7 bits if(ch) { ch = (ch - 1);// & IT_bitmask_patternChanMask_c; // 0x3f mask of the byte again, keeping only 6 bits } if(ch >= chnMask.size()) { chnMask.resize(ch + 1, 0); } if(b & IT_bitmask_patternChanEnabled_c) // 0x80 check if the upper bit is enabled. { chnMask[ch] = patternData.ReadUint8(); // set the channel mask for this channel. } // Channel used if(chnMask[ch] & 0x0F) // if this channel is used set m_nChannels { if(ch >= GetNumChannels() && ch < MAX_BASECHANNELS) { m_nChannels = ch + 1; } } // Now we actually update the pattern-row entry the note,instrument etc. // Note if(chnMask[ch] & 1) patternData.Skip(1); // Instrument if(chnMask[ch] & 2) patternData.Skip(1); // Volume if(chnMask[ch] & 4) patternData.Skip(1); // Effect if(chnMask[ch] & 8) patternData.Skip(2); } lastSampleOffset = std::max(lastSampleOffset, file.GetPosition()); } // Compute extra instruments settings position if(lastSampleOffset > 0) { file.Seek(lastSampleOffset); if(lastSampleCompressed) { // If the last sample was compressed, we do not know where it ends. // Hence, in case we decided not to decode the sample data, we now // have to emulate this until we reach EOF or some instrument / song properties. while(file.CanRead(4)) { if(file.ReadMagic("XTPM") || file.ReadMagic("STPM")) { uint32 id = file.ReadUint32LE(); file.SkipBack(8); // Our chunk IDs should only contain ASCII characters if(!(id & 0x80808080) && (id & 0x60606060)) { break; } } file.Skip(file.ReadUint16LE()); } } } // Load instrument and song extensions. LoadExtendedInstrumentProperties(file, &interpretModPlugMade); if(interpretModPlugMade && m_madeWithTracker != MPT_USTRING("BeRoTracker")) { m_playBehaviour.reset(); m_nMixLevels = mixLevelsOriginal; } // Need to do this before reading the patterns because m_nChannels might be modified by LoadExtendedSongProperties. *sigh* LoadExtendedSongProperties(file, &interpretModPlugMade); // Reading Patterns Patterns.ResizeArray(numPats); for(PATTERNINDEX pat = 0; pat < numPats; pat++) { if(patPos[pat] == 0 || !file.Seek(patPos[pat])) { // Empty 64-row pattern if(!Patterns.Insert(pat, 64)) { AddToLog(mpt::format("Allocating patterns failed starting from pattern %1")(pat)); break; } // Now (after the Insert() call), we can read the pattern name. CopyPatternName(Patterns[pat], patNames); continue; } uint16 len = file.ReadUint16LE(); ROWINDEX numRows = file.ReadUint16LE(); if(!file.Skip(4) || !Patterns.Insert(pat, numRows)) continue; FileReader patternData = file.ReadChunk(len); // Now (after the Insert() call), we can read the pattern name. CopyPatternName(Patterns[pat], patNames); std::vector chnMask(GetNumChannels()); std::vector lastValue(GetNumChannels(), ModCommand::Empty()); auto patData = Patterns[pat].begin(); ROWINDEX row = 0; while(row < numRows && patternData.CanRead(1)) { uint8 b = patternData.ReadUint8(); if(!b) { row++; patData += GetNumChannels(); continue; } CHANNELINDEX ch = b & IT_bitmask_patternChanField_c; // 0x7f if(ch) { ch = (ch - 1); //& IT_bitmask_patternChanMask_c; // 0x3f } if(ch >= chnMask.size()) { chnMask.resize(ch + 1, 0); lastValue.resize(ch + 1, ModCommand::Empty()); MPT_ASSERT(chnMask.size() <= GetNumChannels()); } if(b & IT_bitmask_patternChanEnabled_c) // 0x80 { chnMask[ch] = patternData.ReadUint8(); } // Now we grab the data for this particular row/channel. ModCommand dummy; ModCommand &m = ch < m_nChannels ? patData[ch] : dummy; if(chnMask[ch] & 0x10) { m.note = lastValue[ch].note; } if(chnMask[ch] & 0x20) { m.instr = lastValue[ch].instr; } if(chnMask[ch] & 0x40) { m.volcmd = lastValue[ch].volcmd; m.vol = lastValue[ch].vol; } if(chnMask[ch] & 0x80) { m.command = lastValue[ch].command; m.param = lastValue[ch].param; } if(chnMask[ch] & 1) // Note { uint8 note = patternData.ReadUint8(); if(note < 0x80) note += NOTE_MIN; if(!(GetType() & MOD_TYPE_MPT)) { if(note > NOTE_MAX && note < 0xFD) note = NOTE_FADE; else if(note == 0xFD) note = NOTE_NONE; } m.note = note; lastValue[ch].note = note; } if(chnMask[ch] & 2) { uint8 instr = patternData.ReadUint8(); m.instr = instr; lastValue[ch].instr = instr; } if(chnMask[ch] & 4) { uint8 vol = patternData.ReadUint8(); // 0-64: Set Volume if(vol <= 64) { m.volcmd = VOLCMD_VOLUME; m.vol = vol; } else // 128-192: Set Panning if(vol >= 128 && vol <= 192) { m.volcmd = VOLCMD_PANNING; m.vol = vol - 128; } else // 65-74: Fine Volume Up if(vol < 75) { m.volcmd = VOLCMD_FINEVOLUP; m.vol = vol - 65; } else // 75-84: Fine Volume Down if(vol < 85) { m.volcmd = VOLCMD_FINEVOLDOWN; m.vol = vol - 75; } else // 85-94: Volume Slide Up if(vol < 95) { m.volcmd = VOLCMD_VOLSLIDEUP; m.vol = vol - 85; } else // 95-104: Volume Slide Down if(vol < 105) { m.volcmd = VOLCMD_VOLSLIDEDOWN; m.vol = vol - 95; } else // 105-114: Pitch Slide Up if(vol < 115) { m.volcmd = VOLCMD_PORTADOWN; m.vol = vol - 105; } else // 115-124: Pitch Slide Down if(vol < 125) { m.volcmd = VOLCMD_PORTAUP; m.vol = vol - 115; } else // 193-202: Portamento To if(vol >= 193 && vol <= 202) { m.volcmd = VOLCMD_TONEPORTAMENTO; m.vol = vol - 193; } else // 203-212: Vibrato depth if(vol >= 203 && vol <= 212) { m.volcmd = VOLCMD_VIBRATODEPTH; m.vol = vol - 203; // Old versions of ModPlug saved this as vibrato speed instead, so let's fix that. if(m.vol && m_dwLastSavedWithVersion && m_dwLastSavedWithVersion <= MAKE_VERSION_NUMERIC(1, 17, 02, 54)) m.volcmd = VOLCMD_VIBRATOSPEED; } else // 213-222: Unused (was velocity) // 223-232: Offset if(vol >= 223 && vol <= 232) { m.volcmd = VOLCMD_OFFSET; m.vol = vol - 223; } lastValue[ch].volcmd = m.volcmd; lastValue[ch].vol = m.vol; } // Reading command/param if(chnMask[ch] & 8) { m.command = patternData.ReadUint8(); m.param = patternData.ReadUint8(); S3MConvert(m, true); // In some IT-compatible trackers, it is possible to input a parameter without a command. // In this case, we still need to update the last value memory. OpenMPT didn't do this until v1.25.01.07. // Example: ckbounce.it lastValue[ch].command = m.command; lastValue[ch].param = m.param; } } } if(!m_dwLastSavedWithVersion && fileHeader.cwtv == 0x0888) { // Up to OpenMPT 1.17.02.45 (r165), it was possible that the "last saved with" field was 0 // when saving a file in OpenMPT for the first time. m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 17, 00, 00); } if(m_dwLastSavedWithVersion && m_madeWithTracker.empty()) { m_madeWithTracker = MPT_USTRING("OpenMPT ") + MptVersion::ToUString(m_dwLastSavedWithVersion); if(memcmp(&fileHeader.reserved, "OMPT", 4) && (fileHeader.cwtv & 0xF000) == 0x5000) { m_madeWithTracker += MPT_USTRING(" (compatibility export)"); } else if(MptVersion::IsTestBuild(m_dwLastSavedWithVersion)) { m_madeWithTracker += MPT_USTRING(" (test build)"); } } else { switch(fileHeader.cwtv >> 12) { case 0: if(!m_madeWithTracker.empty()) { // BeRoTracker has been detected above. } else if(fileHeader.cwtv == 0x0214 && fileHeader.cmwt == 0x0200 && fileHeader.flags == 9 && fileHeader.special == 0 && fileHeader.highlight_major == 0 && fileHeader.highlight_minor == 0 && fileHeader.insnum == 0 && fileHeader.patnum + 1 == fileHeader.ordnum && fileHeader.globalvol == 128 && fileHeader.mv == 100 && fileHeader.speed == 1 && fileHeader.sep == 128 && fileHeader.pwd == 0 && fileHeader.msglength == 0 && fileHeader.msgoffset == 0 && fileHeader.reserved == 0) { m_madeWithTracker = MPT_USTRING("OpenSPC conversion"); } else if(fileHeader.cwtv == 0x0214 && fileHeader.cmwt == 0x0200 && fileHeader.reserved == 0) { // ModPlug Tracker 1.00a5, instruments 560 bytes apart m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 00, 00, A5); m_madeWithTracker = MPT_USTRING("ModPlug Tracker 1.00a5"); interpretModPlugMade = true; } else if(fileHeader.cwtv == 0x0214 && fileHeader.cmwt == 0x0214 && !memcmp(&fileHeader.reserved, "CHBI", 4)) { m_madeWithTracker = MPT_USTRING("ChibiTracker"); } else if(fileHeader.cwtv == 0x0214 && fileHeader.cmwt == 0x0214 && fileHeader.special <= 1 && fileHeader.pwd == 0 && fileHeader.reserved == 0 && (fileHeader.flags & (ITFileHeader::vol0Optimisations | ITFileHeader::instrumentMode | ITFileHeader::useMIDIPitchController | ITFileHeader::reqEmbeddedMIDIConfig | ITFileHeader::extendedFilterRange)) == ITFileHeader::instrumentMode && m_nSamples > 0 && !strcmp(Samples[1].filename, "XXXXXXXX.YYY")) { m_madeWithTracker = MPT_USTRING("CheeseTracker"); } else if(fileHeader.cmwt < 0x0300) { if(fileHeader.cmwt > 0x0214) { m_madeWithTracker = MPT_USTRING("Impulse Tracker 2.15"); } else if(fileHeader.cwtv > 0x0214) { // Patched update of IT 2.14 (0x0215 - 0x0217 == p1 - p3) // p4 (as found on modland) adds the ITVSOUND driver, but doesn't seem to change // anything as far as file saving is concerned. m_madeWithTracker = mpt::format(MPT_USTRING("Impulse Tracker 2.14p%1"))(fileHeader.cwtv - 0x0214); } else { m_madeWithTracker = mpt::format(MPT_USTRING("Impulse Tracker %1.%2"))((fileHeader.cwtv & 0x0F00) >> 8, mpt::ufmt::hex0<2>((fileHeader.cwtv & 0xFF))); } if(m_FileHistory.empty() && fileHeader.reserved != 0) { // Starting from version 2.07, IT encrypts the total edit time of a module in the "reserved" field uint32 editTime = fileHeader.reserved; if(fileHeader.cwtv >= 0x0208) { editTime ^= 0x4954524B; // 'ITRK' editTime = (editTime >> 7) | (editTime << (32 - 7)); editTime = -(int32)editTime; editTime = (editTime << 4) | (editTime >> (32 - 4)); editTime ^= 0x4A54484C; // 'JTHL' } FileHistory hist; MemsetZero(hist); hist.openTime = static_cast(editTime * (HISTORY_TIMER_PRECISION / 18.2f)); m_FileHistory.push_back(hist); } } break; case 1: m_madeWithTracker = GetSchismTrackerVersion(fileHeader.cwtv); // Hertz in linear mode: Added 2015-01-29, https://github.com/schismtracker/schismtracker/commit/671b30311082a0e7df041fca25f989b5d2478f69 if(fileHeader.cwtv < SchismVersionFromDate<2015, 01, 29>::Version()) m_playBehaviour.reset(kHertzInLinearMode); // Qxx with short samples: Added 2016-05-13, https://github.com/schismtracker/schismtracker/commit/e7b1461fe751554309fd403713c2a1ef322105ca if(fileHeader.cwtv < SchismVersionFromDate<2016, 05, 13>::Version()) m_playBehaviour.reset(kITShortSampleRetrig); break; case 4: m_madeWithTracker = mpt::format(MPT_USTRING("pyIT %1.%2"))((fileHeader.cwtv & 0x0F00) >> 8, mpt::ufmt::hex0<2>((fileHeader.cwtv & 0xFF))); break; case 6: m_madeWithTracker = MPT_USTRING("BeRoTracker"); break; case 7: m_madeWithTracker = mpt::format(MPT_USTRING("ITMCK %1.%2.%3"))((fileHeader.cwtv >> 8) & 0x0F, (fileHeader.cwtv >> 4) & 0x0F, fileHeader.cwtv & 0x0F); break; case 0xD: m_madeWithTracker = MPT_USTRING("spc2it"); break; } } if(GetType() == MOD_TYPE_MPT) { // START - mpt specific: if(fileHeader.cwtv > 0x0889 && file.Seek(mptStartPos)) { LoadMPTMProperties(file, fileHeader.cwtv); } } return true; } void CSoundFile::LoadMPTMProperties(FileReader &file, uint16 cwtv) { mpt::istringstream iStrm(file.GetRawDataAsString()); if(cwtv >= 0x88D) { srlztn::SsbRead ssb(iStrm); ssb.BeginRead("mptm", MptVersion::num); ssb.ReadItem(GetTuneSpecificTunings(), "0", &ReadTuningCollection); ssb.ReadItem(*this, "1", &ReadTuningMap); ssb.ReadItem(Order, "2", &ReadModSequenceOld); ssb.ReadItem(Patterns, FileIdPatterns, &ReadModPatterns); ssb.ReadItem(Order, FileIdSequences, &ReadModSequences); if(ssb.GetStatus() & srlztn::SNT_FAILURE) { AddToLog(LogError, MPT_USTRING("Unknown error occurred while deserializing file.")); } } else { // Loading for older files. std::string name; if(GetTuneSpecificTunings().Deserialize(iStrm, name) != Tuning::SerializationResult::Success) { AddToLog(LogError, MPT_USTRING("Loading tune specific tunings failed.")); } else { ReadTuningMapImpl(iStrm, *this, 0, cwtv < 0x88C); } } } #ifndef MODPLUG_NO_FILESAVE // Save edit history. Pass a null pointer for *f to retrieve the number of bytes that would be written. static uint32 SaveITEditHistory(const CSoundFile &sndFile, FILE *f) { size_t num = sndFile.GetFileHistory().size(); #ifdef MODPLUG_TRACKER const CModDoc *pModDoc = sndFile.GetpModDoc(); num += (pModDoc != nullptr) ? 1 : 0; // + 1 for this session #endif // MODPLUG_TRACKER uint16 fnum = mpt::saturate_cast(num); // Number of entries that are actually going to be written const uint32 bytesWritten = 2 + fnum * 8; // Number of bytes that are actually going to be written if(f == nullptr) return bytesWritten; // Write number of history entries mpt::IO::WriteIntLE(f, fnum); // Write history data const size_t start = (num > uint16_max) ? num - uint16_max : 0; for(size_t n = start; n < num; n++) { FileHistory mptHistory; #ifdef MODPLUG_TRACKER if(n < sndFile.GetFileHistory().size()) #endif // MODPLUG_TRACKER { // Previous timestamps mptHistory = sndFile.GetFileHistory().at(n); #ifdef MODPLUG_TRACKER } else { // Current ("new") timestamp const time_t creationTime = pModDoc->GetCreationTime(); MemsetZero(mptHistory.loadDate); //localtime_s(&loadDate, &creationTime); const tm* const p = localtime(&creationTime); if (p != nullptr) mptHistory.loadDate = *p; else sndFile.AddToLog("Unable to retrieve current time."); mptHistory.openTime = (uint32)(difftime(time(nullptr), creationTime) * (double)HISTORY_TIMER_PRECISION); #endif // MODPLUG_TRACKER } ITHistoryStruct itHistory; itHistory.ConvertToIT(mptHistory); mpt::IO::Write(f, itHistory); } return bytesWritten; } bool CSoundFile::SaveIT(const mpt::PathString &filename, bool compatibilityExport) { const CModSpecifications &specs = (GetType() == MOD_TYPE_MPT ? ModSpecs::mptm : (compatibilityExport ? ModSpecs::it : ModSpecs::itEx)); uint32 dwChnNamLen; ITFileHeader itHeader; uint64 dwPos = 0; uint32 dwHdrPos = 0, dwExtra = 0; FILE *f; if(filename.empty() || ((f = mpt_fopen(filename, "wb")) == NULL)) return false; // Writing Header MemsetZero(itHeader); dwChnNamLen = 0; memcpy(itHeader.id, "IMPM", 4); mpt::String::Write(itHeader.songname, m_songName); itHeader.highlight_minor = (uint8)std::min(m_nDefaultRowsPerBeat, ROWINDEX(uint8_max)); itHeader.highlight_major = (uint8)std::min(m_nDefaultRowsPerMeasure, ROWINDEX(uint8_max)); if(GetType() == MOD_TYPE_MPT) { itHeader.ordnum = Order().GetLengthTailTrimmed(); if(Order().NeedsExtraDatafield() && itHeader.ordnum > 256) { // If there are more order items, write them elsewhere. itHeader.ordnum = 256; } } else { // An additional "---" pattern is appended so Impulse Tracker won't ignore the last order item. // Interestingly, this can exceed IT's 256 order limit. Also, IT will always save at least two orders. itHeader.ordnum = std::min(Order().GetLengthTailTrimmed(), specs.ordersMax) + 1; if(itHeader.ordnum < 2) itHeader.ordnum = 2; } itHeader.insnum = std::min(m_nInstruments, specs.instrumentsMax); itHeader.smpnum = std::min(m_nSamples, specs.samplesMax); itHeader.patnum = std::min(Patterns.GetNumPatterns(), specs.patternsMax); // Parapointers std::vector patpos(itHeader.patnum, 0); std::vector smppos(itHeader.smpnum, 0); std::vector inspos(itHeader.insnum, 0); //VERSION if(GetType() == MOD_TYPE_MPT) { // MPTM itHeader.cwtv = verMptFileVer; // Used in OMPT-hack versioning. itHeader.cmwt = 0x888; } else { // IT MptVersion::VersionNum vVersion = MptVersion::num; itHeader.cwtv = 0x5000 | (uint16)((vVersion >> 16) & 0x0FFF); // format: txyy (t = tracker ID, x = version major, yy = version minor), e.g. 0x5117 (OpenMPT = 5, 117 = v1.17) itHeader.cmwt = 0x0214; // Common compatible tracker :) // Hack from schism tracker: for(INSTRUMENTINDEX nIns = 1; nIns <= GetNumInstruments(); nIns++) { if(Instruments[nIns] && Instruments[nIns]->PitchEnv.dwFlags[ENV_FILTER]) { itHeader.cmwt = 0x0216; break; } } if(!compatibilityExport) { // This way, we indicate that the file will most likely contain OpenMPT hacks. Compatibility export puts 0 here. memcpy(&itHeader.reserved, "OMPT", 4); } } itHeader.flags = ITFileHeader::useStereoPlayback | ITFileHeader::useMIDIPitchController; itHeader.special = ITFileHeader::embedEditHistory | ITFileHeader::embedPatternHighlights; if(m_nInstruments) itHeader.flags |= ITFileHeader::instrumentMode; if(m_SongFlags[SONG_LINEARSLIDES]) itHeader.flags |= ITFileHeader::linearSlides; if(m_SongFlags[SONG_ITOLDEFFECTS]) itHeader.flags |= ITFileHeader::itOldEffects; if(m_SongFlags[SONG_ITCOMPATGXX]) itHeader.flags |= ITFileHeader::itCompatGxx; if(m_SongFlags[SONG_EXFILTERRANGE] && !compatibilityExport) itHeader.flags |= ITFileHeader::extendedFilterRange; itHeader.globalvol = (uint8)(m_nDefaultGlobalVolume >> 1); itHeader.mv = (uint8)MIN(m_nSamplePreAmp, 128u); itHeader.speed = (uint8)MIN(m_nDefaultSpeed, 255u); itHeader.tempo = (uint8)MIN(m_nDefaultTempo.GetInt(), 255u); //Limit this one to 255, we save the real one as an extension below. itHeader.sep = 128; // pan separation // IT doesn't have a per-instrument Pitch Wheel Depth setting, so we just store the first non-zero PWD setting in the header. for(INSTRUMENTINDEX ins = 1; ins < GetNumInstruments(); ins++) { if(Instruments[ins] != nullptr && Instruments[ins]->midiPWD != 0) { itHeader.pwd = (uint8)mpt::abs(Instruments[ins]->midiPWD); break; } } dwHdrPos = sizeof(itHeader) + itHeader.ordnum; // Channel Pan and Volume memset(itHeader.chnpan, 0xA0, 64); memset(itHeader.chnvol, 64, 64); for(CHANNELINDEX ich = 0; ich < std::min(m_nChannels, CHANNELINDEX(64)); ich++) // Header only has room for settings for 64 chans... { itHeader.chnpan[ich] = (uint8)(ChnSettings[ich].nPan >> 2); if (ChnSettings[ich].dwFlags[CHN_SURROUND]) itHeader.chnpan[ich] = 100; itHeader.chnvol[ich] = (uint8)(ChnSettings[ich].nVolume); #ifdef MODPLUG_TRACKER if(TrackerSettings::Instance().MiscSaveChannelMuteStatus) #endif if (ChnSettings[ich].dwFlags[CHN_MUTE]) itHeader.chnpan[ich] |= 0x80; } // Channel names if(!compatibilityExport) { for(CHANNELINDEX i = 0; i < m_nChannels; i++) { if(ChnSettings[i].szName[0]) { dwChnNamLen = (i + 1) * MAX_CHANNELNAME; } } if(dwChnNamLen) dwExtra += dwChnNamLen + 8; } if(!m_MidiCfg.IsMacroDefaultSetupUsed()) { itHeader.flags |= ITFileHeader::reqEmbeddedMIDIConfig; itHeader.special |= ITFileHeader::embedMIDIConfiguration; dwExtra += sizeof(MIDIMacroConfigData); } // Pattern Names const PATTERNINDEX numNamedPats = compatibilityExport ? 0 : Patterns.GetNumNamedPatterns(); if(numNamedPats > 0) { dwExtra += (numNamedPats * MAX_PATTERNNAME) + 8; } // Mix Plugins. Just calculate the size of this extra block for now. if(!compatibilityExport) { dwExtra += SaveMixPlugins(nullptr, true); } // Edit History. Just calculate the size of this extra block for now. dwExtra += SaveITEditHistory(*this, nullptr); // Comments uint16 msglength = 0; if(!m_songMessage.empty()) { itHeader.special |= ITFileHeader::embedSongMessage; itHeader.msglength = msglength = mpt::saturate_cast(m_songMessage.length() + 1u); itHeader.msgoffset = dwHdrPos + dwExtra + (itHeader.insnum + itHeader.smpnum + itHeader.patnum) * 4; } // Write file header mpt::IO::Write(f, itHeader); Order().WriteAsByte(f, itHeader.ordnum); for(uint16 i = 0; i < itHeader.insnum; ++i) { mpt::IO::WriteIntLE(f, inspos[i]); } for(uint16 i = 0; i < itHeader.smpnum; ++i) { mpt::IO::WriteIntLE(f, smppos[i]); } for(uint16 i = 0; i < itHeader.patnum; ++i) { mpt::IO::WriteIntLE(f, patpos[i]); } // Writing edit history information SaveITEditHistory(*this, f); // Writing midi cfg if(itHeader.flags & ITFileHeader::reqEmbeddedMIDIConfig) { mpt::IO::Write(f, static_cast(m_MidiCfg)); } // Writing pattern names if(numNamedPats) { mpt::IO::WriteRaw(f, "PNAM", 4); mpt::IO::WriteIntLE(f, numNamedPats * MAX_PATTERNNAME); for(PATTERNINDEX pat = 0; pat < numNamedPats; pat++) { char name[MAX_PATTERNNAME]; mpt::String::Write(name, Patterns[pat].GetName()); mpt::IO::Write(f, name); } } // Writing channel names if(dwChnNamLen && !compatibilityExport) { mpt::IO::WriteRaw(f, "CNAM", 4); mpt::IO::WriteIntLE(f, dwChnNamLen); uint32 nChnNames = dwChnNamLen / MAX_CHANNELNAME; for(uint32 inam = 0; inam < nChnNames; inam++) { char name[MAX_CHANNELNAME]; mpt::String::Write(name, ChnSettings[inam].szName); mpt::IO::Write(f, name); } } // Writing mix plugins info if(!compatibilityExport) { SaveMixPlugins(f, false); } // Writing song message dwPos = dwHdrPos + dwExtra + (itHeader.insnum + itHeader.smpnum + itHeader.patnum) * 4; if(itHeader.special & ITFileHeader::embedSongMessage) { dwPos += msglength; mpt::IO::WriteRaw(f, m_songMessage.c_str(), msglength); } // Writing instruments const ModInstrument dummyInstr; for(INSTRUMENTINDEX nins = 1; nins <= itHeader.insnum; nins++) { ITInstrumentEx iti; uint32 instSize; const ModInstrument &instr = (Instruments[nins] != nullptr) ? *Instruments[nins] : dummyInstr; instSize = iti.ConvertToIT(instr, compatibilityExport, *this); // Writing instrument inspos[nins - 1] = static_cast(dwPos); dwPos += instSize; mpt::IO::WritePartial(f, iti, instSize); } // Writing dummy sample headers (until we know the correct sample data offset) ITSample itss; MemsetZero(itss); for(SAMPLEINDEX smp = 0; smp < itHeader.smpnum; smp++) { smppos[smp] = static_cast(dwPos); dwPos += sizeof(ITSample); mpt::IO::Write(f, itss); } // Writing Patterns bool bNeedsMptPatSave = false; for(PATTERNINDEX pat = 0; pat < itHeader.patnum; pat++) { uint32 dwPatPos = static_cast(dwPos); if (!Patterns.IsValidPat(pat)) continue; if(Patterns[pat].GetOverrideSignature()) bNeedsMptPatSave = true; // Check for empty pattern if(Patterns[pat].GetNumRows() == 64 && Patterns.IsPatternEmpty(pat)) { patpos[pat] = 0; continue; } patpos[pat] = static_cast(dwPos); // Write pattern header ROWINDEX writeRows = mpt::saturate_cast(Patterns[pat].GetNumRows()); uint16 writeSize = 0; uint16le patinfo[4]; patinfo[0] = 0; patinfo[1] = (uint16)writeRows; patinfo[2] = 0; patinfo[3] = 0; mpt::IO::Write(f, patinfo); dwPos += 8; const CHANNELINDEX maxChannels = std::min(specs.channelsMax, GetNumChannels()); std::vector chnmask(maxChannels, 0xFF); std::vector lastvalue(maxChannels, ModCommand::Empty()); for(ROWINDEX row = 0; row < writeRows; row++) { uint32 len = 0; // Maximum 7 bytes per cell, plus end of row marker, so this buffer is always large enough to cover one row. uint8 buf[7 * MAX_BASECHANNELS + 1]; const ModCommand *m = Patterns[pat].GetRow(row); for(CHANNELINDEX ch = 0; ch < maxChannels; ch++, m++) { // Skip mptm-specific notes. if(m->IsPcNote()) { bNeedsMptPatSave = true; continue; } uint8 b = 0; uint8 command = m->command; uint8 param = m->param; uint8 vol = 0xFF; uint8 note = m->note; if (note != NOTE_NONE) b |= 1; if (m->IsNote()) note -= NOTE_MIN; if (note == NOTE_FADE && GetType() != MOD_TYPE_MPT) note = 0xF6; if (m->instr) b |= 2; if (m->volcmd != VOLCMD_NONE) { vol = std::min(m->vol, uint8(9)); switch(m->volcmd) { case VOLCMD_VOLUME: vol = std::min(m->vol, uint8(64)); break; case VOLCMD_PANNING: vol = std::min(m->vol, uint8(64)) + 128; break; case VOLCMD_VOLSLIDEUP: vol += 85; break; case VOLCMD_VOLSLIDEDOWN: vol += 95; break; case VOLCMD_FINEVOLUP: vol += 65; break; case VOLCMD_FINEVOLDOWN: vol += 75; break; case VOLCMD_VIBRATODEPTH: vol += 203; break; case VOLCMD_VIBRATOSPEED: if(command == CMD_NONE) { // illegal command -> move if possible command = CMD_VIBRATO; param = std::min(m->vol, uint8(15)) << 4; } else { vol = 203; } break; case VOLCMD_TONEPORTAMENTO: vol += 193; break; case VOLCMD_PORTADOWN: vol += 105; break; case VOLCMD_PORTAUP: vol += 115; break; case VOLCMD_OFFSET: if(!compatibilityExport) vol += 223; break; default: vol = 0xFF; } } if (vol != 0xFF) b |= 4; if (command != CMD_NONE) { S3MSaveConvert(command, param, true, compatibilityExport); if (command) b |= 8; } // Packing information if (b) { // Same note ? if (b & 1) { if ((note == lastvalue[ch].note) && (lastvalue[ch].volcmd & 1)) { b &= ~1; b |= 0x10; } else { lastvalue[ch].note = note; lastvalue[ch].volcmd |= 1; } } // Same instrument ? if (b & 2) { if ((m->instr == lastvalue[ch].instr) && (lastvalue[ch].volcmd & 2)) { b &= ~2; b |= 0x20; } else { lastvalue[ch].instr = m->instr; lastvalue[ch].volcmd |= 2; } } // Same volume column byte ? if (b & 4) { if ((vol == lastvalue[ch].vol) && (lastvalue[ch].volcmd & 4)) { b &= ~4; b |= 0x40; } else { lastvalue[ch].vol = vol; lastvalue[ch].volcmd |= 4; } } // Same command / param ? if (b & 8) { if ((command == lastvalue[ch].command) && (param == lastvalue[ch].param) && (lastvalue[ch].volcmd & 8)) { b &= ~8; b |= 0x80; } else { lastvalue[ch].command = command; lastvalue[ch].param = param; lastvalue[ch].volcmd |= 8; } } if (b != chnmask[ch]) { chnmask[ch] = b; buf[len++] = uint8((ch + 1) | IT_bitmask_patternChanEnabled_c); buf[len++] = b; } else { buf[len++] = uint8(ch + 1); } if (b & 1) buf[len++] = note; if (b & 2) buf[len++] = m->instr; if (b & 4) buf[len++] = vol; if (b & 8) { buf[len++] = command; buf[len++] = param; } } } buf[len++] = 0; if(writeSize > uint16_max - len) { AddToLog(mpt::format("%1 (%2 %3)")(str_tooMuchPatternData, str_pattern, pat)); break; } else { dwPos += len; writeSize += (uint16)len; mpt::IO::WriteRaw(f, buf, len); } } fseek(f, dwPatPos, SEEK_SET); patinfo[0] = writeSize; mpt::IO::Write(f, patinfo); fseek(f, static_cast(dwPos), SEEK_SET); } // Writing Sample Data for(SAMPLEINDEX smp = 1; smp <= itHeader.smpnum; smp++) { #ifdef MODPLUG_TRACKER uint32 type = GetType() == MOD_TYPE_IT ? 1 : 4; if(compatibilityExport) type = 2; bool compress = ((((Samples[smp].GetNumChannels() > 1) ? TrackerSettings::Instance().MiscITCompressionStereo : TrackerSettings::Instance().MiscITCompressionMono) & type) != 0); #else bool compress = false; #endif // MODPLUG_TRACKER // Old MPT, DUMB and probably other libraries will only consider the IT2.15 compression flag if the header version also indicates IT2.15. // MilkyTracker <= 0.90.85 will only assume IT2.15 compression with cmwt == 0x215, ignoring the delta flag completely. itss.ConvertToIT(Samples[smp], GetType(), compress, itHeader.cmwt >= 0x215, GetType() == MOD_TYPE_MPT); const bool isExternal = itss.cvt == ITSample::cvtExternalSample; mpt::String::Write(itss.name, m_szNames[smp]); itss.samplepointer = static_cast(dwPos); if(dwPos > uint32_max) { // Sample position does not fit into sample pointer! AddToLog(mpt::format("Cannot save sample %1: File size exceeds 4 GB.")(smp)); itss.samplepointer = 0; itss.length = 0; } SmpLength smpLength = itss.length; // Possibly truncated to 2^32 samples fseek(f, smppos[smp - 1], SEEK_SET); mpt::IO::Write(f, itss); if(dwPos > uint32_max) { continue; } // TODO this actually wraps around at 2 GB, so we either need to use the 64-bit seek API or warn earlier! fseek(f, static_cast(dwPos), SEEK_SET); if(!isExternal) { if(Samples[smp].nLength != smpLength) { // Sample length does not fit into IT header! AddToLog(mpt::format("Truncating sample %1: Length exceeds exceeds 4 gigasamples.")(smp)); } dwPos += itss.GetSampleFormat().WriteSample(f, Samples[smp], smpLength); } else { #ifdef MPT_EXTERNAL_SAMPLES const std::string filenameU8 = GetSamplePath(smp).AbsolutePathToRelative(filename.GetPath()).ToUTF8(); const size_t strSize = filenameU8.size(); size_t intBytes = 0; if(mpt::IO::WriteVarInt(f, strSize, &intBytes)) { dwPos += intBytes + strSize; mpt::IO::WriteRaw(f, filenameU8.data(), strSize); } #endif // MPT_EXTERNAL_SAMPLES } } //Save hacked-on extra info if(!compatibilityExport) { if(GetNumInstruments()) { SaveExtendedInstrumentProperties(itHeader.insnum, f); } SaveExtendedSongProperties(f); } // Updating offsets fseek(f, dwHdrPos, SEEK_SET); for(uint16 i = 0; i < itHeader.insnum; ++i) { mpt::IO::WriteIntLE(f, inspos[i]); } for(uint16 i = 0; i < itHeader.smpnum; ++i) { mpt::IO::WriteIntLE(f, smppos[i]); } for(uint16 i = 0; i < itHeader.patnum; ++i) { mpt::IO::WriteIntLE(f, patpos[i]); } if(GetType() == MOD_TYPE_IT) { fclose(f); return true; } //hack //BEGIN: MPT SPECIFIC: bool success = true; fseek(f, 0, SEEK_END); { mpt::FILE_ostream fout(f); const uint32 MPTStartPos = (uint32)fout.tellp(); // catch standard library truncating files MPT_ASSERT_ALWAYS(MPTStartPos > 0); srlztn::SsbWrite ssb(fout); ssb.BeginWrite("mptm", MptVersion::num); if(GetTuneSpecificTunings().GetNumTunings() > 0) ssb.WriteItem(GetTuneSpecificTunings(), "0", &WriteTuningCollection); if(AreNonDefaultTuningsUsed(*this)) ssb.WriteItem(*this, "1", &WriteTuningMap); if(Order().NeedsExtraDatafield()) ssb.WriteItem(Order, "2", &WriteModSequenceOld); if(bNeedsMptPatSave) ssb.WriteItem(Patterns, FileIdPatterns, &WriteModPatterns); ssb.WriteItem(Order, FileIdSequences, &WriteModSequences); ssb.FinishWrite(); if(ssb.GetStatus() & srlztn::SNT_FAILURE) { AddToLog(LogError, MPT_USTRING("Error occurred in writing MPTM extensions.")); } //Last 4 bytes should tell where the hack mpt things begin. if(!fout.good()) { fout.clear(); success = false; } mpt::IO::WriteIntLE(fout, MPTStartPos); fout.seekp(0, std::ios_base::end); } fclose(f); f = nullptr; //END : MPT SPECIFIC //NO WRITING HERE ANYMORE. return success; } #endif // MODPLUG_NO_FILESAVE #ifndef MODPLUG_NO_FILESAVE uint32 CSoundFile::SaveMixPlugins(FILE *f, bool bUpdate) { #ifndef NO_PLUGINS uint32 chinfo[MAX_BASECHANNELS]; char id[4]; uint32 nPluginSize; uint32 nTotalSize = 0; uint32 nChInfo = 0; for(PLUGINDEX i = 0; i < MAX_MIXPLUGINS; i++) { const SNDMIXPLUGIN &plugin = m_MixPlugins[i]; if(plugin.IsValidPlugin()) { nPluginSize = sizeof(SNDMIXPLUGININFO) + 4; // plugininfo+4 (datalen) if((plugin.pMixPlugin) && (bUpdate)) { plugin.pMixPlugin->SaveAllParameters(); } nPluginSize += plugin.pluginData.size(); uint32 MPTxPlugDataSize = 4 + sizeof(float32) + // 4 for ID and size of dryRatio 4 + sizeof(int32); // Default Program // for each extra entity, add 4 for ID, plus 4 for size of entity, plus size of entity nPluginSize += MPTxPlugDataSize + 4; //+4 is for size itself: sizeof(uint32) is 4 if(f) { // write plugin ID id[0] = 'F'; id[1] = i < 100 ? 'X' : '0' + i / 100; id[2] = '0' + (i / 10) % 10u; id[3] = '0' + (i % 10u); mpt::IO::WriteRaw(f, id, 4); // write plugin size: mpt::IO::WriteIntLE(f, nPluginSize); mpt::IO::Write(f, m_MixPlugins[i].Info); uint32 dataSize = mpt::saturate_cast(m_MixPlugins[i].pluginData.size()); mpt::IO::WriteIntLE(f, dataSize); if(dataSize) { mpt::IO::WriteRaw(f, m_MixPlugins[i].pluginData.data(), dataSize); } mpt::IO::WriteIntLE(f, MPTxPlugDataSize); // Dry/Wet ratio memcpy(id, "DWRT", 4); mpt::IO::WriteRaw(f, id, 4); // DWRT chunk does not include a size, so better make sure we always write 4 bytes here. STATIC_ASSERT(sizeof(IEEE754binary32LE) == 4); mpt::IO::Write(f, IEEE754binary32LE(m_MixPlugins[i].fDryRatio)); // Default program memcpy(id, "PROG", 4); mpt::IO::WriteRaw(f, id, 4); // PROG chunk does not include a size, so better make sure we always write 4 bytes here. STATIC_ASSERT(sizeof(m_MixPlugins[i].defaultProgram) == sizeof(int32)); mpt::IO::WriteIntLE(f, m_MixPlugins[i].defaultProgram); // Please, if you add any more chunks here, don't repeat history (see above) and *do* add a size field for your chunk, mmmkay? } nTotalSize += nPluginSize + 8; } } for(CHANNELINDEX j = 0; j < GetNumChannels(); j++) { if(j < MAX_BASECHANNELS) { if((chinfo[j] = ChnSettings[j].nMixPlugin) != 0) { nChInfo = j + 1; } } } if(nChInfo) { if(f) { memcpy(id, "CHFX", 4); mpt::IO::WriteRaw(f, id, 4); mpt::IO::WriteIntLE(f, nChInfo * 4); for(uint32 i = 0; i < nChInfo; ++i) { mpt::IO::WriteIntLE(f, chinfo[i]); } } nTotalSize += nChInfo * 4 + 8; } return nTotalSize; #else MPT_UNREFERENCED_PARAMETER(f); MPT_UNREFERENCED_PARAMETER(bUpdate); return 0; #endif // NO_PLUGINS } #endif // MODPLUG_NO_FILESAVE void CSoundFile::LoadMixPlugins(FileReader &file) { while(file.CanRead(9)) { char code[4]; file.ReadArray(code); const uint32 chunkSize = file.ReadUint32LE(); if(!memcmp(code, "IMPI", 4) // IT instrument, we definitely read too far || !memcmp(code, "IMPS", 4) // IT sample, ditto || !memcmp(code, "XTPM", 4) // Instrument extensions, ditto || !memcmp(code, "STPM", 4) // Song extensions, ditto || !file.CanRead(chunkSize)) { file.SkipBack(8); return; } FileReader chunk = file.ReadChunk(chunkSize); // Channel FX if(!memcmp(code, "CHFX", 4)) { for (size_t ch = 0; ch < MAX_BASECHANNELS; ch++) { ChnSettings[ch].nMixPlugin = static_cast(chunk.ReadUint32LE()); } #ifndef NO_PLUGINS } // Plugin Data FX00, ... FX99, F100, ... F255 #define ISNUMERIC(x) (code[(x)] >= '0' && code[(x)] <= '9') else if(code[0] == 'F' && (code[1] == 'X' || ISNUMERIC(1)) && ISNUMERIC(2) && ISNUMERIC(3)) #undef ISNUMERIC { PLUGINDEX plug = (code[2] - '0') * 10 + (code[3] - '0'); //calculate plug-in number. if(code[1] != 'X') plug += (code[1] - '0') * 100; if(plug < MAX_MIXPLUGINS) { ReadMixPluginChunk(chunk, m_MixPlugins[plug]); } #endif // NO_PLUGINS } else if(!memcmp(code, "MODU", 4)) { m_madeWithTracker = MPT_USTRING("BeRoTracker"); m_dwLastSavedWithVersion = 0; // Reset MPT detection for old files that have a similar fingerprint } } } #ifndef NO_PLUGINS void CSoundFile::ReadMixPluginChunk(FileReader &file, SNDMIXPLUGIN &plugin) { // MPT's standard plugin data. Size not specified in file.. grrr.. file.ReadStruct(plugin.Info); mpt::String::SetNullTerminator(plugin.Info.szName); mpt::String::SetNullTerminator(plugin.Info.szLibraryName); plugin.editorX = plugin.editorY = int32_min; // Plugin user data const uint32 pluginDataChunkSize = file.ReadUint32LE(); FileReader pluginDataChunk = file.ReadChunk(pluginDataChunkSize); if(pluginDataChunk.IsValid()) { plugin.pluginData.resize(pluginDataChunkSize); pluginDataChunk.ReadRaw(plugin.pluginData.data(), pluginDataChunkSize); } FileReader modularData = file.ReadChunk(file.ReadUint32LE()); //if dwMPTExtra is positive and there are dwMPTExtra bytes left in nPluginSize, we have some more data! if(modularData.IsValid()) { while(modularData.CanRead(5)) { // do we recognize this chunk? char code[4]; modularData.ReadArray(code); uint32 dataSize = 0; if(!memcmp(code, "DWRT", 4) || !memcmp(code, "PROG", 4)) { // Legacy system with fixed size chunks dataSize = 4; } else { dataSize = modularData.ReadUint32LE(); } FileReader dataChunk = modularData.ReadChunk(dataSize); if(!memcmp(code, "DWRT", 4)) { plugin.fDryRatio = dataChunk.ReadFloatLE(); } else if(!memcmp(code, "PROG", 4)) { plugin.defaultProgram = dataChunk.ReadUint32LE(); } else if(!memcmp(code, "MCRO", 4)) { // Read plugin-specific macros //dataChunk.ReadStructPartial(plugin.macros, dataChunk.GetLength()); } } } } #endif // NO_PLUGINS #ifndef MODPLUG_NO_FILESAVE void CSoundFile::SaveExtendedSongProperties(FILE* f) const { const CModSpecifications &specs = GetModSpecifications(); // Extra song data - Yet Another Hack. mpt::IO::WriteIntLE(f, MAGIC4BE('M','P','T','S')); #define WRITEMODULARHEADER(code, fsize) \ { \ mpt::IO::WriteIntLE(f, code); \ MPT_ASSERT(Util::TypeCanHoldValue(fsize)); \ const uint16 _size = fsize; \ mpt::IO::WriteIntLE(f, _size); \ } #define WRITEMODULAR(code, field) \ { \ WRITEMODULARHEADER(code, sizeof(field)) \ mpt::IO::WriteIntLE(f, field); \ } if(m_nDefaultTempo.GetInt() > 255) { uint32 tempo = m_nDefaultTempo.GetInt(); WRITEMODULAR(MAGIC4BE('D','T','.','.'), tempo); } if(m_nDefaultTempo.GetFract() != 0 && specs.hasFractionalTempo) { uint32 tempo = m_nDefaultTempo.GetFract(); WRITEMODULAR(MAGIC4LE('D','T','F','R'), tempo); } WRITEMODULAR(MAGIC4BE('R','P','B','.'), m_nDefaultRowsPerBeat); WRITEMODULAR(MAGIC4BE('R','P','M','.'), m_nDefaultRowsPerMeasure); if(GetType() != MOD_TYPE_XM) { WRITEMODULAR(MAGIC4BE('C','.','.','.'), m_nChannels); } if((GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) && GetNumChannels() > 64) { // IT header has only room for 64 channels. Save the settings that do not fit to the header here as an extension. WRITEMODULARHEADER(MAGIC4BE('C','h','n','S'), (GetNumChannels() - 64) * 2); for(CHANNELINDEX chn = 64; chn < GetNumChannels(); chn++) { uint8 panvol[2]; panvol[0] = (uint8)(ChnSettings[chn].nPan >> 2); if (ChnSettings[chn].dwFlags[CHN_SURROUND]) panvol[0] = 100; if (ChnSettings[chn].dwFlags[CHN_MUTE]) panvol[0] |= 0x80; panvol[1] = (uint8)ChnSettings[chn].nVolume; mpt::IO::Write(f, panvol); } } { WRITEMODULARHEADER(MAGIC4BE('T','M','.','.'), 1); uint8 mode = static_cast(m_nTempoMode); mpt::IO::WriteIntLE(f, mode); } const int32 tmpMixLevels = static_cast(m_nMixLevels); WRITEMODULAR(MAGIC4BE('P','M','M','.'), tmpMixLevels); if(m_dwCreatedWithVersion) { WRITEMODULAR(MAGIC4BE('C','W','V','.'), m_dwCreatedWithVersion); } WRITEMODULAR(MAGIC4BE('L','S','W','V'), MptVersion::num); WRITEMODULAR(MAGIC4BE('S','P','A','.'), m_nSamplePreAmp); WRITEMODULAR(MAGIC4BE('V','S','T','V'), m_nVSTiVolume); if(GetType() == MOD_TYPE_XM && m_nDefaultGlobalVolume != MAX_GLOBAL_VOLUME) { WRITEMODULAR(MAGIC4BE('D','G','V','.'), m_nDefaultGlobalVolume); } if(GetType() != MOD_TYPE_XM && Order().GetRestartPos() != 0) { WRITEMODULAR(MAGIC4BE('R','P','.','.'), Order().GetRestartPos()); } if(m_nResampling != SRCMODE_DEFAULT && specs.hasDefaultResampling) { WRITEMODULAR(MAGIC4LE('R','S','M','P'), static_cast(m_nResampling)); } // Sample cues if(GetType() == MOD_TYPE_MPT) { for(SAMPLEINDEX smp = 1; smp <= GetNumSamples(); smp++) { const ModSample &sample = Samples[smp]; if(sample.nLength && sample.HasCustomCuePoints()) { // Write one chunk for every sample. // Rationale: chunks are limited to 65536 bytes, which can easily be reached // with the amount of samples that OpenMPT supports. WRITEMODULARHEADER(MAGIC4LE('C','U','E','S'), 2 + CountOf(sample.cues) * 4); mpt::IO::WriteIntLE(f, smp); for(std::size_t i = 0; i < CountOf(sample.cues); i++) { mpt::IO::WriteIntLE(f, sample.cues[i]); } } } } // Tempo Swing Factors if(!m_tempoSwing.empty()) { mpt::ostringstream oStrm; TempoSwing::Serialize(oStrm, m_tempoSwing); std::string data = oStrm.str(); uint16 length = mpt::saturate_cast(data.size()); WRITEMODULARHEADER(MAGIC4LE('S','W','N','G'), length); mpt::IO::WriteRaw(f, data.data(), length); } // Playback compatibility flags { uint8 bits[(kMaxPlayBehaviours + 7) / 8u]; MemsetZero(bits); size_t maxBit = 0; for(size_t i = 0; i < kMaxPlayBehaviours; i++) { if(m_playBehaviour[i]) { bits[i >> 3] |= 1 << (i & 0x07); maxBit = i + 8; } } uint16 numBytes = static_cast(maxBit / 8u); WRITEMODULARHEADER(MAGIC4BE('M','S','F','.'), numBytes); mpt::IO::WriteRaw(f, bits, numBytes); } if(!m_songArtist.empty() && specs.hasArtistName) { std::string songArtistU8 = mpt::ToCharset(mpt::CharsetUTF8, m_songArtist); uint16 length = mpt::saturate_cast(songArtistU8.length()); WRITEMODULARHEADER(MAGIC4LE('A','U','T','H'), length); mpt::IO::WriteRaw(f, songArtistU8.c_str(), length); } #ifdef MODPLUG_TRACKER // MIDI mapping directives if(GetMIDIMapper().GetCount() > 0) { const size_t objectsize = GetMIDIMapper().Serialize(); if(!Util::TypeCanHoldValue(objectsize)) { AddToLog("Too many MIDI Mapping directives to save; data won't be written."); } else { WRITEMODULARHEADER(MAGIC4BE('M','I','M','A'), static_cast(objectsize)); GetMIDIMapper().Serialize(f); } } #endif #undef WRITEMODULAR #undef WRITEMODULARHEADER return; } #endif // MODPLUG_NO_FILESAVE template void ReadField(FileReader &chunk, std::size_t size, T &field) { field = chunk.ReadSizedIntLE(size); } template void ReadFieldCast(FileReader &chunk, std::size_t size, T &field) { STATIC_ASSERT(sizeof(T) <= sizeof(int32)); field = static_cast(chunk.ReadSizedIntLE(size)); } void CSoundFile::LoadExtendedSongProperties(FileReader &file, bool *pInterpretMptMade) { if(!file.ReadMagic("STPM")) // 'MPTS' { return; } // Found MPTS, interpret the file MPT made. if(pInterpretMptMade != nullptr) *pInterpretMptMade = true; // HACK: Reset mod flags to default values here, as they are not always written. m_playBehaviour.reset(); while(file.CanRead(7)) { const uint32 code = file.ReadUint32LE(); const uint16 size = file.ReadUint16LE(); // Start of MPTM extensions, non-ASCII ID or truncated field if(code == MAGIC4LE('2','2','8',4)) { file.SkipBack(6); break; } else if((code & 0x80808080) || !(code & 0x60606060) || !file.CanRead(size)) { break; } FileReader chunk = file.ReadChunk(size); switch (code) // interpret field code { case MAGIC4BE('D','T','.','.'): { uint32 tempo; ReadField(chunk, size, tempo); m_nDefaultTempo.Set(tempo, m_nDefaultTempo.GetFract()); break; } case MAGIC4LE('D','T','F','R'): { uint32 tempoFract; ReadField(chunk, size, tempoFract); m_nDefaultTempo.Set(m_nDefaultTempo.GetInt(), tempoFract); break; } case MAGIC4BE('R','P','B','.'): ReadField(chunk, size, m_nDefaultRowsPerBeat); break; case MAGIC4BE('R','P','M','.'): ReadField(chunk, size, m_nDefaultRowsPerMeasure); break; // FIXME: If there are only PC events on the last few channels in an MPTM MO3, they won't be imported! case MAGIC4BE('C','.','.','.'): if(GetType() != MOD_TYPE_XM && m_ContainerType != MOD_CONTAINERTYPE_MO3) { CHANNELINDEX chn = 0; ReadField(chunk, size, chn); m_nChannels = Clamp(chn, m_nChannels, MAX_BASECHANNELS); } break; case MAGIC4BE('T','M','.','.'): ReadFieldCast(chunk, size, m_nTempoMode); break; case MAGIC4BE('P','M','M','.'): ReadFieldCast(chunk, size, m_nMixLevels); break; case MAGIC4BE('C','W','V','.'): ReadField(chunk, size, m_dwCreatedWithVersion); break; case MAGIC4BE('L','S','W','V'): { uint32 ver; ReadField(chunk, size, ver); if(ver != 0) { m_dwLastSavedWithVersion = ver; } break; } case MAGIC4BE('S','P','A','.'): ReadField(chunk, size, m_nSamplePreAmp); break; case MAGIC4BE('V','S','T','V'): ReadField(chunk, size, m_nVSTiVolume); break; case MAGIC4BE('D','G','V','.'): ReadField(chunk, size, m_nDefaultGlobalVolume); break; case MAGIC4BE('R','P','.','.'): if(GetType() != MOD_TYPE_XM) { ORDERINDEX restartPos; ReadField(chunk, size, restartPos); Order().SetRestartPos(restartPos); } break; case MAGIC4LE('R','S','M','P'): ReadFieldCast(chunk, size, m_nResampling); if(!IsKnownResamplingMode(m_nResampling)) m_nResampling = SRCMODE_DEFAULT; break; #ifdef MODPLUG_TRACKER case MAGIC4BE('M','I','M','A'): GetMIDIMapper().Deserialize(chunk); break; #endif case MAGIC4LE('A','U','T','H'): { std::string artist; chunk.ReadString(artist, chunk.GetLength()); m_songArtist = mpt::ToUnicode(mpt::CharsetUTF8, artist); } break; case MAGIC4BE('C','h','n','S'): // Channel settings for channels 65+ if(size <= (MAX_BASECHANNELS - 64) * 2 && (size % 2u) == 0) { STATIC_ASSERT(CountOf(ChnSettings) >= 64); const CHANNELINDEX loopLimit = std::min(uint16(64 + size / 2), uint16(CountOf(ChnSettings))); for(CHANNELINDEX chn = 64; chn < loopLimit; chn++) { uint8 pan = chunk.ReadUint8(), vol = chunk.ReadUint8(); if(pan != 0xFF) { ChnSettings[chn].nVolume = vol; ChnSettings[chn].nPan = 128; ChnSettings[chn].dwFlags.reset(); if(pan & 0x80) ChnSettings[chn].dwFlags.set(CHN_MUTE); pan &= 0x7F; if(pan <= 64) ChnSettings[chn].nPan = pan << 2; if(pan == 100) ChnSettings[chn].dwFlags.set(CHN_SURROUND); } } } break; case MAGIC4LE('C','U','E','S'): // Sample cues if(size > 2) { SAMPLEINDEX smp = chunk.ReadUint16LE(); if(smp > 0 && smp <= GetNumSamples()) { ModSample &sample = Samples[smp]; for(std::size_t i = 0; i < CountOf(sample.cues); i++) { sample.cues[i] = chunk.ReadUint32LE(); } } } break; case MAGIC4LE('S','W','N','G'): // Tempo Swing Factors if(size > 2) { mpt::istringstream iStrm(chunk.ReadRawDataAsString()); TempoSwing::Deserialize(iStrm, m_tempoSwing, chunk.GetLength()); } break; case MAGIC4BE('M','S','F','.'): // Playback compatibility flags { size_t bit = 0; m_playBehaviour.reset(); while(chunk.CanRead(1) && bit < m_playBehaviour.size()) { uint8 b = chunk.ReadUint8(); for(uint8 i = 0; i < 8; i++, bit++) { if((b & (1 << i)) && bit < m_playBehaviour.size()) { m_playBehaviour.set(bit); } } } } break; } } // Validate read values. Limit(m_nDefaultTempo, GetModSpecifications().GetTempoMin(), GetModSpecifications().GetTempoMax()); if(m_nDefaultRowsPerMeasure < m_nDefaultRowsPerBeat) m_nDefaultRowsPerMeasure = m_nDefaultRowsPerBeat; if(m_nTempoMode >= tempoModeMax) m_nTempoMode = tempoModeClassic; if(m_nMixLevels >= mixLevelsMax) m_nMixLevels = mixLevelsOriginal; //m_dwCreatedWithVersion //m_dwLastSavedWithVersion //m_nSamplePreAmp //m_nVSTiVolume //m_nDefaultGlobalVolume LimitMax(m_nDefaultGlobalVolume, MAX_GLOBAL_VOLUME); //m_nRestartPos //m_ModFlags if(!m_tempoSwing.empty()) m_tempoSwing.resize(m_nDefaultRowsPerBeat); } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/S3MTools.h0000644000372100037210000000771512752113043017701 00000000000000/* * S3MTools.h * ---------- * Purpose: Definition of S3M file structures and helper functions * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "../soundlib/ModSample.h" #include "../soundlib/SampleIO.h" OPENMPT_NAMESPACE_BEGIN // S3M File Header struct S3MFileHeader { // Magic Bytes enum S3MMagic { idEOF = 0x1A, idS3MType = 0x10, idPanning = 0xFC, }; // Tracker Versions in the cwtv field enum S3MTrackerVersions { trackerMask = 0xF000, versionMask = 0x0FFF, trkScreamTracker = 0x1000, trkImagoOrpheus = 0x2000, trkImpulseTracker = 0x3000, trkSchismTracker = 0x4000, trkOpenMPT = 0x5000, trkBeRoTracker = 0x6000, trkCreamTracker = 0x7000, trkST3_20 = 0x1320, trkIT2_14 = 0x3214, trkBeRoTrackerOld = 0x4100, // Used from 2004 to 2012 }; // Flags enum S3MHeaderFlags { st2Vibrato = 0x01, // Vibrato is twice as deep. Cannot be enabled from UI. zeroVolOptim = 0x08, // Volume 0 optimisations amigaLimits = 0x10, // Enforce Amiga limits fastVolumeSlides = 0x40, // Fast volume slides (like in ST3.00) }; // S3M Format Versions enum S3MFormatVersion { oldVersion = 0x01, // Old Version, signed samples newVersion = 0x02, // New Version, unsigned samples }; char name[28]; // Song Title uint8le dosEof; // Supposed to be 0x1A, but even ST3 seems to ignore this sometimes (see STRSHINE.S3M by Purple Motion) uint8le fileType; // File Type, 0x10 = ST3 module char reserved1[2]; // Reserved uint16le ordNum; // Number of order items uint16le smpNum; // Number of sample parapointers uint16le patNum; // Number of pattern parapointers uint16le flags; // Flags, see S3MHeaderFlags uint16le cwtv; // "Made With" Tracker ID, see S3MTrackerVersions uint16le formatVersion; // Format Version, see S3MFormatVersion char magic[4]; // "SCRM" magic bytes uint8le globalVol; // Default Global Volume (0...64) uint8le speed; // Default Speed (1...254) uint8le tempo; // Default Tempo (33...255) uint8le masterVolume; // Sample Volume (0...127, stereo if high bit is set) uint8le ultraClicks; // Number of channels used for ultra click removal uint8le usePanningTable; // 0xFC => read extended panning table char reserved2[8]; // More reserved bytes uint16le special; // Pointer to special custom data (unused) uint8le channels[32]; // Channel setup }; MPT_BINARY_STRUCT(S3MFileHeader, 96) // S3M Sample Header struct S3MSampleHeader { enum SampleType { typeNone = 0, typePCM = 1, typeAdMel = 2, }; enum SampleFlags { smpLoop = 0x01, smpStereo = 0x02, smp16Bit = 0x04, }; enum SamplePacking { pUnpacked = 0x00, // PCM pDP30ADPCM = 0x01, // Unused packing type pADPCM = 0x04, // MODPlugin ADPCM :( }; uint8le sampleType; // Sample type, see SampleType char filename[12]; // Sample filename uint8le dataPointer[3]; // Pointer to sample data (divided by 16) uint32le length; // Sample length, in samples uint32le loopStart; // Loop start, in samples uint32le loopEnd; // Loop end, in samples uint8le defaultVolume; // Default volume (0...64) char reserved1; // Reserved uint8le pack; // Packing algorithm, SamplePacking uint8le flags; // Sample flags uint32le c5speed; // Middle-C frequency char reserved2[12]; // Reserved + Internal ST3 stuff char name[28]; // Sample name char magic[4]; // "SCRS" magic bytes ("SCRI" for Adlib instruments) // Convert an S3M sample header to OpenMPT's internal sample header. void ConvertToMPT(ModSample &mptSmp) const; // Convert OpenMPT's internal sample header to an S3M sample header. SmpLength ConvertToS3M(const ModSample &mptSmp); // Retrieve the internal sample format flags for this sample. SampleIO GetSampleFormat(bool signedSamples) const; }; MPT_BINARY_STRUCT(S3MSampleHeader, 80) OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/ModSampleCopy.h0000644000372100037210000001276513161656666021015 00000000000000/* * ModSampleCopy.h * --------------- * Purpose: Functions for copying ModSample data. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "../soundbase/SampleFormatCopy.h" OPENMPT_NAMESPACE_BEGIN struct ModSample; // Copy a mono sample data buffer. template size_t CopyMonoSample(ModSample &sample, const Tbyte *sourceBuffer, size_t sourceSize, SampleConversion conv = SampleConversion()) { MPT_ASSERT(sample.GetNumChannels() == 1); MPT_ASSERT(sample.GetElementarySampleSize() == sizeof(typename SampleConversion::output_t)); const size_t frameSize = SampleConversion::input_inc; const size_t countFrames = std::min(sourceSize / frameSize, sample.nLength); size_t numFrames = countFrames; SampleConversion sampleConv(conv); const mpt::byte * MPT_RESTRICT inBuf = mpt::byte_cast(sourceBuffer); typename SampleConversion::output_t * MPT_RESTRICT outBuf = static_cast(sample.pSample); while(numFrames--) { *outBuf = sampleConv(inBuf); inBuf += SampleConversion::input_inc; outBuf++; } return frameSize * countFrames; } // Copy a stereo interleaved sample data buffer. template size_t CopyStereoInterleavedSample(ModSample &sample, const Tbyte *sourceBuffer, size_t sourceSize, SampleConversion conv = SampleConversion()) { MPT_ASSERT(sample.GetNumChannels() == 2); MPT_ASSERT(sample.GetElementarySampleSize() == sizeof(typename SampleConversion::output_t)); const size_t frameSize = 2 * SampleConversion::input_inc; const size_t countFrames = std::min(sourceSize / frameSize, sample.nLength); size_t numFrames = countFrames; SampleConversion sampleConvLeft(conv); SampleConversion sampleConvRight(conv); const mpt::byte * MPT_RESTRICT inBuf = mpt::byte_cast(sourceBuffer); typename SampleConversion::output_t * MPT_RESTRICT outBuf = static_cast(sample.pSample); while(numFrames--) { *outBuf = sampleConvLeft(inBuf); inBuf += SampleConversion::input_inc; outBuf++; *outBuf = sampleConvRight(inBuf); inBuf += SampleConversion::input_inc; outBuf++; } return frameSize * countFrames; } // Copy a stereo split sample data buffer. template size_t CopyStereoSplitSample(ModSample &sample, const Tbyte *sourceBuffer, size_t sourceSize, SampleConversion conv = SampleConversion()) { MPT_ASSERT(sample.GetNumChannels() == 2); MPT_ASSERT(sample.GetElementarySampleSize() == sizeof(typename SampleConversion::output_t)); const size_t sampleSize = SampleConversion::input_inc; const size_t sourceSizeLeft = std::min(sample.nLength * SampleConversion::input_inc, sourceSize); const size_t sourceSizeRight = std::min(sample.nLength * SampleConversion::input_inc, sourceSize - sourceSizeLeft); const size_t countSamplesLeft = sourceSizeLeft / sampleSize; const size_t countSamplesRight = sourceSizeRight / sampleSize; size_t numSamplesLeft = countSamplesLeft; SampleConversion sampleConvLeft(conv); const mpt::byte * MPT_RESTRICT inBufLeft = mpt::byte_cast(sourceBuffer); typename SampleConversion::output_t * MPT_RESTRICT outBufLeft = static_cast(sample.pSample); while(numSamplesLeft--) { *outBufLeft = sampleConvLeft(inBufLeft); inBufLeft += SampleConversion::input_inc; outBufLeft += 2; } size_t numSamplesRight = countSamplesRight; SampleConversion sampleConvRight(conv); const mpt::byte * MPT_RESTRICT inBufRight = mpt::byte_cast(sourceBuffer) + sample.nLength * SampleConversion::input_inc; typename SampleConversion::output_t * MPT_RESTRICT outBufRight = static_cast(sample.pSample) + 1; while(numSamplesRight--) { *outBufRight = sampleConvRight(inBufRight); inBufRight += SampleConversion::input_inc; outBufRight += 2; } return (countSamplesLeft + countSamplesRight) * sampleSize; } // Copy a sample data buffer and normalize it. Requires slightly advanced sample conversion functor. template size_t CopyAndNormalizeSample(ModSample &sample, const Tbyte *sourceBuffer, size_t sourceSize, typename SampleConversion::peak_t *srcPeak = nullptr, SampleConversion conv = SampleConversion()) { const size_t inSize = sizeof(typename SampleConversion::input_t); MPT_ASSERT(sample.GetElementarySampleSize() == sizeof(typename SampleConversion::output_t)); size_t numSamples = sample.nLength * sample.GetNumChannels(); LimitMax(numSamples, sourceSize / inSize); const mpt::byte * inBuf = mpt::byte_cast(sourceBuffer); // Finding max value SampleConversion sampleConv(conv); for(size_t i = numSamples; i != 0; i--) { sampleConv.FindMax(inBuf); inBuf += SampleConversion::input_inc; } // If buffer is silent (maximum is 0), don't bother normalizing the sample - just keep the already silent buffer. if(!sampleConv.IsSilent()) { inBuf = sourceBuffer; // Copying buffer. typename SampleConversion::output_t *outBuf = static_cast(sample.pSample); for(size_t i = numSamples; i != 0; i--) { *outBuf = sampleConv(inBuf); outBuf++; inBuf += SampleConversion::input_inc; } } if(srcPeak) { *srcPeak = sampleConv.GetSrcPeak(); } return numSamples * inSize; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/ITTools.cpp0000644000372100037210000004656613215224652020161 00000000000000/* * ITTools.cpp * ----------- * Purpose: Definition of IT file structures and helper functions * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" #include "ITTools.h" #include "Tables.h" #include "../common/StringFixer.h" #include "../common/version.h" OPENMPT_NAMESPACE_BEGIN // Convert OpenMPT's internal envelope format into an IT/MPTM envelope. void ITEnvelope::ConvertToIT(const InstrumentEnvelope &mptEnv, uint8 envOffset, uint8 envDefault) { // Envelope Flags if(mptEnv.dwFlags[ENV_ENABLED]) flags |= ITEnvelope::envEnabled; if(mptEnv.dwFlags[ENV_LOOP]) flags |= ITEnvelope::envLoop; if(mptEnv.dwFlags[ENV_SUSTAIN]) flags |= ITEnvelope::envSustain; if(mptEnv.dwFlags[ENV_CARRY]) flags |= ITEnvelope::envCarry; // Nodes and Loops num = (uint8)std::min(mptEnv.size(), uint32(25)); lpb = (uint8)mptEnv.nLoopStart; lpe = (uint8)mptEnv.nLoopEnd; slb = (uint8)mptEnv.nSustainStart; sle = (uint8)mptEnv.nSustainEnd; // Envelope Data MemsetZero(data); if(!mptEnv.empty()) { // Attention: Full MPTM envelope is stored in extended instrument properties for(uint32 ev = 0; ev < num; ev++) { data[ev].value = static_cast(mptEnv[ev].value) - envOffset; data[ev].tick = mptEnv[ev].tick; } } else { // Fix non-existing envelopes so that they can still be edited in Impulse Tracker. num = 2; data[0].value = data[1].value = envDefault - envOffset; data[1].tick = 10; } } // Convert IT/MPTM envelope data into OpenMPT's internal envelope format - To be used by ITInstrToMPT() void ITEnvelope::ConvertToMPT(InstrumentEnvelope &mptEnv, uint8 envOffset, uint8 maxNodes) const { // Envelope Flags mptEnv.dwFlags.set(ENV_ENABLED, (flags & ITEnvelope::envEnabled) != 0); mptEnv.dwFlags.set(ENV_LOOP, (flags & ITEnvelope::envLoop) != 0); mptEnv.dwFlags.set(ENV_SUSTAIN, (flags & ITEnvelope::envSustain) != 0); mptEnv.dwFlags.set(ENV_CARRY, (flags & ITEnvelope::envCarry) != 0); // Nodes and Loops mptEnv.resize(std::min(num, maxNodes)); mptEnv.nLoopStart = std::min(lpb, maxNodes); mptEnv.nLoopEnd = Clamp(lpe, mptEnv.nLoopStart, maxNodes); mptEnv.nSustainStart = std::min(slb, maxNodes); mptEnv.nSustainEnd = Clamp(sle, mptEnv.nSustainStart, maxNodes); // Envelope Data // Attention: Full MPTM envelope is stored in extended instrument properties for(uint32 ev = 0; ev < std::min(25, num); ev++) { mptEnv[ev].value = Clamp(data[ev].value + envOffset, 0, 64); mptEnv[ev].tick = data[ev].tick; if(ev > 0 && ev < num && mptEnv[ev].tick < mptEnv[ev - 1].tick) { // Fix broken envelopes... Instruments 2 and 3 in NoGap.it by Werewolf have envelope points where the high byte of envelope nodes is missing. // NoGap.it was saved with MPT 1.07 or MPT 1.09, which *normally* doesn't do this in IT files. // However... It turns out that MPT 1.07 omitted the high byte of envelope nodes when saving an XI instrument file, and it looks like // Instrument 2 and 3 in NoGap.it were loaded from XI files. mptEnv[ev].tick &= 0xFF; mptEnv[ev].tick |= (mptEnv[ev].tick & ~0xFF); if(mptEnv[ev].tick < mptEnv[ev - 1].tick) { mptEnv[ev].tick += 0x100; } } } } // Convert an ITOldInstrument to OpenMPT's internal instrument representation. void ITOldInstrument::ConvertToMPT(ModInstrument &mptIns) const { // Header if(memcmp(id, "IMPI", 4)) { return; } mpt::String::Read(mptIns.name, name); mpt::String::Read(mptIns.filename, filename); // Volume / Panning mptIns.nFadeOut = fadeout << 6; mptIns.nGlobalVol = 64; mptIns.nPan = 128; // NNA Stuff mptIns.nNNA = nna; mptIns.nDCT = dnc; // Sample Map for(size_t i = 0; i < 120; i++) { uint8 note = keyboard[i * 2]; SAMPLEINDEX ins = keyboard[i * 2 + 1]; if(ins < MAX_SAMPLES) { mptIns.Keyboard[i] = ins; } if(note < 120) { mptIns.NoteMap[i] = note + 1u; } else { mptIns.NoteMap[i] = static_cast(i + 1); } } // Volume Envelope Flags mptIns.VolEnv.dwFlags.set(ENV_ENABLED, (flags & ITOldInstrument::envEnabled) != 0); mptIns.VolEnv.dwFlags.set(ENV_LOOP, (flags & ITOldInstrument::envLoop) != 0); mptIns.VolEnv.dwFlags.set(ENV_SUSTAIN, (flags & ITOldInstrument::envSustain) != 0); // Volume Envelope Loops mptIns.VolEnv.nLoopStart = vls; mptIns.VolEnv.nLoopEnd = vle; mptIns.VolEnv.nSustainStart = sls; mptIns.VolEnv.nSustainEnd = sle; mptIns.VolEnv.resize(25); // Volume Envelope Data for(uint32 i = 0; i < 25; i++) { if((mptIns.VolEnv[i].tick = nodes[i * 2]) == 0xFF) { mptIns.VolEnv.resize(i); break; } mptIns.VolEnv[i].value = nodes[i * 2 + 1]; } if(std::max(mptIns.VolEnv.nLoopStart, mptIns.VolEnv.nLoopEnd) >= mptIns.VolEnv.size()) mptIns.VolEnv.dwFlags.reset(ENV_LOOP); if(std::max(mptIns.VolEnv.nSustainStart, mptIns.VolEnv.nSustainEnd) >= mptIns.VolEnv.size()) mptIns.VolEnv.dwFlags.reset(ENV_SUSTAIN); } // Convert OpenMPT's internal instrument representation to an ITInstrument. uint32 ITInstrument::ConvertToIT(const ModInstrument &mptIns, bool compatExport, const CSoundFile &sndFile) { MemsetZero(*this); // Header memcpy(id, "IMPI", 4); trkvers = 0x5000 | static_cast(MptVersion::num >> 16); mpt::String::Write(filename, mptIns.filename); mpt::String::Write(name, mptIns.name); // Volume / Panning fadeout = static_cast(std::min(mptIns.nFadeOut >> 5, 256u)); gbv = static_cast(std::min(mptIns.nGlobalVol * 2u, 128u)); dfp = static_cast(std::min(mptIns.nPan / 4u, 64u)); if(!mptIns.dwFlags[INS_SETPANNING]) dfp |= ITInstrument::ignorePanning; // Random Variation rv = std::min(mptIns.nVolSwing, uint8(100)); rp = std::min(mptIns.nPanSwing, uint8(64)); // NNA Stuff nna = mptIns.nNNA; dct = (mptIns.nDCT < DCT_PLUGIN || !compatExport) ? mptIns.nDCT : DCT_NONE; dca = mptIns.nDNA; // Pitch / Pan Separation pps = mptIns.nPPS; ppc = mptIns.nPPC; // Filter Stuff ifc = mptIns.GetCutoff() | (mptIns.IsCutoffEnabled() ? ITInstrument::enableCutoff : 0x00); ifr = mptIns.GetResonance() | (mptIns.IsResonanceEnabled() ? ITInstrument::enableResonance : 0x00); // MIDI Setup if(mptIns.nMidiProgram > 0) mpr = mptIns.nMidiProgram - 1u; else mpr = 0xFF; if(mptIns.wMidiBank > 0) { mbank[0] = static_cast((mptIns.wMidiBank - 1) & 0x7F); mbank[1] = static_cast((mptIns.wMidiBank - 1) >> 7); } else { mbank[0] = 0xFF; mbank[1] = 0xFF; } if(mptIns.nMidiChannel != MidiNoChannel || mptIns.nMixPlug == 0 || mptIns.nMixPlug > 127 || compatExport) { // Default. Prefer MIDI channel over mixplug to keep the semantics intact. mch = mptIns.nMidiChannel; } else { // Keep compatibility with MPT 1.16's instrument format if possible, as XMPlay / BASS also uses this. mch = mptIns.nMixPlug + 128; } // Sample Map nos = 0; // Only really relevant for ITI files std::vector smpCount(sndFile.GetNumSamples(), false); for(int i = 0; i < 120; i++) { keyboard[i * 2] = (mptIns.NoteMap[i] >= NOTE_MIN && mptIns.NoteMap[i] <= NOTE_MAX) ? (mptIns.NoteMap[i] - NOTE_MIN) : static_cast(i); const SAMPLEINDEX smp = mptIns.Keyboard[i]; if(smp < MAX_SAMPLES && smp < 256) { keyboard[i * 2 + 1] = static_cast(smp); if(smp && smp <= sndFile.GetNumSamples() && !smpCount[smp - 1]) { // We haven't considered this sample yet. Update number of samples. smpCount[smp - 1] = true; nos++; } } } // Writing Volume envelope volenv.ConvertToIT(mptIns.VolEnv, 0, 64); // Writing Panning envelope panenv.ConvertToIT(mptIns.PanEnv, 32, 32); // Writing Pitch Envelope pitchenv.ConvertToIT(mptIns.PitchEnv, 32, 32); if(mptIns.PitchEnv.dwFlags[ENV_FILTER]) pitchenv.flags |= ITEnvelope::envFilter; return sizeof(ITInstrument); } // Convert an ITInstrument to OpenMPT's internal instrument representation. Returns size of the instrument data that has been read. uint32 ITInstrument::ConvertToMPT(ModInstrument &mptIns, MODTYPE modFormat) const { if(memcmp(id, "IMPI", 4)) { return 0; } mpt::String::Read(mptIns.name, name); mpt::String::Read(mptIns.filename, filename); // Volume / Panning mptIns.nFadeOut = fadeout << 5; mptIns.nGlobalVol = gbv / 2; LimitMax(mptIns.nGlobalVol, 64u); mptIns.nPan = (dfp & 0x7F) * 4; if(mptIns.nPan > 256) mptIns.nPan = 128; mptIns.dwFlags.set(INS_SETPANNING, !(dfp & ITInstrument::ignorePanning)); // Random Variation mptIns.nVolSwing = std::min(rv, 100); mptIns.nPanSwing = std::min(rp, 64); // NNA Stuff mptIns.nNNA = nna; mptIns.nDCT = dct; mptIns.nDNA = dca; // Pitch / Pan Separation mptIns.nPPS = pps; mptIns.nPPC = ppc; // Filter Stuff mptIns.SetCutoff(ifc & 0x7F, (ifc & ITInstrument::enableCutoff) != 0); mptIns.SetResonance(ifr & 0x7F, (ifr & ITInstrument::enableResonance) != 0); // MIDI Setup // MPT used to have a slightly different encoding of MIDI program and banks which we are trying to fix here. // Impulse Tracker / Schism Tracker will set trkvers to 0 in IT files, // and we won't care about correctly importing MIDI programs and banks in ITI files. // Chibi Tracker sets trkvers to 0x214, but always writes mpr=mbank=0 anyway. // Old BeRoTracker versions set trkvers to 0x214 or 0x217. // <= MPT 1.07 <= MPT 1.16 OpenMPT 1.17-? <= OpenMPT 1.26 definitely not MPT if((trkvers == 0x0202 || trkvers == 0x0211 || trkvers == 0x0220 || trkvers == 0x0214) && mpr != 0xFF) { if(mpr <= 128) { mptIns.nMidiProgram = mpr; } uint16 bank = mbank[0] | (mbank[1] << 8); // These versions also ignored the high bank nibble (was only handled correctly in OpenMPT instrument extensions) if(bank <= 128) { mptIns.wMidiBank = bank; } } else { if(mpr < 128) { mptIns.nMidiProgram = mpr + 1; } uint16 bank = 0; if(mbank[0] < 128) bank = mbank[0] + 1; if(mbank[1] < 128) bank += (mbank[1] << 7); mptIns.wMidiBank = bank; } mptIns.nMidiChannel = mch; if(mptIns.nMidiChannel >= 128) { // Handle old format where MIDI channel and Plugin index are stored in the same variable mptIns.nMixPlug = mptIns.nMidiChannel - 128; mptIns.nMidiChannel = 0; } // Envelope point count. Limited to 25 in IT format. const uint8 maxNodes = (modFormat & MOD_TYPE_MPT) ? MAX_ENVPOINTS : 25; // Volume Envelope volenv.ConvertToMPT(mptIns.VolEnv, 0, maxNodes); // Panning Envelope panenv.ConvertToMPT(mptIns.PanEnv, 32, maxNodes); // Pitch Envelope pitchenv.ConvertToMPT(mptIns.PitchEnv, 32, maxNodes); mptIns.PitchEnv.dwFlags.set(ENV_FILTER, (pitchenv.flags & ITEnvelope::envFilter) != 0); // Sample Map for(int i = 0; i < 120; i++) { uint8 note = keyboard[i * 2]; SAMPLEINDEX ins = keyboard[i * 2 + 1]; if(ins < MAX_SAMPLES) { mptIns.Keyboard[i] = ins; } if(note < 120) { mptIns.NoteMap[i] = note + NOTE_MIN; } else { mptIns.NoteMap[i] = static_cast(i + NOTE_MIN); } } return sizeof(ITInstrument); } // Convert OpenMPT's internal instrument representation to an ITInstrumentEx. Returns amount of bytes that need to be written to file. uint32 ITInstrumentEx::ConvertToIT(const ModInstrument &mptIns, bool compatExport, const CSoundFile &sndFile) { uint32 instSize = iti.ConvertToIT(mptIns, compatExport, sndFile); if(compatExport) { return instSize; } // Sample Map bool usedExtension = false; iti.nos = 0; std::vector smpCount(sndFile.GetNumSamples(), false); for(int i = 0; i < 120; i++) { const SAMPLEINDEX smp = mptIns.Keyboard[i]; keyboardhi[i] = 0; if(smp < MAX_SAMPLES) { if(smp >= 256) { // We need to save the upper byte for this sample index. iti.keyboard[i * 2 + 1] = static_cast(smp & 0xFF); keyboardhi[i] = static_cast(smp >> 8); usedExtension = true; } if(smp && smp <= sndFile.GetNumSamples() && !smpCount[smp - 1]) { // We haven't considered this sample yet. Update number of samples. smpCount[smp - 1] = true; iti.nos++; } } } if(usedExtension) { // If we actually had to extend the sample map, update the magic bytes and instrument size. memcpy(iti.dummy, "XTPM", 4); instSize = sizeof(ITInstrumentEx); } return instSize; } // Convert an ITInstrumentEx to OpenMPT's internal instrument representation. Returns size of the instrument data that has been read. uint32 ITInstrumentEx::ConvertToMPT(ModInstrument &mptIns, MODTYPE fromType) const { uint32 insSize = iti.ConvertToMPT(mptIns, fromType); // Is this actually an extended instrument? // Note: OpenMPT 1.20 - 1.22 accidentally wrote "MPTX" here (since revision 1203), while previous versions wrote the reversed version, "XTPM". if(insSize == 0 || (memcmp(iti.dummy, "MPTX", 4) && memcmp(iti.dummy, "XTPM", 4))) { return insSize; } // Olivier's MPT Instrument Extension for(int i = 0; i < 120; i++) { mptIns.Keyboard[i] |= ((SAMPLEINDEX)keyboardhi[i] << 8); } return sizeof(ITInstrumentEx); } // Convert OpenMPT's internal sample representation to an ITSample. void ITSample::ConvertToIT(const ModSample &mptSmp, MODTYPE fromType, bool compress, bool compressIT215, bool allowExternal) { MemsetZero(*this); // Header memcpy(id, "IMPS", 4); mpt::String::Write(filename, mptSmp.filename); //mpt::String::Write(name, m_szNames[nsmp]); // Volume / Panning gvl = static_cast(mptSmp.nGlobalVol); vol = static_cast(mptSmp.nVolume / 4); dfp = static_cast(mptSmp.nPan / 4); if(mptSmp.uFlags[CHN_PANNING]) dfp |= ITSample::enablePanning; // Sample Format / Loop Flags if(mptSmp.nLength && mptSmp.pSample) { flags = ITSample::sampleDataPresent; if(mptSmp.uFlags[CHN_LOOP]) flags |= ITSample::sampleLoop; if(mptSmp.uFlags[CHN_SUSTAINLOOP]) flags |= ITSample::sampleSustain; if(mptSmp.uFlags[CHN_PINGPONGLOOP]) flags |= ITSample::sampleBidiLoop; if(mptSmp.uFlags[CHN_PINGPONGSUSTAIN]) flags |= ITSample::sampleBidiSustain; if(mptSmp.uFlags[CHN_STEREO]) { flags |= ITSample::sampleStereo; } if(mptSmp.uFlags[CHN_16BIT]) { flags |= ITSample::sample16Bit; } cvt = ITSample::cvtSignedSample; if(compress) { flags |= ITSample::sampleCompressed; if(compressIT215) { cvt |= ITSample::cvtDelta; } } } else { flags = 0x00; } // Frequency C5Speed = mptSmp.nC5Speed ? mptSmp.nC5Speed : 8363; // Size and loops length = mpt::saturate_cast(mptSmp.nLength); loopbegin = mpt::saturate_cast(mptSmp.nLoopStart); loopend = mpt::saturate_cast(mptSmp.nLoopEnd); susloopbegin = mpt::saturate_cast(mptSmp.nSustainStart); susloopend = mpt::saturate_cast(mptSmp.nSustainEnd); // Auto Vibrato settings vit = AutoVibratoXM2IT[mptSmp.nVibType & 7]; vis = std::min(mptSmp.nVibRate, uint8(64)); vid = std::min(mptSmp.nVibDepth, uint8(32)); vir = std::min(mptSmp.nVibSweep, uint8(255)); if((vid | vis) != 0 && (fromType & MOD_TYPE_XM)) { // Sweep is upside down in XM vir = 255 - vir; } if(mptSmp.uFlags[SMP_KEEPONDISK]) { #ifndef MPT_EXTERNAL_SAMPLES MPT_UNREFERENCED_PARAMETER(allowExternal); #else // Save external sample (filename at sample pointer) if(allowExternal && mptSmp.HasSampleData()) { cvt = ITSample::cvtExternalSample; } else #endif // MPT_EXTERNAL_SAMPLES { length = loopbegin = loopend = susloopbegin = susloopend = 0; } } } // Convert an ITSample to OpenMPT's internal sample representation. uint32 ITSample::ConvertToMPT(ModSample &mptSmp) const { if(memcmp(id, "IMPS", 4)) { return 0; } mptSmp.Initialize(MOD_TYPE_IT); mpt::String::Read(mptSmp.filename, filename); // Volume / Panning mptSmp.nVolume = vol * 4; LimitMax(mptSmp.nVolume, uint16(256)); mptSmp.nGlobalVol = gvl; LimitMax(mptSmp.nGlobalVol, uint16(64)); mptSmp.nPan = (dfp & 0x7F) * 4; LimitMax(mptSmp.nPan, uint16(256)); if(dfp & ITSample::enablePanning) mptSmp.uFlags.set(CHN_PANNING); // Loop Flags if(flags & ITSample::sampleLoop) mptSmp.uFlags.set(CHN_LOOP); if(flags & ITSample::sampleSustain) mptSmp.uFlags.set(CHN_SUSTAINLOOP); if(flags & ITSample::sampleBidiLoop) mptSmp.uFlags.set(CHN_PINGPONGLOOP); if(flags & ITSample::sampleBidiSustain) mptSmp.uFlags.set(CHN_PINGPONGSUSTAIN); // Frequency mptSmp.nC5Speed = C5Speed; if(!mptSmp.nC5Speed) mptSmp.nC5Speed = 8363; if(mptSmp.nC5Speed < 256) mptSmp.nC5Speed = 256; // Size and loops mptSmp.nLength = length; mptSmp.nLoopStart = loopbegin; mptSmp.nLoopEnd = loopend; mptSmp.nSustainStart = susloopbegin; mptSmp.nSustainEnd = susloopend; mptSmp.SanitizeLoops(); // Auto Vibrato settings mptSmp.nVibType = AutoVibratoIT2XM[vit & 7]; mptSmp.nVibRate = vis; mptSmp.nVibDepth = vid & 0x7F; mptSmp.nVibSweep = vir; if(cvt == ITSample::cvtExternalSample) { // Read external sample (filename at sample pointer) mptSmp.uFlags.set(SMP_KEEPONDISK); } return samplepointer; } // Retrieve the internal sample format flags for this instrument. SampleIO ITSample::GetSampleFormat(uint16 cwtv) const { SampleIO sampleIO( (flags & ITSample::sample16Bit) ? SampleIO::_16bit : SampleIO::_8bit, SampleIO::mono, SampleIO::littleEndian, (cvt & ITSample::cvtSignedSample) ? SampleIO::signedPCM: SampleIO::unsignedPCM); // Some old version of IT didn't clear the stereo flag when importing samples. Luckily, all other trackers are identifying as IT 2.14+, so let's check for old IT versions. if((flags & ITSample::sampleStereo) && cwtv >= 0x214) { sampleIO |= SampleIO::stereoSplit; } if(flags & ITSample::sampleCompressed) { // IT 2.14 packed sample sampleIO |= (cvt & ITSample::cvtDelta) ? SampleIO::IT215 : SampleIO::IT214; } else { // MODPlugin :( if(!(flags & ITSample::sample16Bit) && cvt == ITSample::cvtADPCMSample) { sampleIO |= SampleIO::ADPCM; } else { // ITTECH.TXT says these convert flags are "safe to ignore". IT doesn't ignore them, though, so why should we? :) if(cvt & ITSample::cvtBigEndian) { sampleIO |= SampleIO::bigEndian; } if(cvt & ITSample::cvtDelta) { sampleIO |= SampleIO::deltaPCM; } if((cvt & ITSample::cvtPTM8to16) && (flags & ITSample::sample16Bit)) { sampleIO |= SampleIO::PTM8Dto16; } } } return sampleIO; } // Convert an ITHistoryStruct to OpenMPT's internal edit history representation void ITHistoryStruct::ConvertToMPT(FileHistory &mptHistory) const { // Decode FAT date and time MemsetZero(mptHistory.loadDate); mptHistory.loadDate.tm_year = ((fatdate >> 9) & 0x7F) + 80; mptHistory.loadDate.tm_mon = Clamp((fatdate >> 5) & 0x0F, 1, 12) - 1; mptHistory.loadDate.tm_mday = Clamp(fatdate & 0x1F, 1, 31); mptHistory.loadDate.tm_hour = Clamp((fattime >> 11) & 0x1F, 0, 23); mptHistory.loadDate.tm_min = Clamp((fattime >> 5) & 0x3F, 0, 59); mptHistory.loadDate.tm_sec = Clamp((fattime & 0x1F) * 2, 0, 59); mptHistory.openTime = static_cast(runtime * (HISTORY_TIMER_PRECISION / 18.2f)); } // Convert OpenMPT's internal edit history representation to an ITHistoryStruct void ITHistoryStruct::ConvertToIT(const FileHistory &mptHistory) { // Create FAT file dates fatdate = static_cast(mptHistory.loadDate.tm_mday | ((mptHistory.loadDate.tm_mon + 1) << 5) | ((mptHistory.loadDate.tm_year - 80) << 9)); fattime = static_cast((mptHistory.loadDate.tm_sec / 2) | (mptHistory.loadDate.tm_min << 5) | (mptHistory.loadDate.tm_hour << 11)); runtime = static_cast(mptHistory.openTime * (18.2f / HISTORY_TIMER_PRECISION)); } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Tagging.cpp0000644000372100037210000000137513161656666020207 00000000000000/* * tagging.cpp * ----------- * Purpose: Structure holding a superset of tags for all supported output sample or stream files or types. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Tagging.h" #include "../common/version.h" OPENMPT_NAMESPACE_BEGIN FileTags::FileTags() { encoder = mpt::ToUnicode(mpt::CharsetASCII, MptVersion::GetOpenMPTVersionStr()); } mpt::ustring GetSampleNameFromTags(const FileTags &tags) { mpt::ustring result; if(tags.artist.empty()) { result = tags.title; } else { result = mpt::format(MPT_USTRING("%1 (by %2)"))(tags.title, tags.artist); } return result; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/ModInstrument.cpp0000644000372100037210000001771413161656666021443 00000000000000/* * ModInstrument.cpp * ----------------- * Purpose: Helper functions for Module Instrument handling * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Sndfile.h" #include "ModInstrument.h" OPENMPT_NAMESPACE_BEGIN // Convert envelope data between various formats. void InstrumentEnvelope::Convert(MODTYPE fromType, MODTYPE toType) { if(!(fromType & MOD_TYPE_XM) && (toType & MOD_TYPE_XM)) { // IT / MPTM -> XM: Expand loop by one tick, convert sustain loops to sustain points, remove carry flag. nSustainStart = nSustainEnd; dwFlags.reset(ENV_CARRY); if(nLoopEnd > nLoopStart && dwFlags[ENV_LOOP]) { for(uint32 node = nLoopEnd; node < size(); node++) { at(node).tick++; } } } else if((fromType & MOD_TYPE_XM) && !(toType & MOD_TYPE_XM)) { if(nSustainStart > nLoopEnd && dwFlags[ENV_LOOP]) { // In the IT format, the sustain loop is always considered before the envelope loop. // In the XM format, whichever of the two is encountered first is considered. // So we have to disable the sustain loop if it was behind the normal loop. dwFlags.reset(ENV_SUSTAIN); } // XM -> IT / MPTM: Shorten loop by one tick by inserting bogus point if(nLoopEnd > nLoopStart && dwFlags[ENV_LOOP]) { if(at(nLoopEnd).tick - 1 > at(nLoopEnd - 1).tick) { // Insert an interpolated point just before the loop point. EnvelopeNode::tick_t tick = at(nLoopEnd).tick - 1u; auto interpolatedValue = static_cast(GetValueFromPosition(tick, 64)); insert(begin() + nLoopEnd, EnvelopeNode(tick, interpolatedValue)); } else { // There is already a point before the loop point: Use it as new loop end. nLoopEnd--; } } } } // Get envelope value at a given tick. Assumes that the envelope data is in rage [0, rangeIn], // returns value in range [0, rangeOut]. int32 InstrumentEnvelope::GetValueFromPosition(int position, int32 rangeOut, int32 rangeIn) const { uint32 pt = size() - 1u; const int32 ENV_PRECISION = 1 << 16; // Checking where current 'tick' is relative to the envelope points. for(uint32 i = 0; i < size() - 1u; i++) { if (position <= at(i).tick) { pt = i; break; } } int x2 = at(pt).tick; int32 value = 0; if(position >= x2) { // Case: current 'tick' is on a envelope point. value = at(pt).value * ENV_PRECISION / rangeIn; } else { // Case: current 'tick' is between two envelope points. int x1 = 0; if(pt) { // Get previous node's value and tick. value = at(pt - 1).value * ENV_PRECISION / rangeIn; x1 = at(pt - 1).tick; } if(x2 > x1 && position > x1) { // Linear approximation between the points; // f(x + d) ~ f(x) + f'(x) * d, where f'(x) = (y2 - y1) / (x2 - x1) value += ((position - x1) * (at(pt).value * ENV_PRECISION / rangeIn - value)) / (x2 - x1); } } Limit(value, 0, ENV_PRECISION); return (value * rangeOut + ENV_PRECISION / 2) / ENV_PRECISION; } void InstrumentEnvelope::Sanitize(uint8 maxValue) { if(!empty()) { front().tick = 0; LimitMax(front().value, maxValue); for(iterator it = begin() + 1; it != end(); it++) { it->tick = std::max(it->tick, (it - 1)->tick); LimitMax(it->value, maxValue); } } LimitMax(nLoopEnd, static_cast(size() - 1)); LimitMax(nLoopStart, nLoopEnd); LimitMax(nSustainEnd, static_cast(size() - 1)); LimitMax(nSustainStart, nSustainEnd); if(nReleaseNode != ENV_RELEASE_NODE_UNSET) LimitMax(nReleaseNode, static_cast(size() - 1)); } ModInstrument::ModInstrument(SAMPLEINDEX sample) { nFadeOut = 256; dwFlags.reset(); nGlobalVol = 64; nPan = 32 * 4; nNNA = NNA_NOTECUT; nDCT = DCT_NONE; nDNA = DNA_NOTECUT; nPanSwing = 0; nVolSwing = 0; SetCutoff(0, false); SetResonance(0, false); wMidiBank = 0; nMidiProgram = 0; nMidiChannel = 0; nMidiDrumKey = 0; midiPWD = 2; nPPC = NOTE_MIDDLEC - 1; nPPS = 0; nMixPlug = 0; nVolRampUp = 0; nResampling = SRCMODE_DEFAULT; nCutSwing = 0; nResSwing = 0; nFilterMode = FLTMODE_UNCHANGED; pitchToTempoLock.Set(0); nPluginVelocityHandling = PLUGIN_VELOCITYHANDLING_CHANNEL; nPluginVolumeHandling = PLUGIN_VOLUMEHANDLING_IGNORE; pTuning = CSoundFile::GetDefaultTuning(); AssignSample(sample); ResetNoteMap(); MemsetZero(name); MemsetZero(filename); } // Translate instrument properties between two given formats. void ModInstrument::Convert(MODTYPE fromType, MODTYPE toType) { MPT_UNREFERENCED_PARAMETER(fromType); if(toType & MOD_TYPE_XM) { ResetNoteMap(); PitchEnv.dwFlags.reset(ENV_ENABLED | ENV_FILTER); dwFlags.reset(INS_SETPANNING); SetCutoff(GetCutoff(), false); SetResonance(GetResonance(), false); nFilterMode = FLTMODE_UNCHANGED; nCutSwing = nPanSwing = nResSwing = nVolSwing = 0; nPPC = NOTE_MIDDLEC - 1; nPPS = 0; nNNA = NNA_NOTECUT; nDCT = DCT_NONE; nDNA = DNA_NOTECUT; if(nMidiChannel == MidiMappedChannel) { nMidiChannel = 1; } // FT2 only has unsigned Pitch Wheel Depth, and it's limited to 0...36 (in the GUI, at least. As you would expect it from FT2, this value is actually not sanitized on load). midiPWD = static_cast(mpt::abs(midiPWD)); Limit(midiPWD, int8(0), int8(36)); nGlobalVol = 64; nPan = 128; LimitMax(nFadeOut, 32767u); } VolEnv.Convert(fromType, toType); PanEnv.Convert(fromType, toType); PitchEnv.Convert(fromType, toType); if(fromType == MOD_TYPE_XM && (toType & (MOD_TYPE_IT | MOD_TYPE_MPT))) { if(!VolEnv.dwFlags[ENV_ENABLED]) { // Note-Off with no envelope cuts the note immediately in XM VolEnv.resize(2); VolEnv[0].tick = 0; VolEnv[0].value = ENVELOPE_MAX; VolEnv[1].tick = 1; VolEnv[1].value = ENVELOPE_MIN; VolEnv.dwFlags.set(ENV_ENABLED | ENV_SUSTAIN); VolEnv.dwFlags.reset(ENV_LOOP); VolEnv.nSustainStart = VolEnv.nSustainEnd = 0; } } // Limit fadeout length for IT if(toType & MOD_TYPE_IT) { LimitMax(nFadeOut, 8192u); } // MPT-specific features - remove instrument tunings, Pitch/Tempo Lock, cutoff / resonance swing and filter mode for other formats if(!(toType & MOD_TYPE_MPT)) { SetTuning(nullptr); pitchToTempoLock.Set(0); nCutSwing = nResSwing = 0; nFilterMode = FLTMODE_UNCHANGED; nVolRampUp = 0; } } // Get a set of all samples referenced by this instrument std::set ModInstrument::GetSamples() const { std::set referencedSamples; for(size_t i = 0; i < CountOf(Keyboard); i++) { // 0 isn't a sample. if(Keyboard[i] != 0) { referencedSamples.insert(Keyboard[i]); } } return referencedSamples; } // Write sample references into a bool vector. If a sample is referenced by this instrument, true is written. // The caller has to initialize the vector. void ModInstrument::GetSamples(std::vector &referencedSamples) const { for(size_t i = 0; i < CountOf(Keyboard); i++) { // 0 isn't a sample. if(Keyboard[i] != 0 && Keyboard[i] < referencedSamples.size()) { referencedSamples[Keyboard[i]] = true; } } } void ModInstrument::Sanitize(MODTYPE modType) { LimitMax(nFadeOut, 65536u); LimitMax(nGlobalVol, 64u); LimitMax(nPan, 256u); LimitMax(wMidiBank, uint16(16384)); LimitMax(nMidiProgram, uint8(128)); LimitMax(nMidiChannel, uint8(17)); if(nNNA > NNA_NOTEFADE) nNNA = NNA_NOTECUT; if(nDCT > DCT_PLUGIN) nDCT = DCT_NONE; if(nDNA > DNA_NOTEFADE) nDNA = DNA_NOTECUT; LimitMax(nPanSwing, uint8(64)); LimitMax(nVolSwing, uint8(100)); Limit(nPPS, int8(-32), int8(32)); LimitMax(nCutSwing, uint8(64)); LimitMax(nResSwing, uint8(64)); #ifdef MODPLUG_TRACKER MPT_UNREFERENCED_PARAMETER(modType); const uint8 range = ENVELOPE_MAX; #else const uint8 range = modType == MOD_TYPE_AMS2 ? uint8_max : ENVELOPE_MAX; #endif VolEnv.Sanitize(); PanEnv.Sanitize(); PitchEnv.Sanitize(range); for(size_t i = 0; i < CountOf(NoteMap); i++) { if(NoteMap[i] < NOTE_MIN || NoteMap[i] > NOTE_MAX) NoteMap[i] = static_cast(i + NOTE_MIN); } } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/ITTools.h0000644000372100037210000002405613215224652017614 00000000000000/* * ITTools.h * --------- * Purpose: Definition of IT file structures and helper functions * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "../soundlib/ModInstrument.h" #include "../soundlib/ModSample.h" #include "../soundlib/SampleIO.h" OPENMPT_NAMESPACE_BEGIN struct ITFileHeader { // Header Flags enum ITHeaderFlags { useStereoPlayback = 0x01, vol0Optimisations = 0x02, instrumentMode = 0x04, linearSlides = 0x08, itOldEffects = 0x10, itCompatGxx = 0x20, useMIDIPitchController = 0x40, reqEmbeddedMIDIConfig = 0x80, extendedFilterRange = 0x1000, }; // Special Flags enum ITHeaderSpecialFlags { embedSongMessage = 0x01, embedEditHistory = 0x02, embedPatternHighlights = 0x04, embedMIDIConfiguration = 0x08, }; char id[4]; // Magic Bytes (IMPM) char songname[26]; // Song Name, null-terminated (but may also contain nulls) uint8le highlight_minor; // Rows per Beat highlight uint8le highlight_major; // Rows per Measure highlight uint16le ordnum; // Number of Orders uint16le insnum; // Number of Instruments uint16le smpnum; // Number of Samples uint16le patnum; // Number of Patterns uint16le cwtv; // "Made With" Tracker uint16le cmwt; // "Compatible With" Tracker uint16le flags; // Header Flags uint16le special; // Special Flags, for embedding extra information uint8le globalvol; // Global Volume (0...128) uint8le mv; // Master Volume (0...128), referred to as Sample Volume in OpenMPT uint8le speed; // Initial Speed (1...255) uint8le tempo; // Initial Tempo (31...255) uint8le sep; // Pan Separation (0...128) uint8le pwd; // Pitch Wheel Depth uint16le msglength; // Length of Song Message uint32le msgoffset; // Offset of Song Message in File (IT crops message after first null) uint32le reserved; // Some IT versions save an edit timer here. ChibiTracker writes "CHBI" here. OpenMPT writes "OMPT" here in some cases, see Load_it.cpp uint8le chnpan[64]; // Initial Channel Panning uint8le chnvol[64]; // Initial Channel Volume }; MPT_BINARY_STRUCT(ITFileHeader, 192) struct ITEnvelope { // Envelope Flags enum ITEnvelopeFlags { envEnabled = 0x01, envLoop = 0x02, envSustain = 0x04, envCarry = 0x08, envFilter = 0x80, }; struct Node { int8le value; uint16le tick; }; uint8 flags; // Envelope Flags uint8 num; // Number of Envelope Nodes uint8 lpb; // Loop Start uint8 lpe; // Loop End uint8 slb; // Sustain Start uint8 sle; // Sustain End Node data[25]; // Envelope Node Positions / Values uint8 reserved; // Reserved // Convert OpenMPT's internal envelope format to an IT/MPTM envelope. void ConvertToIT(const InstrumentEnvelope &mptEnv, uint8 envOffset, uint8 envDefault); // Convert IT/MPTM envelope data into OpenMPT's internal envelope format - To be used by ITInstrToMPT() void ConvertToMPT(InstrumentEnvelope &mptEnv, uint8 envOffset, uint8 maxNodes) const; }; MPT_BINARY_STRUCT(ITEnvelope::Node, 3) MPT_BINARY_STRUCT(ITEnvelope, 82) // Old Impulse Instrument Format (cmwt < 0x200) struct ITOldInstrument { enum ITOldInstrFlags { envEnabled = 0x01, envLoop = 0x02, envSustain = 0x04, }; char id[4]; // Magic Bytes (IMPI) char filename[13]; // DOS Filename, null-terminated uint8le flags; // Volume Envelope Flags uint8le vls; // Envelope Loop Start uint8le vle; // Envelope Loop End uint8le sls; // Envelope Sustain Start uint8le sle; // Envelope Sustain End char reserved1[2]; // Reserved uint16le fadeout; // Instrument Fadeout (0...128) uint8le nna; // New Note Action uint8le dnc; // Duplicate Note Check Type uint16le trkvers; // Tracker ID uint8le nos; // Number of embedded samples char reserved2; // Reserved char name[26]; // Instrument Name, null-terminated (but may also contain nulls) char reserved3[6]; // Even more reserved bytes uint8le keyboard[240]; // Sample / Transpose map uint8le volenv[200]; // This appears to be a pre-computed (interpolated) version of the volume envelope data found below. uint8le nodes[25 * 2]; // Volume Envelope Node Positions / Values // Convert an ITOldInstrument to OpenMPT's internal instrument representation. void ConvertToMPT(ModInstrument &mptIns) const; }; MPT_BINARY_STRUCT(ITOldInstrument, 554) // Impulse Instrument Format struct ITInstrument { enum ITInstrumentFlags { ignorePanning = 0x80, enableCutoff = 0x80, enableResonance = 0x80, }; char id[4]; // Magic Bytes (IMPI) char filename[13]; // DOS Filename, null-terminated uint8le nna; // New Note Action uint8le dct; // Duplicate Note Check Type uint8le dca; // Duplicate Note Check Action uint16le fadeout; // Instrument Fadeout (0...256, although values up to 1024 would be sensible. Up to IT2.07, the limit was 0...128) int8le pps; // Pitch/Pan Separatation uint8le ppc; // Pitch/Pan Centre uint8le gbv; // Global Volume uint8le dfp; // Panning uint8le rv; // Vol Swing uint8le rp; // Pan Swing uint16le trkvers; // Tracker ID uint8le nos; // Number of embedded samples char reserved1; // Reserved char name[26]; // Instrument Name, null-terminated (but may also contain nulls) uint8le ifc; // Filter Cutoff uint8le ifr; // Filter Resonance uint8le mch; // MIDI Channel uint8le mpr; // MIDI Program uint8le mbank[2]; // MIDI Bank uint8le keyboard[240]; // Sample / Transpose map ITEnvelope volenv; // Volume Envelope ITEnvelope panenv; // Pan Envelope ITEnvelope pitchenv; // Pitch / Filter Envelope char dummy[4]; // IT saves some additional padding bytes to match the size of the old instrument format for simplified loading. We use them for some hacks. // Convert OpenMPT's internal instrument representation to an ITInstrument. Returns amount of bytes that need to be written. uint32 ConvertToIT(const ModInstrument &mptIns, bool compatExport, const CSoundFile &sndFile); // Convert an ITInstrument to OpenMPT's internal instrument representation. Returns size of the instrument data that has been read. uint32 ConvertToMPT(ModInstrument &mptIns, MODTYPE fromType) const; }; MPT_BINARY_STRUCT(ITInstrument, 554) // MPT IT Instrument Extension struct ITInstrumentEx { ITInstrument iti; // Normal IT Instrument uint8 keyboardhi[120]; // High Byte of Sample map // Convert OpenMPT's internal instrument representation to an ITInstrumentEx. Returns amount of bytes that need to be written. uint32 ConvertToIT(const ModInstrument &mptIns, bool compatExport, const CSoundFile &sndFile); // Convert an ITInstrumentEx to OpenMPT's internal instrument representation. Returns size of the instrument data that has been read. uint32 ConvertToMPT(ModInstrument &mptIns, MODTYPE fromType) const; }; MPT_BINARY_STRUCT(ITInstrumentEx, sizeof(ITInstrument) + 120) // IT Sample Format struct ITSample { // Magic Bytes enum Magic { magic = 0x53504D49, // "IMPS" IT Sample Header Magic Bytes }; enum ITSampleFlags { sampleDataPresent = 0x01, sample16Bit = 0x02, sampleStereo = 0x04, sampleCompressed = 0x08, sampleLoop = 0x10, sampleSustain = 0x20, sampleBidiLoop = 0x40, sampleBidiSustain = 0x80, enablePanning = 0x80, cvtSignedSample = 0x01, cvtExternalSample = 0x80, // Keep MPTM sample on disk cvtADPCMSample = 0xFF, // MODPlugin :( // ITTECH.TXT says these convert flags are "safe to ignore". IT doesn't ignore them, though, so why should we? :) cvtBigEndian = 0x02, cvtDelta = 0x04, cvtPTM8to16 = 0x08, }; char id[4]; // Magic Bytes (IMPS) char filename[13]; // DOS Filename, null-terminated uint8le gvl; // Global Volume uint8le flags; // Sample Flags uint8le vol; // Default Volume char name[26]; // Sample Name, null-terminated (but may also contain nulls) uint8le cvt; // Sample Import Format uint8le dfp; // Sample Panning uint32le length; // Sample Length (in samples) uint32le loopbegin; // Sample Loop Begin (in samples) uint32le loopend; // Sample Loop End (in samples) uint32le C5Speed; // C-5 frequency uint32le susloopbegin; // Sample Sustain Begin (in samples) uint32le susloopend; // Sample Sustain End (in samples) uint32le samplepointer; // Pointer to sample data uint8le vis; // Auto-Vibrato Rate (called Sweep in IT) uint8le vid; // Auto-Vibrato Depth uint8le vir; // Auto-Vibrato Sweep (called Rate in IT) uint8le vit; // Auto-Vibrato Type // Convert OpenMPT's internal sample representation to an ITSample. void ConvertToIT(const ModSample &mptSmp, MODTYPE fromType, bool compress, bool compressIT215, bool allowExternal); // Convert an ITSample to OpenMPT's internal sample representation. uint32 ConvertToMPT(ModSample &mptSmp) const; // Retrieve the internal sample format flags for this instrument. SampleIO GetSampleFormat(uint16 cwtv = 0x214) const; }; MPT_BINARY_STRUCT(ITSample, 80) struct FileHistory; // IT Header extension: Save history struct ITHistoryStruct { uint16le fatdate; // DOS / FAT date when the file was opened / created in the editor. For details, read http://msdn.microsoft.com/en-us/library/ms724247(VS.85).aspx uint16le fattime; // DOS / FAT time when the file was opened / created in the editor. uint32le runtime; // The time how long the file was open in the editor, in 1/18.2th seconds. (= ticks of the DOS timer) // Convert an ITHistoryStruct to OpenMPT's internal edit history representation void ConvertToMPT(FileHistory &mptHistory) const; // Convert OpenMPT's internal edit history representation to an ITHistoryStruct void ConvertToIT(const FileHistory &mptHistory); }; MPT_BINARY_STRUCT(ITHistoryStruct, 8) enum IT_ReaderBitMasks { // pattern row parsing, the channel data is read to obtain // number of channels active in the pattern. These bit masks are // to blank out sections of the byte of data being read. IT_bitmask_patternChanField_c = 0x7f, IT_bitmask_patternChanMask_c = 0x3f, IT_bitmask_patternChanEnabled_c = 0x80, IT_bitmask_patternChanUsed_c = 0x0f }; OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/MixFuncTable.h0000644000372100037210000000170713116243551020575 00000000000000/* * MixFuncTable.h * -------------- * Purpose: Table containing all mixer functions. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "MixerInterface.h" OPENMPT_NAMESPACE_BEGIN namespace MixFuncTable { // Table index: // [b1-b0] format (8-bit-mono, 16-bit-mono, 8-bit-stereo, 16-bit-stereo) // [b2] ramp // [b3] filter // [b6-b4] src type // Sample type / processing type index enum FunctionIndex { ndx16Bit = 0x01, ndxStereo = 0x02, ndxRamp = 0x04, ndxFilter = 0x08, }; // SRC index enum ResamplingIndex { ndxNoInterpolation = 0x00, ndxLinear = 0x10, ndxFastSinc = 0x20, ndxKaiser = 0x30, ndxFIRFilter = 0x40, ndxAmigaBlep = 0x50, }; extern const MixFuncInterface Functions[6 * 16]; ResamplingIndex ResamplingModeToMixFlags(ResamplingMode resamplingMode); } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/OggStream.cpp0000644000372100037210000000733313077154531020505 00000000000000/* * OggStream.cpp * ------------- * Purpose: Basic Ogg stream parsing functionality * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "OggStream.h" #include "../common/FileReader.h" #include "../common/mptCRC.h" #include "../common/mptIO.h" OPENMPT_NAMESPACE_BEGIN namespace Ogg { uint16 PageInfo::GetPagePhysicalSize() const { uint16 size = 0; size += sizeof(PageHeader); size += header.page_segments; for(uint8 segment = 0; segment < header.page_segments; ++segment) { size += segment_table[segment]; } return size; } uint16 PageInfo::GetPageDataSize() const { uint16 size = 0; for(uint8 segment = 0; segment < header.page_segments; ++segment) { size += segment_table[segment]; } return size; } bool AdvanceToPageMagic(FileReader &file) { #if MPT_COMPILER_MSVC #pragma warning(push) #pragma warning(disable:4127) // conditional expression is constant #endif // MPT_COMPILER_MSVC while(true) #if MPT_COMPILER_MSVC #pragma warning(pop) #endif // MPT_COMPILER_MSVC { if(!file.CanRead(4)) { return false; } if(file.ReadMagic("OggS")) { file.SkipBack(4); return true; } file.Skip(1); } } bool ReadPage(FileReader &file, PageInfo &pageInfo, std::vector &pageData) { pageInfo = PageInfo(); pageData.clear(); if(!file.ReadMagic("OggS")) { return false; } file.SkipBack(4); FileReader filePageReader = file; // do not modify original file read position if(!filePageReader.ReadStruct(pageInfo.header)) { return false; } if(!filePageReader.CanRead(pageInfo.header.page_segments)) { return false; } uint16 pageDataSize = 0; for(uint8 segment = 0; segment < pageInfo.header.page_segments; ++segment) { pageInfo.segment_table[segment] = filePageReader.ReadIntLE(); pageDataSize += pageInfo.segment_table[segment]; } if(!filePageReader.CanRead(pageDataSize)) { return false; } filePageReader.ReadVector(pageData, pageDataSize); filePageReader.SkipBack(pageInfo.GetPagePhysicalSize()); { mpt::crc32_ogg calculatedCRC; uint8 rawHeader[sizeof(PageHeader)]; MemsetZero(rawHeader); filePageReader.ReadArray(rawHeader); std::memset(rawHeader + 22, 0, 4); // clear out old crc calculatedCRC.process(rawHeader, rawHeader + sizeof(rawHeader)); calculatedCRC.process(pageInfo.segment_table, pageInfo.segment_table + pageInfo.header.page_segments); calculatedCRC.process(pageData); if(calculatedCRC != pageInfo.header.CRC_checksum) { return false; } } file.Skip(pageInfo.GetPagePhysicalSize()); return true; } bool ReadPageAndSkipJunk(FileReader &file, PageInfo &pageInfo, std::vector &pageData) { pageInfo = PageInfo(); pageData.clear(); #if MPT_COMPILER_MSVC #pragma warning(push) #pragma warning(disable:4127) // conditional expression is constant #endif // MPT_COMPILER_MSVC while(true) #if MPT_COMPILER_MSVC #pragma warning(pop) #endif // MPT_COMPILER_MSVC { if(!AdvanceToPageMagic(file)) { return false; } if(ReadPage(file, pageInfo, pageData)) { return true; } else { pageInfo = PageInfo(); pageData.clear(); } file.Skip(1); } } bool UpdatePageCRC(PageInfo &pageInfo, const std::vector &pageData) { if(pageData.size() != pageInfo.GetPageDataSize()) { return false; } mpt::crc32_ogg crc; pageInfo.header.CRC_checksum = 0; char rawHeader[sizeof(PageHeader)]; std::memcpy(rawHeader, &pageInfo.header, sizeof(PageHeader)); crc.process(rawHeader, rawHeader + sizeof(PageHeader)); crc.process(pageInfo.segment_table, pageInfo.segment_table + pageInfo.header.page_segments); crc.process(pageData); pageInfo.header.CRC_checksum = crc; return true; } } // namespace Ogg OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Dlsbank.h0000644000372100037210000001070213161656666017644 00000000000000/* * DLSBank.h * --------- * Purpose: Sound bank loading. * Notes : Supported sound bank types: DLS (including embedded DLS in MSS & RMI), SF2 * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once OPENMPT_NAMESPACE_BEGIN class CSoundFile; OPENMPT_NAMESPACE_END #include "Snd_defs.h" OPENMPT_NAMESPACE_BEGIN #ifdef MODPLUG_TRACKER #define DLSMAXREGIONS 128 // Region Flags #define DLSREGION_KEYGROUPMASK 0x0F #define DLSREGION_OVERRIDEWSMP 0x10 #define DLSREGION_PINGPONGLOOP 0x20 #define DLSREGION_SAMPLELOOP 0x40 #define DLSREGION_SELFNONEXCLUSIVE 0x80 #define DLSREGION_SUSTAINLOOP 0x100 struct DLSREGION { uint32 ulLoopStart; uint32 ulLoopEnd; uint16 nWaveLink; uint16 uPercEnv; uint16 usVolume; // 0..256 uint16 fuOptions; // flags + key group int16 sFineTune; // +128 = +1 semitone uint8 uKeyMin; uint8 uKeyMax; uint8 uUnityNote; }; struct DLSENVELOPE { // Volume Envelope uint16 wVolAttack; // Attack Time: 0-1000, 1 = 20ms (1/50s) -> [0-20s] uint16 wVolDecay; // Decay Time: 0-1000, 1 = 20ms (1/50s) -> [0-20s] uint16 wVolRelease; // Release Time: 0-1000, 1 = 20ms (1/50s) -> [0-20s] uint8 nVolSustainLevel; // Sustain Level: 0-128, 128=100% uint8 nDefPan; // Default Pan }; // Special Bank bits #define F_INSTRUMENT_DRUMS 0x80000000 struct DLSINSTRUMENT { uint32 ulBank, ulInstrument; uint32 nRegions, nMelodicEnv; DLSREGION Regions[DLSMAXREGIONS]; char szName[32]; // SF2 stuff (DO NOT USE! -> used internally by the SF2 loader) uint16 wPresetBagNdx, wPresetBagNum; }; struct DLSSAMPLEEX { char szName[20]; uint32 dwLen; uint32 dwStartloop; uint32 dwEndloop; uint32 dwSampleRate; uint8 byOriginalPitch; int8 chPitchCorrection; }; #define SOUNDBANK_TYPE_INVALID 0 #define SOUNDBANK_TYPE_DLS 0x01 #define SOUNDBANK_TYPE_SF2 0x02 struct SOUNDBANKINFO { std::string szBankName, szCopyRight, szComments, szEngineer, szSoftware, // ISFT: Software szDescription; // ISBJ: Subject }; struct IFFCHUNK; struct SF2LOADERINFO; class CDLSBank { protected: SOUNDBANKINFO m_BankInfo; mpt::PathString m_szFileName; uint32 m_nType; uint32 m_dwWavePoolOffset; // DLS Information uint32 m_nMaxWaveLink; std::vector m_WaveForms; std::vector m_Instruments; std::vector m_SamplesEx; std::vector m_Envelopes; public: CDLSBank(); static bool IsDLSBank(const mpt::PathString &filename); static uint32 MakeMelodicCode(uint32 bank, uint32 instr) { return ((bank << 16) | (instr));} static uint32 MakeDrumCode(uint32 rgn, uint32 instr) { return (0x80000000 | (rgn << 16) | (instr));} public: bool Open(const mpt::PathString &filename); bool Open(FileReader file); mpt::PathString GetFileName() const { return m_szFileName; } uint32 GetBankType() const { return m_nType; } const SOUNDBANKINFO &GetBankInfo() const { return m_BankInfo; } public: uint32 GetNumInstruments() const { return static_cast(m_Instruments.size()); } uint32 GetNumSamples() const { return static_cast(m_WaveForms.size()); } DLSINSTRUMENT *GetInstrument(uint32 iIns) { return iIns < m_Instruments.size() ? &m_Instruments[iIns] : nullptr; } DLSINSTRUMENT *FindInstrument(bool bDrum, uint32 nBank=0xFF, uint32 dwProgram=0xFF, uint32 dwKey=0xFF, uint32 *pInsNo=nullptr); uint32 GetRegionFromKey(uint32 nIns, uint32 nKey); bool ExtractWaveForm(uint32 nIns, uint32 nRgn, std::vector &waveData, uint32 &length); bool ExtractSample(CSoundFile &sndFile, SAMPLEINDEX nSample, uint32 nIns, uint32 nRgn, int transpose=0); bool ExtractInstrument(CSoundFile &sndFile, INSTRUMENTINDEX nInstr, uint32 nIns, uint32 nDrumRgn); const char *GetRegionName(uint32 nIns, uint32 nRgn) const; uint8 GetPanning(uint32 ins, uint32 region) const; // Internal Loader Functions protected: bool UpdateInstrumentDefinition(DLSINSTRUMENT *pDlsIns, const IFFCHUNK *pchunk, uint32 dwMaxLen); bool UpdateSF2PresetData(SF2LOADERINFO &sf2info, const IFFCHUNK &header, FileReader &chunk); bool ConvertSF2ToDLS(SF2LOADERINFO &sf2info); public: // DLS Unit conversion static int32 DLS32BitTimeCentsToMilliseconds(int32 lTimeCents); static int32 DLS32BitRelativeGainToLinear(int32 lCentibels); // 0dB = 0x10000 static int32 DLS32BitRelativeLinearToGain(int32 lGain); // 0dB = 0x10000 static int32 DLSMidiVolumeToLinear(uint32 nMidiVolume); // [0-127] -> [0-0x10000] }; #endif // MODPLUG_TRACKER OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Load_gdm.cpp0000644000372100037210000003465713161656666020346 00000000000000/* * Load_gdm.cpp * ------------ * Purpose: GDM (BWSB Soundsystem) module loader * Notes : This code is partly based on zilym's original code / specs (which are utterly wrong :P). * Thanks to the MenTaLguY for gdm.txt and ajs for gdm2s3m and some hints. * * Hint 1: Most (all?) of the unsupported features were not supported in 2GDM / BWSB either. * Hint 2: Files will be played like their original formats would be played in MPT, so no * BWSB quirks including crashes and freezes are supported. :-P * Authors: Johannes Schultz * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" #include "mod_specifications.h" OPENMPT_NAMESPACE_BEGIN // GDM File Header struct GDMFileHeader { char magic[4]; // ID: 'GDM\xFE' char songTitle[32]; // Music's title char songMusician[32]; // Name of music's composer char dosEOF[3]; // 13, 10, 26 char magic2[4]; // ID: 'GMFS' uint8le formatMajorVer; // Format major version uint8le formatMinorVer; // Format minor version uint16le trackerID; // Composing Tracker ID code (00 = 2GDM) uint8le trackerMajorVer; // Tracker's major version uint8le trackerMinorVer; // Tracker's minor version uint8le panMap[32]; // 0-Left to 15-Right, 255-N/U uint8le masterVol; // Range: 0...64 uint8le tempo; // Initial music tempo (6) uint8le bpm; // Initial music BPM (125) uint16le originalFormat; // Original format ID: // 1-MOD, 2-MTM, 3-S3M, 4-669, 5-FAR, 6-ULT, 7-STM, 8-MED, 9-PSM // (versions of 2GDM prior to v1.15 won't set this correctly) // 2GDM v1.17 will only spit out 0-byte files when trying to convert a PSM16 file, // and fail outright when trying to convert a new PSM file. uint32le orderOffset; uint8le lastOrder; // Number of orders in module - 1 uint32le patternOffset; uint8le lastPattern; // Number of patterns in module - 1 uint32le sampleHeaderOffset; uint32le sampleDataOffset; uint8le lastSample; // Number of samples in module - 1 uint32le messageTextOffset; // Offset of song message uint32le messageTextLength; uint32le scrollyScriptOffset; // Offset of scrolly script (huh?) uint16le scrollyScriptLength; uint32le textGraphicOffset; // Offset of text graphic (huh?) uint16le textGraphicLength; }; MPT_BINARY_STRUCT(GDMFileHeader, 157) // GDM Sample Header struct GDMSampleHeader { enum SampleFlags { smpLoop = 0x01, smp16Bit = 0x02, // 16-Bit samples are not handled correctly by 2GDM (not implemented) smpVolume = 0x04, smpPanning = 0x08, smpLZW = 0x10, // LZW-compressed samples are not implemented in 2GDM smpStereo = 0x20, // Stereo samples are not handled correctly by 2GDM (not implemented) }; char name[32]; // sample's name char fileName[12]; // sample's filename uint8le emsHandle; // useless uint32le length; // length in bytes uint32le loopBegin; // loop start in samples uint32le loopEnd; // loop end in samples uint8le flags; // misc. flags uint16le c4Hertz; // frequency uint8le volume; // default volume uint8le panning; // default pan }; MPT_BINARY_STRUCT(GDMSampleHeader, 62) static const MODTYPE gdmFormatOrigin[] = { MOD_TYPE_NONE, MOD_TYPE_MOD, MOD_TYPE_MTM, MOD_TYPE_S3M, MOD_TYPE_669, MOD_TYPE_FAR, MOD_TYPE_ULT, MOD_TYPE_STM, MOD_TYPE_MED, MOD_TYPE_PSM }; static bool ValidateHeader(const GDMFileHeader &fileHeader) { if(std::memcmp(fileHeader.magic, "GDM\xFE", 4) || fileHeader.dosEOF[0] != 13 || fileHeader.dosEOF[1] != 10 || fileHeader.dosEOF[2] != 26 || std::memcmp(fileHeader.magic2, "GMFS", 4) || fileHeader.formatMajorVer != 1 || fileHeader.formatMinorVer != 0 || fileHeader.originalFormat >= mpt::size(gdmFormatOrigin) || fileHeader.originalFormat == 0) { return false; } return true; } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderGDM(MemoryFileReader file, const uint64 *pfilesize) { GDMFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return ProbeWantMoreData; } if(!ValidateHeader(fileHeader)) { return ProbeFailure; } MPT_UNREFERENCED_PARAMETER(pfilesize); return ProbeSuccess; } bool CSoundFile::ReadGDM(FileReader &file, ModLoadingFlags loadFlags) { file.Rewind(); GDMFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return false; } if(!ValidateHeader(fileHeader)) { return false; } if(loadFlags == onlyVerifyHeader) { return true; } InitializeGlobals(gdmFormatOrigin[fileHeader.originalFormat]); m_ContainerType = MOD_CONTAINERTYPE_GDM; m_madeWithTracker = mpt::format(MPT_USTRING("BWSB 2GDM %1.%2 (converted from %3)"))(fileHeader.trackerMajorVer, fileHeader.formatMinorVer, ModTypeToTracker(GetType())); // Song name mpt::String::Read(m_songName, fileHeader.songTitle); // Artist name { std::string artist; mpt::String::Read(artist, fileHeader.songMusician); if(artist != "Unknown") { m_songArtist = mpt::ToUnicode(mpt::CharsetCP437, artist); } } // Read channel pan map... 0...15 = channel panning, 16 = surround channel, 255 = channel does not exist m_nChannels = 32; for(CHANNELINDEX i = 0; i < 32; i++) { ChnSettings[i].Reset(); if(fileHeader.panMap[i] < 16) { ChnSettings[i].nPan = static_cast(std::min((fileHeader.panMap[i] * 16) + 8, 256)); } else if(fileHeader.panMap[i] == 16) { ChnSettings[i].nPan = 128; ChnSettings[i].dwFlags = CHN_SURROUND; } else if(fileHeader.panMap[i] == 0xFF) { m_nChannels = i; break; } } if(m_nChannels < 1) { return false; } m_nDefaultGlobalVolume = std::min(fileHeader.masterVol * 4u, 256u); m_nDefaultSpeed = fileHeader.tempo; m_nDefaultTempo.Set(fileHeader.bpm); // Read orders if(file.Seek(fileHeader.orderOffset)) { ReadOrderFromFile(Order(), file, fileHeader.lastOrder + 1, 0xFF, 0xFE); } // Read samples if(!file.Seek(fileHeader.sampleHeaderOffset)) { return false; } m_nSamples = fileHeader.lastSample + 1; // Sample headers for(SAMPLEINDEX smp = 1; smp <= m_nSamples; smp++) { GDMSampleHeader gdmSample; if(!file.ReadStruct(gdmSample)) { break; } ModSample &sample = Samples[smp]; sample.Initialize(); mpt::String::Read(m_szNames[smp], gdmSample.name); mpt::String::Read(sample.filename, gdmSample.fileName); sample.nC5Speed = gdmSample.c4Hertz; sample.nGlobalVol = 256; // Not supported in this format sample.nLength = gdmSample.length; // in bytes // Sample format if(gdmSample.flags & GDMSampleHeader::smp16Bit) { sample.uFlags.set(CHN_16BIT); sample.nLength /= 2; } sample.nLoopStart = gdmSample.loopBegin; // in samples sample.nLoopEnd = gdmSample.loopEnd - 1; // ditto sample.FrequencyToTranspose(); // set transpose + finetune for mod files // Fix transpose + finetune for some rare cases where transpose is not C-5 (e.g. sample 4 in wander2.gdm) if(m_nType == MOD_TYPE_MOD) { if(sample.RelativeTone > 0) { sample.RelativeTone -= 1; sample.nFineTune += 128; } else if(sample.RelativeTone < 0) { sample.RelativeTone += 1; sample.nFineTune -= 128; } } if(gdmSample.flags & GDMSampleHeader::smpLoop) sample.uFlags.set(CHN_LOOP); // Loop sample if(gdmSample.flags & GDMSampleHeader::smpVolume) { // Default volume is used... 0...64, 255 = no default volume sample.nVolume = std::min(gdmSample.volume, 64) * 4; } else { sample.uFlags.set(SMP_NODEFAULTVOLUME); } if(gdmSample.flags & GDMSampleHeader::smpPanning) { // Default panning is used sample.uFlags.set(CHN_PANNING); // 0...15, 16 = surround (not supported), 255 = no default panning sample.nPan = static_cast((gdmSample.panning > 15) ? 128 : std::min((gdmSample.panning * 16) + 8, 256)); sample.uFlags.set(CHN_SURROUND, gdmSample.panning == 16); } else { sample.nPan = 128; } } // Read sample data if((loadFlags & loadSampleData) && file.Seek(fileHeader.sampleDataOffset)) { for(SAMPLEINDEX smp = 1; smp <= GetNumSamples(); smp++) { SampleIO( Samples[smp].uFlags[CHN_16BIT] ? SampleIO::_16bit : SampleIO::_8bit, SampleIO::mono, SampleIO::littleEndian, SampleIO::unsignedPCM) .ReadSample(Samples[smp], file); } } // Read patterns Patterns.ResizeArray(fileHeader.lastPattern + 1); const CModSpecifications &modSpecs = GetModSpecifications(GetBestSaveFormat()); bool onlyAmigaNotes = true; // We'll start at position patternsOffset and decode all patterns file.Seek(fileHeader.patternOffset); for(PATTERNINDEX pat = 0; pat <= fileHeader.lastPattern; pat++) { // Read pattern length *including* the two "length" bytes uint16 patternLength = file.ReadUint16LE(); if(patternLength <= 2) { // Huh, no pattern data present? continue; } FileReader chunk = file.ReadChunk(patternLength - 2); if(!(loadFlags & loadPatternData) || !chunk.IsValid() || !Patterns.Insert(pat, 64)) { continue; } enum { rowDone = 0, // Advance to next row channelMask = 0x1F, // Mask for retrieving channel information noteFlag = 0x20, // Note / instrument information present effectFlag = 0x40, // Effect information present effectMask = 0x1F, // Mask for retrieving effect command effectDone = 0x20, // Last effect in this channel }; for(ROWINDEX row = 0; row < 64; row++) { PatternRow rowBase = Patterns[pat].GetRow(row); uint8 channelByte; // If channel byte is zero, advance to next row. while((channelByte = chunk.ReadUint8()) != rowDone) { CHANNELINDEX channel = channelByte & channelMask; if(channel >= m_nChannels) break; // Better safe than sorry! ModCommand &m = rowBase[channel]; if(channelByte & noteFlag) { // Note and sample follows uint8 noteByte = chunk.ReadUint8(); uint8 noteSample = chunk.ReadUint8(); if(noteByte) { noteByte = (noteByte & 0x7F) - 1; // This format doesn't have note cuts if(noteByte < 0xF0) noteByte = (noteByte & 0x0F) + 12 * (noteByte >> 4) + 12 + NOTE_MIN; m.note = noteByte; if(!m.IsAmigaNote()) { onlyAmigaNotes = false; } } m.instr = noteSample; } if(channelByte & effectFlag) { // Effect(s) follow(s) m.command = CMD_NONE; m.volcmd = VOLCMD_NONE; while(chunk.CanRead(2)) { // We may want to restore the old command in some cases. const ModCommand oldCmd = m; uint8 effByte = chunk.ReadUint8(); m.param = chunk.ReadUint8(); // Effect translation LUT static const EffectCommand gdmEffTrans[] = { CMD_NONE, CMD_PORTAMENTOUP, CMD_PORTAMENTODOWN, CMD_TONEPORTAMENTO, CMD_VIBRATO, CMD_TONEPORTAVOL, CMD_VIBRATOVOL, CMD_TREMOLO, CMD_TREMOR, CMD_OFFSET, CMD_VOLUMESLIDE, CMD_POSITIONJUMP, CMD_VOLUME, CMD_PATTERNBREAK, CMD_MODCMDEX, CMD_SPEED, CMD_ARPEGGIO, CMD_NONE /* set internal flag */, CMD_RETRIG, CMD_GLOBALVOLUME, CMD_FINEVIBRATO, CMD_NONE, CMD_NONE, CMD_NONE, CMD_NONE, CMD_NONE, CMD_NONE, CMD_NONE, CMD_NONE, CMD_NONE, CMD_S3MCMDEX, CMD_TEMPO, }; // Translate effect uint8 command = effByte & effectMask; if(command < CountOf(gdmEffTrans)) m.command = gdmEffTrans[command]; else m.command = CMD_NONE; // Fix some effects switch(m.command) { case CMD_PORTAMENTOUP: if(m.param >= 0xE0) m.param = 0xDF; break; case CMD_PORTAMENTODOWN: if(m.param >= 0xE0) m.param = 0xDF; break; case CMD_TONEPORTAVOL: if(m.param & 0xF0) m.param &= 0xF0; break; case CMD_VIBRATOVOL: if(m.param & 0xF0) m.param &= 0xF0; break; case CMD_VOLUME: m.param = MIN(m.param, 64); if(modSpecs.HasVolCommand(VOLCMD_VOLUME)) { m.volcmd = VOLCMD_VOLUME; m.vol = m.param; // Don't destroy old command, if there was one. m.command = oldCmd.command; m.param = oldCmd.param; } break; case CMD_MODCMDEX: if(!modSpecs.HasCommand(CMD_MODCMDEX)) { m.ExtendedMODtoS3MEffect(); } break; case CMD_RETRIG: if(!modSpecs.HasCommand(CMD_RETRIG) && modSpecs.HasCommand(CMD_MODCMDEX)) { // Retrig in "MOD style" m.command = CMD_MODCMDEX; m.param = 0x90 | (m.param & 0x0F); } break; case CMD_S3MCMDEX: // Some really special commands switch(m.param >> 4) { case 0x0: switch(m.param & 0x0F) { case 0x0: // Surround Off case 0x1: // Surround On m.param += 0x90; break; case 0x2: // Set normal loop - not implemented in BWSB or 2GDM. case 0x3: // Set bidi loop - ditto m.command = CMD_NONE; break; case 0x4: // Play sample forwards m.command = CMD_S3MCMDEX; m.param = 0x9E; break; case 0x5: // Play sample backwards m.command = CMD_S3MCMDEX; m.param = 0x9F; break; case 0x6: // Monaural sample - also not implemented. case 0x7: // Stereo sample - ditto case 0x8: // Stop sample on end - ditto case 0x9: // Loop sample on end - ditto default: m.command = CMD_NONE; break; } break; case 0x8: // 4-Bit Panning if(!modSpecs.HasCommand(CMD_S3MCMDEX)) { m.command = CMD_MODCMDEX; } break; case 0xD: // Adjust frequency (increment in hz) - also not implemented. default: m.command = CMD_NONE; break; } break; case 0x1F: m.command = CMD_TEMPO; break; } // Move pannings to volume column - should never happen if(m.command == CMD_S3MCMDEX && ((m.param >> 4) == 0x8) && m.volcmd == VOLCMD_NONE) { m.volcmd = VOLCMD_PANNING; m.vol = ((m.param & 0x0F) * 64 + 8) / 15; m.command = oldCmd.command; m.param = oldCmd.param; } if(!(effByte & effectDone)) break; // no other effect follows } } } } } m_SongFlags.set(SONG_AMIGALIMITS | SONG_ISAMIGA, GetType() == MOD_TYPE_MOD && GetNumChannels() == 4 && onlyAmigaNotes); // Read song comments if(fileHeader.messageTextLength > 0 && file.Seek(fileHeader.messageTextOffset)) { m_songMessage.Read(file, fileHeader.messageTextLength, SongMessage::leAutodetect); } return true; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Load_xm.cpp0000644000372100037210000010207313227754324020200 00000000000000/* * Load_xm.cpp * ----------- * Purpose: XM (FastTracker II) module loader / saver * Notes : (currently none) * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" #include "../common/version.h" #include "../common/misc_util.h" #include "XMTools.h" #ifndef MODPLUG_NO_FILESAVE #include "../common/mptFileIO.h" #endif #include #ifdef MODPLUG_TRACKER #include "../mptrack/TrackerSettings.h" // For super smooth ramping option #endif // MODPLUG_TRACKER OPENMPT_NAMESPACE_BEGIN // Allocate samples for an instrument static std::vector AllocateXMSamples(CSoundFile &sndFile, SAMPLEINDEX numSamples) { LimitMax(numSamples, SAMPLEINDEX(32)); std::vector foundSlots; foundSlots.reserve(numSamples); for(SAMPLEINDEX i = 0; i < numSamples; i++) { SAMPLEINDEX candidateSlot = sndFile.GetNumSamples() + 1; if(candidateSlot >= MAX_SAMPLES) { // If too many sample slots are needed, try to fill some empty slots first. for(SAMPLEINDEX j = 1; j <= sndFile.GetNumSamples(); j++) { if(sndFile.GetSample(j).pSample != nullptr) { continue; } if(std::find(foundSlots.begin(), foundSlots.end(), j) == foundSlots.end()) { // Empty sample slot that is not occupied by the current instrument. Yay! candidateSlot = j; // Remove unused sample from instrument sample assignments for(INSTRUMENTINDEX ins = 1; ins <= sndFile.GetNumInstruments(); ins++) { if(sndFile.Instruments[ins] == nullptr) { continue; } for(auto &sample : sndFile.Instruments[ins]->Keyboard) { if(sample == candidateSlot) { sample = 0; } } } break; } } } if(candidateSlot >= MAX_SAMPLES) { // Still couldn't find any empty sample slots, so look out for existing but unused samples. std::vector usedSamples; SAMPLEINDEX unusedSampleCount = sndFile.DetectUnusedSamples(usedSamples); if(unusedSampleCount > 0) { sndFile.RemoveSelectedSamples(usedSamples); // Remove unused samples from instrument sample assignments for(INSTRUMENTINDEX ins = 1; ins <= sndFile.GetNumInstruments(); ins++) { if(sndFile.Instruments[ins] == nullptr) { continue; } for(auto &sample : sndFile.Instruments[ins]->Keyboard) { if(sample < usedSamples.size() && !usedSamples[sample]) { sample = 0; } } } // New candidate slot is first unused sample slot. candidateSlot = static_cast(std::find(usedSamples.begin() + 1, usedSamples.end(), false) - usedSamples.begin()); } else { // No unused sampel slots: Give up :( break; } } if(candidateSlot < MAX_SAMPLES) { foundSlots.push_back(candidateSlot); if(candidateSlot > sndFile.GetNumSamples()) { sndFile.m_nSamples = candidateSlot; } } } return foundSlots; } // Read .XM patterns static void ReadXMPatterns(FileReader &file, const XMFileHeader &fileHeader, CSoundFile &sndFile) { // Reading patterns sndFile.Patterns.ResizeArray(fileHeader.patterns); for(PATTERNINDEX pat = 0; pat < fileHeader.patterns; pat++) { FileReader::off_t curPos = file.GetPosition(); uint32 headerSize = file.ReadUint32LE(); file.Skip(1); // Pack method (= 0) ROWINDEX numRows = 64; if(fileHeader.version == 0x0102) { numRows = file.ReadUint8() + 1; } else { numRows = file.ReadUint16LE(); } // A packed size of 0 indicates a completely empty pattern. const uint16 packedSize = file.ReadUint16LE(); if(numRows == 0 || numRows > MAX_PATTERN_ROWS) { numRows = 64; } file.Seek(curPos + headerSize); FileReader patternChunk = file.ReadChunk(packedSize); if(!sndFile.Patterns.Insert(pat, numRows) || packedSize == 0) { continue; } enum PatternFlags { isPackByte = 0x80, allFlags = 0xFF, notePresent = 0x01, instrPresent = 0x02, volPresent = 0x04, commandPresent = 0x08, paramPresent = 0x10, }; for(auto &m : sndFile.Patterns[pat]) { uint8 info = patternChunk.ReadUint8(); uint8 vol = 0; if(info & isPackByte) { // Interpret byte as flag set. if(info & notePresent) m.note = patternChunk.ReadUint8(); } else { // Interpret byte as note, read all other pattern fields as well. m.note = info; info = allFlags; } if(info & instrPresent) m.instr = patternChunk.ReadUint8(); if(info & volPresent) vol = patternChunk.ReadUint8(); if(info & commandPresent) m.command = patternChunk.ReadUint8(); if(info & paramPresent) m.param = patternChunk.ReadUint8(); if(m.note == 97) { m.note = NOTE_KEYOFF; } else if(m.note > 0 && m.note < 97) { m.note += 12; } else { m.note = NOTE_NONE; } if(m.command | m.param) { CSoundFile::ConvertModCommand(m); } else { m.command = CMD_NONE; } if(m.instr == 0xFF) { m.instr = 0; } if(vol >= 0x10 && vol <= 0x50) { m.volcmd = VOLCMD_VOLUME; m.vol = vol - 0x10; } else if (vol >= 0x60) { // Volume commands 6-F translation. static const ModCommand::VOLCMD volEffTrans[] = { VOLCMD_VOLSLIDEDOWN, VOLCMD_VOLSLIDEUP, VOLCMD_FINEVOLDOWN, VOLCMD_FINEVOLUP, VOLCMD_VIBRATOSPEED, VOLCMD_VIBRATODEPTH, VOLCMD_PANNING, VOLCMD_PANSLIDELEFT, VOLCMD_PANSLIDERIGHT, VOLCMD_TONEPORTAMENTO, }; m.volcmd = volEffTrans[(vol - 0x60) >> 4]; m.vol = vol & 0x0F; if(m.volcmd == VOLCMD_PANNING) { m.vol *= 4; // FT2 does indeed not scale panning symmetrically. } } } } } enum TrackerVersions { verUnknown = 0x00, // Probably not made with MPT verOldModPlug = 0x01, // Made with MPT Alpha / Beta verNewModPlug = 0x02, // Made with MPT (not Alpha / Beta) verModPlug1_09 = 0x04, // Made with MPT 1.09 or possibly other version verOpenMPT = 0x08, // Made with OpenMPT verConfirmed = 0x10, // We are very sure that we found the correct tracker version. verFT2Generic = 0x20, // "FastTracker v2.00", but FastTracker has NOT been ruled out verOther = 0x40, // Something we don't know, testing for DigiTrakker. verFT2Clone = 0x80, // NOT FT2: itype changed between instruments, or \0 found in song title verDigiTrakker = 0x100, // Probably DigiTrakker verUNMO3 = 0x200, // TODO: UNMO3-ed XMs are detected as MPT 1.16 verEmptyOrders = 0x400, // Allow empty order list like in OpenMPT (FT2 just plays pattern 0 if the order list is empty according to the header) }; DECLARE_FLAGSET(TrackerVersions) static bool ValidateHeader(const XMFileHeader &fileHeader) { if(fileHeader.channels == 0 || fileHeader.channels > MAX_BASECHANNELS || std::memcmp(fileHeader.signature, "Extended Module: ", 17) ) { return false; } return true; } static uint64 GetHeaderMinimumAdditionalSize(const XMFileHeader &fileHeader) { return fileHeader.orders + 4 * (fileHeader.patterns + fileHeader.instruments); } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderXM(MemoryFileReader file, const uint64 *pfilesize) { XMFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return ProbeWantMoreData; } if(!ValidateHeader(fileHeader)) { return ProbeFailure; } return ProbeAdditionalSize(file, pfilesize, GetHeaderMinimumAdditionalSize(fileHeader)); } bool CSoundFile::ReadXM(FileReader &file, ModLoadingFlags loadFlags) { file.Rewind(); XMFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return false; } if(!ValidateHeader(fileHeader)) { return false; } if(!file.CanRead(mpt::saturate_cast(GetHeaderMinimumAdditionalSize(fileHeader)))) { return false; } else if(loadFlags == onlyVerifyHeader) { return true; } InitializeGlobals(MOD_TYPE_XM); InitializeChannels(); m_nMixLevels = mixLevelsCompatible; FlagSet madeWith(verUnknown); if(!memcmp(fileHeader.trackerName, "FastTracker ", 12)) { if(fileHeader.size == 276 && !memcmp(fileHeader.trackerName + 12, "v2.00 ", 8)) { if(fileHeader.version < 0x0104) madeWith = verFT2Generic | verConfirmed; else if(memchr(fileHeader.songName, '\0', 20) != nullptr) // FT2 pads the song title with spaces, some other trackers use null chars madeWith = verFT2Clone | verNewModPlug | verEmptyOrders; else madeWith = verFT2Generic | verNewModPlug; } else if(!memcmp(fileHeader.trackerName + 12, "v 2.00 ", 8)) { // MPT 1.0 (exact version to be determined later) madeWith = verOldModPlug; } else { // ??? madeWith.set(verConfirmed); m_madeWithTracker = MPT_USTRING("FastTracker Clone"); } } else { // Something else! madeWith = verUnknown | verConfirmed; mpt::String::Read(m_madeWithTracker, mpt::CharsetCP437, fileHeader.trackerName); if(!memcmp(fileHeader.trackerName, "OpenMPT ", 8)) { madeWith = verOpenMPT | verConfirmed | verEmptyOrders; } else if(!memcmp(fileHeader.trackerName, "MilkyTracker ", 12)) { // MilkyTracker prior to version 0.90.87 doesn't set a version string. // Luckily, starting with v0.90.87, MilkyTracker also implements the FT2 panning scheme. if(memcmp(fileHeader.trackerName + 12, " ", 8)) { m_nMixLevels = mixLevelsCompatibleFT2; } } else if(!memcmp(fileHeader.trackerName, "MadTracker 2.0\0", 15)) { // Fix channel 2 in m3_cha.xm m_playBehaviour.reset(kFT2PortaNoNote); // Fix arpeggios in kragle_-_happy_day.xm m_playBehaviour.reset(kFT2Arpeggio); } else if(!memcmp(fileHeader.trackerName, "Skale Tracker\0", 14)) { m_playBehaviour.reset(kFT2OffsetOutOfRange); } else if(!memcmp(fileHeader.trackerName, "*Converted ", 11)) { madeWith = verDigiTrakker; } } mpt::String::Read(m_songName, fileHeader.songName); m_nMinPeriod = 1; m_nMaxPeriod = 31999; Order().SetRestartPos(fileHeader.restartPos); m_nChannels = fileHeader.channels; m_nInstruments = std::min(fileHeader.instruments, MAX_INSTRUMENTS - 1u); if(fileHeader.speed) m_nDefaultSpeed = fileHeader.speed; if(fileHeader.tempo) m_nDefaultTempo.Set(Clamp(fileHeader.tempo, 32, 512)); m_SongFlags.reset(); m_SongFlags.set(SONG_LINEARSLIDES, (fileHeader.flags & XMFileHeader::linearSlides) != 0); m_SongFlags.set(SONG_EXFILTERRANGE, (fileHeader.flags & XMFileHeader::extendedFilterRange) != 0); if(m_SongFlags[SONG_EXFILTERRANGE] && madeWith == (verFT2Generic | verNewModPlug)) { madeWith = verFT2Clone | verNewModPlug | verConfirmed; } ReadOrderFromFile(Order(), file, fileHeader.orders); if(fileHeader.orders == 0 && !madeWith[verEmptyOrders]) { // Fix lamb_-_dark_lighthouse.xm, which only contains one pattern and an empty order list Order().assign(1, 0); } file.Seek(fileHeader.size + 60); if(fileHeader.version >= 0x0104) { ReadXMPatterns(file, fileHeader, *this); } // In case of XM versions < 1.04, we need to memorize the sample flags for all samples, as they are not stored immediately after the sample headers. std::vector sampleFlags; uint8 sampleReserved = 0; int instrType = -1; // Reading instruments for(INSTRUMENTINDEX instr = 1; instr <= m_nInstruments; instr++) { // First, try to read instrument header length... uint32 headerSize = file.ReadUint32LE(); if(headerSize == 0) { headerSize = sizeof(XMInstrumentHeader); } // Now, read the complete struct. file.SkipBack(4); XMInstrumentHeader instrHeader; file.ReadStructPartial(instrHeader, headerSize); // Time for some version detection stuff. if(madeWith == verOldModPlug) { madeWith.set(verConfirmed); if(instrHeader.size == 245) { // ModPlug Tracker Alpha m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 00, 00, A5); m_madeWithTracker = MPT_USTRING("ModPlug Tracker 1.0 alpha"); } else if(instrHeader.size == 263) { // ModPlug Tracker Beta (Beta 1 still behaves like Alpha, but Beta 3.3 does it this way) m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 00, 00, B3); m_madeWithTracker = MPT_USTRING("ModPlug Tracker 1.0 beta"); } else { // WTF? madeWith = (verUnknown | verConfirmed); } } else if(instrHeader.numSamples == 0) { // Empty instruments make tracker identification pretty easy! if(instrHeader.size == 263 && instrHeader.sampleHeaderSize == 0 && madeWith[verNewModPlug]) madeWith.set(verConfirmed); else if(instrHeader.size != 29 && madeWith[verDigiTrakker]) madeWith.reset(verDigiTrakker); else if(madeWith[verFT2Clone | verFT2Generic] && instrHeader.size != 33) { // Sure isn't FT2. // Note: FT2 NORMALLY writes shdr=40 for all samples, but sometimes it // just happens to write random garbage there instead. Surprise! // Note: 4-mat's eternity.xm has an instrument header size of 29. madeWith = verUnknown; } } if(AllocateInstrument(instr) == nullptr) { continue; } instrHeader.ConvertToMPT(*Instruments[instr]); if(instrType == -1) { instrType = instrHeader.type; } else if(instrType != instrHeader.type && madeWith[verFT2Generic]) { // FT2 writes some random junk for the instrument type field, // but it's always the SAME junk for every instrument saved. madeWith.reset(verFT2Generic); madeWith.set(verFT2Clone); } if(instrHeader.numSamples > 0) { // Yep, there are some samples associated with this instrument. if((instrHeader.instrument.midiEnabled | instrHeader.instrument.midiChannel | instrHeader.instrument.midiProgram | instrHeader.instrument.muteComputer) != 0) { // Definitely not an old MPT. madeWith.reset(verOldModPlug | verNewModPlug); } // Read sample headers std::vector sampleSlots = AllocateXMSamples(*this, instrHeader.numSamples); // Update sample assignment map for(size_t k = 0 + 12; k < 96 + 12; k++) { if(Instruments[instr]->Keyboard[k] < sampleSlots.size()) { Instruments[instr]->Keyboard[k] = sampleSlots[Instruments[instr]->Keyboard[k]]; } } if(fileHeader.version >= 0x0104) { sampleFlags.clear(); } // Need to memorize those if we're going to skip any samples... std::vector sampleSize(instrHeader.numSamples); // Early versions of Sk@le Tracker set instrHeader.sampleHeaderSize = 0 (IFULOVE.XM) // cybernostra weekend has instrHeader.sampleHeaderSize = 0x12, which would leave out the sample name, but FT2 still reads the name. MPT_ASSERT(instrHeader.sampleHeaderSize == 0 || instrHeader.sampleHeaderSize == sizeof(XMSample)); for(SAMPLEINDEX sample = 0; sample < instrHeader.numSamples; sample++) { XMSample sampleHeader; file.ReadStruct(sampleHeader); sampleFlags.push_back(sampleHeader.GetSampleFormat()); sampleSize[sample] = sampleHeader.length; sampleReserved |= sampleHeader.reserved; if(sample < sampleSlots.size()) { SAMPLEINDEX mptSample = sampleSlots[sample]; sampleHeader.ConvertToMPT(Samples[mptSample]); instrHeader.instrument.ApplyAutoVibratoToMPT(Samples[mptSample]); mpt::String::Read(m_szNames[mptSample], sampleHeader.name); if((sampleHeader.flags & 3) == 3 && madeWith[verNewModPlug]) { // MPT 1.09 and maybe newer / older versions set both loop flags for bidi loops. madeWith.set(verModPlug1_09); } } } // Read samples if(fileHeader.version >= 0x0104) { for(SAMPLEINDEX sample = 0; sample < instrHeader.numSamples; sample++) { // Sample 15 in dirtysex.xm by J/M/T/M is a 16-bit sample with an odd size of 0x18B according to the header, while the real sample size would be 0x18A. // Always read as many bytes as specified in the header, even if the sample reader would probably read less bytes. FileReader sampleChunk = file.ReadChunk(sampleFlags[sample].GetEncoding() != SampleIO::ADPCM ? sampleSize[sample] : (16 + (sampleSize[sample] + 1) / 2)); if(sample < sampleSlots.size() && (loadFlags & loadSampleData)) { sampleFlags[sample].ReadSample(Samples[sampleSlots[sample]], sampleChunk); } } } } } if(sampleReserved == 0 && madeWith[verNewModPlug] && memchr(fileHeader.songName, '\0', sizeof(fileHeader.songName)) != nullptr) { // Null-terminated song name: Quite possibly MPT. (could really be an MPT-made file resaved in FT2, though) madeWith.set(verConfirmed); } if(fileHeader.version < 0x0104) { // Load Patterns and Samples (Version 1.02 and 1.03) if(loadFlags & (loadPatternData | loadSampleData)) { ReadXMPatterns(file, fileHeader, *this); } if(loadFlags & loadSampleData) { for(SAMPLEINDEX sample = 1; sample <= GetNumSamples(); sample++) { sampleFlags[sample - 1].ReadSample(Samples[sample], file); } } } // Read song comments: "text" if(file.ReadMagic("text")) { m_songMessage.Read(file, file.ReadUint32LE(), SongMessage::leCR); madeWith.set(verConfirmed); } // Read midi config: "MIDI" bool hasMidiConfig = false; if(file.ReadMagic("MIDI")) { file.ReadStructPartial(m_MidiCfg, file.ReadUint32LE()); m_MidiCfg.Sanitize(); hasMidiConfig = true; madeWith.set(verConfirmed); } // Read pattern names: "PNAM" if(file.ReadMagic("PNAM")) { const PATTERNINDEX namedPats = std::min(static_cast(file.ReadUint32LE() / MAX_PATTERNNAME), Patterns.Size()); for(PATTERNINDEX pat = 0; pat < namedPats; pat++) { char patName[MAX_PATTERNNAME]; file.ReadString(patName, MAX_PATTERNNAME); Patterns[pat].SetName(patName); } madeWith.set(verConfirmed); } // Read channel names: "CNAM" if(file.ReadMagic("CNAM")) { const CHANNELINDEX namedChans = std::min(static_cast(file.ReadUint32LE() / MAX_CHANNELNAME), GetNumChannels()); for(CHANNELINDEX chn = 0; chn < namedChans; chn++) { file.ReadString(ChnSettings[chn].szName, MAX_CHANNELNAME); } madeWith.set(verConfirmed); } // Read mix plugins information if(file.CanRead(8)) { FileReader::off_t oldPos = file.GetPosition(); LoadMixPlugins(file); if(file.GetPosition() != oldPos) { madeWith.set(verConfirmed); } } if(madeWith[verConfirmed]) { if(madeWith[verModPlug1_09]) { m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 09, 00, 00); m_madeWithTracker = MPT_USTRING("ModPlug Tracker 1.09"); } else if(madeWith[verNewModPlug]) { m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 16, 00, 00); m_madeWithTracker = MPT_USTRING("ModPlug Tracker 1.10 - 1.16"); } } if(!memcmp(fileHeader.trackerName, "OpenMPT ", 8)) { // Hey, I know this tracker! std::string mptVersion(fileHeader.trackerName + 8, 12); m_dwLastSavedWithVersion = MptVersion::ToNum(mptVersion); madeWith = verOpenMPT | verConfirmed; if(m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 22, 07, 19)) m_nMixLevels = mixLevelsCompatible; else m_nMixLevels = mixLevelsCompatibleFT2; } if(m_dwLastSavedWithVersion != 0 && !madeWith[verOpenMPT]) { m_nMixLevels = mixLevelsOriginal; m_playBehaviour.reset(); } if(madeWith[verFT2Generic]) { m_nMixLevels = mixLevelsCompatibleFT2; if(!hasMidiConfig) { // FT2 allows typing in arbitrary unsupported effect letters such as Zxx. // Prevent these commands from being interpreted as filter commands by erasing the default MIDI Config. m_MidiCfg.ClearZxxMacros(); } if(fileHeader.version >= 0x0104 // Old versions of FT2 didn't have (smooth) ramping. Disable it for those versions where we can be sure that there should be no ramping. #ifdef MODPLUG_TRACKER && TrackerSettings::Instance().autoApplySmoothFT2Ramping #endif // MODPLUG_TRACKER ) { // apply FT2-style super-soft volume ramping m_playBehaviour.set(kFT2VolumeRamping); } } if(m_madeWithTracker.empty()) { if(madeWith[verDigiTrakker] && sampleReserved == 0 && (instrType ? instrType : -1) == -1) { m_madeWithTracker = MPT_USTRING("DigiTrakker"); } else if(madeWith[verFT2Generic]) { m_madeWithTracker = MPT_USTRING("FastTracker 2 or compatible"); } else { m_madeWithTracker = MPT_USTRING("Unknown"); } } // Leave if no extra instrument settings are available (end of file reached) if(file.NoBytesLeft()) return true; bool interpretOpenMPTMade = false; // specific for OpenMPT 1.17+ (bMadeWithModPlug is also for MPT 1.16) if(GetNumInstruments()) { LoadExtendedInstrumentProperties(file, &interpretOpenMPTMade); } LoadExtendedSongProperties(file, &interpretOpenMPTMade); if(interpretOpenMPTMade && m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 17, 00, 00)) { // Up to OpenMPT 1.17.02.45 (r165), it was possible that the "last saved with" field was 0 // when saving a file in OpenMPT for the first time. m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 17, 00, 00); } if(m_dwLastSavedWithVersion >= MAKE_VERSION_NUMERIC(1, 17, 00, 00)) { m_madeWithTracker = MPT_USTRING("OpenMPT ") + MptVersion::ToUString(m_dwLastSavedWithVersion); } // We no longer allow any --- or +++ items in the order list now. if(m_dwLastSavedWithVersion && m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 22, 02, 02)) { if(!Patterns.IsValidPat(0xFE)) Order().RemovePattern(0xFE); if(!Patterns.IsValidPat(0xFF)) Order().Replace(0xFF, Order.GetInvalidPatIndex()); } return true; } #ifndef MODPLUG_NO_FILESAVE #define str_tooMuchPatternData ("Warning: File format limit was reached. Some pattern data may not get written to file.") #define str_pattern ("pattern") bool CSoundFile::SaveXM(const mpt::PathString &filename, bool compatibilityExport) { if(filename.empty()) { return false; } FILE *f = mpt_fopen(filename, "wb"); if(!f) { return false; } bool addChannel = false; // avoid odd channel count for FT2 compatibility XMFileHeader fileHeader; MemsetZero(fileHeader); memcpy(fileHeader.signature, "Extended Module: ", 17); mpt::String::Write(fileHeader.songName, m_songName); fileHeader.eof = 0x1A; const std::string openMptTrackerName = MptVersion::GetOpenMPTVersionStr(); mpt::String::Write(fileHeader.trackerName, openMptTrackerName); // Writing song header fileHeader.version = 0x0104; // XM Format v1.04 fileHeader.size = sizeof(XMFileHeader) - 60; // minus everything before this field fileHeader.restartPos = Order().GetRestartPos(); fileHeader.channels = m_nChannels; if((m_nChannels % 2u) && m_nChannels < 32) { // Avoid odd channel count for FT2 compatibility fileHeader.channels++; addChannel = true; } else if(compatibilityExport && fileHeader.channels > 32) { fileHeader.channels = 32; } // Find out number of orders and patterns used. // +++ and --- patterns are not taken into consideration as FastTracker does not support them. const ORDERINDEX trimmedLength = Order().GetLengthTailTrimmed(); std::vector orderList(trimmedLength); const ORDERINDEX orderLimit = compatibilityExport ? 256 : uint16_max; ORDERINDEX numOrders = 0; PATTERNINDEX numPatterns = Patterns.GetNumPatterns(); bool changeOrderList = false; for(ORDERINDEX ord = 0; ord < trimmedLength; ord++) { PATTERNINDEX pat = Order()[ord]; if(pat == Order.GetIgnoreIndex() || pat == Order.GetInvalidPatIndex() || pat > uint8_max) { changeOrderList = true; } else if(numOrders < orderLimit) { orderList[numOrders++] = static_cast(pat); if(pat >= numPatterns) numPatterns = pat + 1; } } if(changeOrderList) { AddToLog("Skip and stop order list items (+++ and ---) are not saved in XM files."); } orderList.resize(compatibilityExport ? 256 : numOrders); fileHeader.orders = numOrders; fileHeader.patterns = numPatterns; fileHeader.size += static_cast(orderList.size()); uint16 writeInstruments; if(m_nInstruments > 0) fileHeader.instruments = writeInstruments = m_nInstruments; else fileHeader.instruments = writeInstruments = m_nSamples; if(m_SongFlags[SONG_LINEARSLIDES]) fileHeader.flags |= XMFileHeader::linearSlides; if(m_SongFlags[SONG_EXFILTERRANGE] && !compatibilityExport) fileHeader.flags |= XMFileHeader::extendedFilterRange; fileHeader.flags = fileHeader.flags; // Fasttracker 2 will happily accept any tempo faster than 255 BPM. XMPlay does also support this, great! fileHeader.tempo = mpt::saturate_cast(m_nDefaultTempo.GetInt()); fileHeader.speed = static_cast(Clamp(m_nDefaultSpeed, 1u, 31u)); mpt::IO::Write(f, fileHeader); // Write processed order list mpt::IO::WriteRaw(f, orderList.data(), orderList.size()); // Writing patterns #define ASSERT_CAN_WRITE(x) \ if(len > s.size() - x) /*Buffer running out? Make it larger.*/ \ s.resize(s.size() + 10 * 1024, 0); std::vector s(64 * 64 * 5, 0); for(PATTERNINDEX pat = 0; pat < numPatterns; pat++) { uint8 patHead[9] = { 0 }; patHead[0] = 9; if(!Patterns.IsValidPat(pat)) { // There's nothing to write... chicken out. patHead[5] = 64; mpt::IO::Write(f, patHead); continue; } const uint16 numRows = mpt::saturate_cast(Patterns[pat].GetNumRows()); patHead[5] = static_cast(numRows & 0xFF); patHead[6] = static_cast(numRows >> 8); auto p = Patterns[pat].cbegin(); size_t len = 0; // Empty patterns are always loaded as 64-row patterns in FT2, regardless of their real size... bool emptyPattern = true; for(size_t j = m_nChannels * numRows; j > 0; j--, p++) { // Don't write more than 32 channels if(compatibilityExport && m_nChannels - ((j - 1) % m_nChannels) > 32) continue; uint8 note = p->note; uint8 command = p->command, param = p->param; ModSaveCommand(command, param, true, compatibilityExport); if (note >= NOTE_MIN_SPECIAL) note = 97; else if ((note <= 12) || (note > 96+12)) note = 0; else note -= 12; uint8 vol = 0; if (p->volcmd != VOLCMD_NONE) { switch(p->volcmd) { case VOLCMD_VOLUME: vol = 0x10 + p->vol; break; case VOLCMD_VOLSLIDEDOWN: vol = 0x60 + (p->vol & 0x0F); break; case VOLCMD_VOLSLIDEUP: vol = 0x70 + (p->vol & 0x0F); break; case VOLCMD_FINEVOLDOWN: vol = 0x80 + (p->vol & 0x0F); break; case VOLCMD_FINEVOLUP: vol = 0x90 + (p->vol & 0x0F); break; case VOLCMD_VIBRATOSPEED: vol = 0xA0 + (p->vol & 0x0F); break; case VOLCMD_VIBRATODEPTH: vol = 0xB0 + (p->vol & 0x0F); break; case VOLCMD_PANNING: vol = 0xC0 + (p->vol / 4); if (vol > 0xCF) vol = 0xCF; break; case VOLCMD_PANSLIDELEFT: vol = 0xD0 + (p->vol & 0x0F); break; case VOLCMD_PANSLIDERIGHT: vol = 0xE0 + (p->vol & 0x0F); break; case VOLCMD_TONEPORTAMENTO: vol = 0xF0 + (p->vol & 0x0F); break; } // Those values are ignored in FT2. Don't save them, also to avoid possible problems with other trackers (or MPT itself) if(compatibilityExport && p->vol == 0) { switch(p->volcmd) { case VOLCMD_VOLUME: case VOLCMD_PANNING: case VOLCMD_VIBRATODEPTH: case VOLCMD_TONEPORTAMENTO: case VOLCMD_PANSLIDELEFT: // Doesn't have memory, but does weird things with zero param. break; default: // no memory here. vol = 0; } } } // no need to fix non-empty patterns if(!p->IsEmpty()) emptyPattern = false; // Apparently, completely empty patterns are loaded as empty 64-row patterns in FT2, regardless of their original size. // We have to avoid this, so we add a "break to row 0" command in the last row. if(j == 1 && emptyPattern && numRows != 64) { command = 0x0D; param = 0; } if ((note) && (p->instr) && (vol > 0x0F) && (command) && (param)) { s[len++] = note; s[len++] = p->instr; s[len++] = vol; s[len++] = command; s[len++] = param; } else { uint8 b = 0x80; if (note) b |= 0x01; if (p->instr) b |= 0x02; if (vol >= 0x10) b |= 0x04; if (command) b |= 0x08; if (param) b |= 0x10; s[len++] = b; if (b & 1) s[len++] = note; if (b & 2) s[len++] = p->instr; if (b & 4) s[len++] = vol; if (b & 8) s[len++] = command; if (b & 16) s[len++] = param; } if(addChannel && (j % m_nChannels == 1 || m_nChannels == 1)) { ASSERT_CAN_WRITE(1); s[len++] = 0x80; } ASSERT_CAN_WRITE(5); } if(emptyPattern && numRows == 64) { // Be smart when saving empty patterns! len = 0; } // Reaching the limits of file format? if(len > uint16_max) { AddToLog(mpt::format("%1 (%2 %3)")(str_tooMuchPatternData, str_pattern, pat)); len = uint16_max; } patHead[7] = static_cast(len & 0xFF); patHead[8] = static_cast(len >> 8); mpt::IO::Write(f, patHead); if(len) mpt::IO::WriteRaw(f, s.data(), len); } #undef ASSERT_CAN_WRITE // Check which samples are referenced by which instruments (for assigning unreferenced samples to instruments) std::vector sampleAssigned(GetNumSamples() + 1, false); for(INSTRUMENTINDEX ins = 1; ins <= GetNumInstruments(); ins++) { if(Instruments[ins] != nullptr) { Instruments[ins]->GetSamples(sampleAssigned); } } // Writing instruments for(INSTRUMENTINDEX ins = 1; ins <= writeInstruments; ins++) { XMInstrumentHeader insHeader; std::vector samples; if(GetNumInstruments()) { if(Instruments[ins] != nullptr) { // Convert instrument insHeader.ConvertToXM(*Instruments[ins], compatibilityExport); samples = insHeader.instrument.GetSampleList(*Instruments[ins], compatibilityExport); if(samples.size() > 0 && samples[0] <= GetNumSamples()) { // Copy over auto-vibrato settings of first sample insHeader.instrument.ApplyAutoVibratoToXM(Samples[samples[0]], GetType()); } std::vector additionalSamples; // Try to save "instrument-less" samples as well by adding those after the "normal" samples of our sample. // We look for unassigned samples directly after the samples assigned to our current instrument, so if // e.g. sample 1 is assigned to instrument 1 and samples 2 to 10 aren't assigned to any instrument, // we will assign those to sample 1. Any samples before the first referenced sample are going to be lost, // but hey, I wrote this mostly for preserving instrument texts in existing modules, where we shouldn't encounter this situation... for(auto smp : samples) { while(++smp <= GetNumSamples() && !sampleAssigned[smp] && insHeader.numSamples < (compatibilityExport ? 16 : 32)) { sampleAssigned[smp] = true; // Don't want to add this sample again. additionalSamples.push_back(smp); insHeader.numSamples++; } } samples.insert(samples.end(), additionalSamples.begin(), additionalSamples.end()); } else { MemsetZero(insHeader); } } else { // Convert samples to instruments MemsetZero(insHeader); insHeader.numSamples = 1; insHeader.instrument.ApplyAutoVibratoToXM(Samples[ins], GetType()); samples.push_back(ins); } insHeader.Finalise(); size_t insHeaderSize = insHeader.size; mpt::IO::WritePartial(f, insHeader, insHeaderSize); std::vector sampleFlags(samples.size()); // Write Sample Headers for(SAMPLEINDEX smp = 0; smp < samples.size(); smp++) { XMSample xmSample; if(samples[smp] <= GetNumSamples()) { xmSample.ConvertToXM(Samples[samples[smp]], GetType(), compatibilityExport); } else { MemsetZero(xmSample); } sampleFlags[smp] = xmSample.GetSampleFormat(); mpt::String::Write(xmSample.name, m_szNames[samples[smp]]); mpt::IO::Write(f, xmSample); } // Write Sample Data for(SAMPLEINDEX smp = 0; smp < samples.size(); smp++) { if(samples[smp] <= GetNumSamples()) { sampleFlags[smp].WriteSample(f, Samples[samples[smp]]); } } } if(!compatibilityExport) { // Writing song comments if(!m_songMessage.empty()) { uint32 size = mpt::saturate_cast(m_songMessage.length()); mpt::IO::WriteRaw(f, "text", 4); mpt::IO::WriteIntLE(f, size); mpt::IO::WriteRaw(f, m_songMessage.c_str(), size); } // Writing midi cfg if(!m_MidiCfg.IsMacroDefaultSetupUsed()) { mpt::IO::WriteRaw(f, "MIDI", 4); mpt::IO::WriteIntLE(f, sizeof(MIDIMacroConfigData)); mpt::IO::Write(f, static_cast(m_MidiCfg)); } // Writing Pattern Names const PATTERNINDEX numNamedPats = Patterns.GetNumNamedPatterns(); if(numNamedPats > 0) { mpt::IO::WriteRaw(f, "PNAM", 4); mpt::IO::WriteIntLE(f, numNamedPats * MAX_PATTERNNAME); for(PATTERNINDEX pat = 0; pat < numNamedPats; pat++) { char name[MAX_PATTERNNAME]; mpt::String::Write(name, Patterns[pat].GetName()); mpt::IO::Write(f, name); } } // Writing Channel Names { CHANNELINDEX numNamedChannels = 0; for(CHANNELINDEX chn = 0; chn < m_nChannels; chn++) { if (ChnSettings[chn].szName[0]) numNamedChannels = chn + 1; } // Do it! if(numNamedChannels) { mpt::IO::WriteRaw(f, "CNAM", 4); mpt::IO::WriteIntLE(f, numNamedChannels * MAX_CHANNELNAME); for(CHANNELINDEX chn = 0; chn < numNamedChannels; chn++) { char name[MAX_CHANNELNAME]; mpt::String::Write(name, ChnSettings[chn].szName); mpt::IO::Write(f, name); } } } //Save hacked-on extra info SaveMixPlugins(f); if(GetNumInstruments()) { SaveExtendedInstrumentProperties(writeInstruments, f); } SaveExtendedSongProperties(f); } fclose(f); return true; } #endif // MODPLUG_NO_FILESAVE OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/ITCompression.cpp0000644000372100037210000002621313212507211021335 00000000000000/* * ITCompression.cpp * ----------------- * Purpose: Code for IT sample compression and decompression. * Notes : The original Python compression code was written by GreaseMonkey and has been released into the public domain. * Authors: OpenMPT Devs * Ben "GreaseMonkey" Russell * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include #include "ITCompression.h" #include "../common/misc_util.h" #include "../common/mptIO.h" #include "ModSample.h" OPENMPT_NAMESPACE_BEGIN // Algorithm parameters for 16-Bit samples struct IT16BitParams { typedef int16 sample_t; static const int16 lowerTab[]; static const int16 upperTab[]; static const int8 fetchA = 4, lowerB = -8, upperB = 7, defWidth = 17; static const int mask = 0xFFFF; }; const int16 IT16BitParams::lowerTab[] = { 0, -1, -3, -7, -15, -31, -56, -120, -248, -504, -1016, -2040, -4088, -8184, -16376, -32760, -32768 }; const int16 IT16BitParams::upperTab[] = { 0, 1, 3, 7, 15, 31, 55, 119, 247, 503, 1015, 2039, 4087, 8183, 16375, 32759, 32767 }; // Algorithm parameters for 8-Bit samples struct IT8BitParams { typedef int8 sample_t; static const int8 lowerTab[]; static const int8 upperTab[]; static const int8 fetchA = 3, lowerB = -4, upperB = 3, defWidth = 9; static const int mask = 0xFF; }; const int8 IT8BitParams::lowerTab[] = { 0, -1, -3, -7, -15, -31, -60, -124, -128 }; const int8 IT8BitParams::upperTab[] = { 0, 1, 3, 7, 15, 31, 59, 123, 127 }; static const int8 ITWidthChangeSize[] = { 4, 5, 6, 7, 8, 9, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; ////////////////////////////////////////////////////////////////////////////// // IT 2.14 compression ITCompression::ITCompression(const ModSample &sample, bool it215, std::ostream *f, SmpLength maxLength) : file(f) , mptSample(sample) , is215(it215) { packedData = new (std::nothrow) uint8[bufferSize]; sampleData = new (std::nothrow) uint8[blockSize]; packedTotalLength = 0; if(packedData == nullptr || sampleData == nullptr) { return; } if(maxLength == 0 || maxLength > mptSample.nLength) maxLength = mptSample.nLength; for(uint8 chn = 0; chn < mptSample.GetNumChannels(); chn++) { SmpLength offset = 0; SmpLength remain = maxLength; while(remain > 0) { // Initialise output buffer and bit writer positions packedLength = 2; bitPos = 0; remBits = 8; byteVal = 0; if(mptSample.GetElementarySampleSize() > 1) Compress(sample.pSample16 + chn, offset, remain); else Compress(sample.pSample8 + chn, offset, remain); if(file) mpt::IO::WriteRaw(*file, packedData, packedLength); packedTotalLength += packedLength; offset += baseLength; remain -= baseLength; } } delete[] packedData; delete[] reinterpret_cast(sampleData); } template void ITCompression::CopySample(void *target, const void *source, SmpLength offset, SmpLength length, SmpLength skip) { T *out = static_cast(target); const T *in = static_cast(source) + offset * skip; for(SmpLength i = 0, j = 0; j < length; i += skip, j++) { out[j] = in[i]; } } // Convert sample to delta values. template void ITCompression::Deltafy() { T *p = static_cast(sampleData); int oldVal = 0; for(SmpLength i = 0; i < baseLength; i++) { int newVal = p[i]; p[i] = static_cast(newVal - oldVal); oldVal = newVal; } } template void ITCompression::Compress(const void *data, SmpLength offset, SmpLength actualLength) { baseLength = std::min(actualLength, SmpLength(blockSize / sizeof(typename Properties::sample_t))); CopySample(sampleData, data, offset, baseLength, mptSample.GetNumChannels()); Deltafy(); if(is215) { Deltafy(); } const int8 defWidth = Properties::defWidth; // gcc static const member reference workaround // Initialise bit width table with initial values bwt.assign(baseLength, defWidth); // Recurse! SquishRecurse(defWidth, defWidth, defWidth, defWidth - 2, 0, baseLength); // Write those bits! const typename Properties::sample_t *p = static_cast(sampleData); int8 width = defWidth; for(size_t i = 0; i < baseLength; i++) { if(bwt[i] != width) { if(width <= 6) { // Mode A: 1 to 6 bits MPT_ASSERT(width); WriteBits(width, (1 << (width - 1))); WriteBits(Properties::fetchA, ConvertWidth(width, bwt[i])); } else if(width < defWidth) { // Mode B: 7 to 8 / 16 bits int xv = (1 << (width - 1)) + Properties::lowerB + ConvertWidth(width, bwt[i]); WriteBits(width, xv); } else { // Mode C: 9 / 17 bits MPT_ASSERT((bwt[i] - 1) >= 0); WriteBits(width, (1 << (width - 1)) + bwt[i] - 1); } width = bwt[i]; } WriteBits(width, static_cast(p[i]) & Properties::mask); } // Write last byte and update block length WriteByte(byteVal); packedData[0] = static_cast((packedLength - 2) & 0xFF); packedData[1] = static_cast((packedLength - 2) >> 8); } int8 ITCompression::GetWidthChangeSize(int8 w, bool is16) { MPT_ASSERT(w > 0 && static_cast(w) <= CountOf(ITWidthChangeSize)); int8 wcs = ITWidthChangeSize[w - 1]; if(w <= 6 && is16) wcs++; return wcs; } template void ITCompression::SquishRecurse(int8 sWidth, int8 lWidth, int8 rWidth, int8 width, SmpLength offset, SmpLength length) { if(width + 1 < 1) { for(SmpLength i = offset; i < offset + length; i++) bwt[i] = sWidth; return; } MPT_ASSERT(width >= 0 && static_cast(width) < CountOf(Properties::lowerTab)); SmpLength i = offset; SmpLength end = offset + length; const typename Properties::sample_t *p = static_cast(sampleData); while(i < end) { if(p[i] >= Properties::lowerTab[width] && p[i] <= Properties::upperTab[width]) { SmpLength start = i; // Check for how long we can keep this bit width while(i < end && p[i] >= Properties::lowerTab[width] && p[i] <= Properties::upperTab[width]) { i++; } const SmpLength blockLength = i - start; const int8 xlwidth = start == offset ? lWidth : sWidth; const int8 xrwidth = i == end ? rWidth : sWidth; const bool is16 = sizeof(typename Properties::sample_t) > 1; const int8 wcsl = GetWidthChangeSize(xlwidth, is16); const int8 wcss = GetWidthChangeSize(sWidth, is16); const int8 wcsw = GetWidthChangeSize(width + 1, is16); bool comparison; if(i == baseLength) { SmpLength keepDown = wcsl + (width + 1) * blockLength; SmpLength levelLeft = wcsl + sWidth * blockLength; if(xlwidth == sWidth) levelLeft -= wcsl; comparison = (keepDown <= levelLeft); } else { SmpLength keepDown = wcsl + (width + 1) * blockLength + wcsw; SmpLength levelLeft = wcsl + sWidth * blockLength + wcss; if(xlwidth == sWidth) levelLeft -= wcsl; if(xrwidth == sWidth) levelLeft -= wcss; comparison = (keepDown <= levelLeft); } SquishRecurse(comparison ? (width + 1) : sWidth, xlwidth, xrwidth, width - 1, start, blockLength); } else { bwt[i] = sWidth; i++; } } } int8 ITCompression::ConvertWidth(int8 curWidth, int8 newWidth) { curWidth--; newWidth--; MPT_ASSERT(newWidth != curWidth); if(newWidth > curWidth) newWidth--; return newWidth; } void ITCompression::WriteBits(int8 width, int v) { while(width > remBits) { byteVal |= (v << bitPos); width -= remBits; v >>= remBits; bitPos = 0; remBits = 8; WriteByte(byteVal); byteVal = 0; } if(width > 0) { byteVal |= (v & ((1 << width) - 1)) << bitPos; remBits -= width; bitPos += width; } } void ITCompression::WriteByte(uint8 v) { if(packedLength < bufferSize) { packedData[packedLength++] = v; } else { // How could this happen, anyway? MPT_ASSERT_NOTREACHED(); } } ////////////////////////////////////////////////////////////////////////////// // IT 2.14 decompression ITDecompression::ITDecompression(FileReader &file, ModSample &sample, bool it215) : mptSample(sample) , is215(it215) { for(uint8 chn = 0; chn < mptSample.GetNumChannels(); chn++) { writtenSamples = writePos = 0; while(writtenSamples < sample.nLength && file.CanRead(sizeof(uint16))) { dataSize = file.ReadUint16LE(); if(!dataSize) continue; // Malformed sample? file.ReadRaw(chunk, dataSize); // Initialise bit reader dataPos = 0; bitPos = 0; remBits = 8; mem1 = mem2 = 0; if(mptSample.GetElementarySampleSize() > 1) Uncompress(mptSample.pSample16 + chn); else Uncompress(mptSample.pSample8 + chn); } } } template void ITDecompression::Uncompress(typename Properties::sample_t *target) { curLength = std::min(mptSample.nLength - writtenSamples, SmpLength(ITCompression::blockSize / sizeof(typename Properties::sample_t))); const int defWidth = Properties::defWidth; // gcc static const member reference workaround int width = defWidth; while(curLength > 0) { if(width < 1 || width > defWidth || dataPos >= dataSize) { // Error! return; } int v = ReadBits(width); const int topBit = (1 << (width - 1)); if(width <= 6) { // Mode A: 1 to 6 bits if(v == topBit) ChangeWidth(width, ReadBits(Properties::fetchA)); else Write(v, topBit, target); } else if(width < defWidth) { // Mode B: 7 to 8 / 16 bits if(v >= topBit + Properties::lowerB && v <= topBit + Properties::upperB) ChangeWidth(width, v - (topBit + Properties::lowerB)); else Write(v, topBit, target); } else { // Mode C: 9 / 17 bits if(v & topBit) width = (v & ~topBit) + 1; else Write((v & ~topBit), 0, target); } } } #if MPT_MSVC_AT_LEAST(2017,3) && MPT_MSVC_BEFORE(2017,5) // Work-around compiler crash in VS2017.3 / cl 19.11.25506 // https://developercommunity.visualstudio.com/content/problem/96687/c1063-and-c1001-while-compiling-trivial-code-in-vs.html MPT_NOINLINE #endif void ITDecompression::ChangeWidth(int &curWidth, int width) { width++; if(width >= curWidth) width++; curWidth = width; } #if MPT_MSVC_AT_LEAST(2017,3) && MPT_MSVC_BEFORE(2017,5) // Work-around compiler crash in VS2017.3 / cl 19.11.25506 // https://developercommunity.visualstudio.com/content/problem/96687/c1063-and-c1001-while-compiling-trivial-code-in-vs.html MPT_NOINLINE #endif int ITDecompression::ReadBits(int width) { int v = 0, vPos = 0, vMask = (1 << width) - 1; while(width >= remBits && dataPos < dataSize) { v |= (chunk[dataPos] >> bitPos) << vPos; vPos += remBits; width -= remBits; dataPos++; remBits = 8; bitPos = 0; } if(width > 0 && dataPos < dataSize) { v |= (chunk[dataPos] >> bitPos) << vPos; v &= vMask; remBits -= width; bitPos += width; } return v; } template void ITDecompression::Write(int v, int topBit, typename Properties::sample_t *target) { if(v & topBit) v -= (topBit << 1); mem1 += v; mem2 += mem1; target[writePos] = static_cast(static_cast(is215 ? mem2 : mem1)); writtenSamples++; writePos += mptSample.GetNumChannels(); curLength--; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/MIDIEvents.h0000644000372100037210000001207412654745734020202 00000000000000/* * MIDIEvents.h * ------------ * Purpose: MIDI event handling, event lists, ... * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once OPENMPT_NAMESPACE_BEGIN // MIDI related enums and helper functions namespace MIDIEvents { // MIDI Event Types enum EventType { evNoteOff = 0x8, // Note Off event evNoteOn = 0x9, // Note On event evPolyAftertouch = 0xA, // Poly Aftertouch / Poly Pressure event evControllerChange = 0xB, // Controller Change (see MidiCC enum) evProgramChange = 0xC, // Program Change evChannelAftertouch = 0xD, // Channel Aftertouch evPitchBend = 0xE, // Pitchbend event (see PitchBend enum) evSystem = 0xF, // System event (see SystemEvent enum) }; // System Events (Fx ...) enum SystemEvent { sysExStart = 0x0, // Begin of System Exclusive message sysQuarterFrame = 0x1, // Quarter Frame Message sysPositionPointer = 0x2, // Song Position Pointer sysSongSelect = 0x3, // Song Select sysTuneRequest = 0x6, // Tune Request sysExEnd = 0x7, // End of System Exclusive message sysMIDIClock = 0x8, // MIDI Clock event sysMIDITick = 0x9, // MIDI Tick event sysStart = 0xA, // Start Song sysContinue = 0xB, // Continue Song sysStop = 0xC, // Stop Song sysActiveSense = 0xE, // Active Sense Message sysReset = 0xF, // Reset Device }; // MIDI Pitchbend Constants enum PitchBend { pitchBendMin = 0x00, pitchBendCentre = 0x2000, pitchBendMax = 0x3FFF }; // MIDI Continuous Controller Codes // http://home.roadrunner.com/~jgglatt/tech/midispec/ctllist.htm enum MidiCC { MIDICC_start = 0, MIDICC_BankSelect_Coarse = MIDICC_start, MIDICC_ModulationWheel_Coarse = 1, MIDICC_Breathcontroller_Coarse = 2, MIDICC_FootPedal_Coarse = 4, MIDICC_PortamentoTime_Coarse = 5, MIDICC_DataEntry_Coarse = 6, MIDICC_Volume_Coarse = 7, MIDICC_Balance_Coarse = 8, MIDICC_Panposition_Coarse = 10, MIDICC_Expression_Coarse = 11, MIDICC_EffectControl1_Coarse = 12, MIDICC_EffectControl2_Coarse = 13, MIDICC_GeneralPurposeSlider1 = 16, MIDICC_GeneralPurposeSlider2 = 17, MIDICC_GeneralPurposeSlider3 = 18, MIDICC_GeneralPurposeSlider4 = 19, MIDICC_BankSelect_Fine = 32, MIDICC_ModulationWheel_Fine = 33, MIDICC_Breathcontroller_Fine = 34, MIDICC_FootPedal_Fine = 36, MIDICC_PortamentoTime_Fine = 37, MIDICC_DataEntry_Fine = 38, MIDICC_Volume_Fine = 39, MIDICC_Balance_Fine = 40, MIDICC_Panposition_Fine = 42, MIDICC_Expression_Fine = 43, MIDICC_EffectControl1_Fine = 44, MIDICC_EffectControl2_Fine = 45, MIDICC_HoldPedal_OnOff = 64, MIDICC_Portamento_OnOff = 65, MIDICC_SustenutoPedal_OnOff = 66, MIDICC_SoftPedal_OnOff = 67, MIDICC_LegatoPedal_OnOff = 68, MIDICC_Hold2Pedal_OnOff = 69, MIDICC_SoundVariation = 70, MIDICC_SoundTimbre = 71, MIDICC_SoundReleaseTime = 72, MIDICC_SoundAttackTime = 73, MIDICC_SoundBrightness = 74, MIDICC_SoundControl6 = 75, MIDICC_SoundControl7 = 76, MIDICC_SoundControl8 = 77, MIDICC_SoundControl9 = 78, MIDICC_SoundControl10 = 79, MIDICC_GeneralPurposeButton1_OnOff = 80, MIDICC_GeneralPurposeButton2_OnOff = 81, MIDICC_GeneralPurposeButton3_OnOff = 82, MIDICC_GeneralPurposeButton4_OnOff = 83, MIDICC_EffectsLevel = 91, MIDICC_TremoloLevel = 92, MIDICC_ChorusLevel = 93, MIDICC_CelesteLevel = 94, MIDICC_PhaserLevel = 95, MIDICC_DataButtonincrement = 96, MIDICC_DataButtondecrement = 97, MIDICC_NonRegisteredParameter_Fine = 98, MIDICC_NonRegisteredParameter_Coarse = 99, MIDICC_RegisteredParameter_Fine = 100, MIDICC_RegisteredParameter_Coarse = 101, MIDICC_AllSoundOff = 120, MIDICC_AllControllersOff = 121, MIDICC_LocalKeyboard_OnOff = 122, MIDICC_AllNotesOff = 123, MIDICC_OmniModeOff = 124, MIDICC_OmniModeOn = 125, MIDICC_MonoOperation = 126, MIDICC_PolyOperation = 127, MIDICC_end = MIDICC_PolyOperation, }; // MIDI CC Names extern const char* const MidiCCNames[MIDICC_end + 1]; // Build a generic MIDI event uint32 Event(EventType eventType, uint8 midiChannel, uint8 dataByte1, uint8 dataByte2); // Build a MIDI CC event uint32 CC(MidiCC midiCC, uint8 midiChannel, uint8 param); // Build a MIDI Pitchbend event uint32 PitchBend(uint8 midiChannel, uint16 bendAmount); // Build a MIDI Program Change event uint32 ProgramChange(uint8 midiChannel, uint8 program); // Build a MIDI Note Off event uint32 NoteOff(uint8 midiChannel, uint8 note, uint8 velocity); // Build a MIDI Note On event uint32 NoteOn(uint8 midiChannel, uint8 note, uint8 velocity); // Build a MIDI System Event uint8 System(SystemEvent eventType); // Get MIDI channel from a MIDI event uint8 GetChannelFromEvent(uint32 midiMsg); // Get MIDI Event type from a MIDI event EventType GetTypeFromEvent(uint32 midiMsg); // Get first data byte from a MIDI event uint8 GetDataByte1FromEvent(uint32 midiMsg); // Get second data byte from a MIDI event uint8 GetDataByte2FromEvent(uint32 midiMsg); // Get the length of a MIDI event in bytes uint8 GetEventLength(uint8 firstByte); } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Message.h0000644000372100037210000000510313161656666017651 00000000000000/* * Message.h * --------- * Purpose: Various functions for processing song messages (allocating, reading from file...) * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include #include "../common/FileReaderFwd.h" OPENMPT_NAMESPACE_BEGIN class SongMessage : public std::string { public: // Line ending types (for reading song messages from module files) enum LineEnding { leCR, // Carriage Return (0x0D, \r) leLF, // Line Feed (0x0A \n) leCRLF, // Carriage Return, Line Feed (0x0D0A, \r\n) leMixed, // It is not defined whether Carriage Return or Line Feed is the actual line ending. Both are accepted. leAutodetect, // Detect suitable line ending }; enum { InternalLineEnding = '\r', // The character that represents line endings internally }; // Read song message from a mapped file. // [in] data: pointer to the data in memory that is going to be read // [in] length: number of characters that should be read, not including a possible trailing null terminator (it is automatically appended). // [in] lineEnding: line ending formatting of the text in memory. // [out] returns true on success. bool Read(const mpt::byte *data, const size_t length, LineEnding lineEnding); bool Read(FileReader &file, const size_t length, LineEnding lineEnding); // Read comments with fixed line length from a mapped file. // [in] data: pointer to the data in memory that is going to be read // [in] length: number of characters that should be read, not including a possible trailing null terminator (it is automatically appended). // [in] lineLength: The fixed length of a line. // [in] lineEndingLength: The padding space between two fixed lines. (there could for example be a null char after every line) // [out] returns true on success. bool ReadFixedLineLength(const mpt::byte *data, const size_t length, const size_t lineLength, const size_t lineEndingLength); bool ReadFixedLineLength(FileReader &file, const size_t length, const size_t lineLength, const size_t lineEndingLength); // Retrieve song message. // [in] lineEnding: line ending formatting of the text in memory. // [out] returns formatted song message. std::string GetFormatted(const LineEnding lineEnding) const; // Set song message. // [in] lineEnding: line ending formatting of the text in memory. Must be leCR or leLF or leCRLF, // [out] returns true if the message has been changed. bool SetFormatted(std::string message, LineEnding lineEnding); }; OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/tuningbase.h0000644000372100037210000000361613135157006020414 00000000000000/* * tuningbase.h * ------------ * Purpose: Alternative sample tuning. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include #include "../common/typedefs.h" OPENMPT_NAMESPACE_BEGIN namespace Tuning { enum class SerializationResult : int { Success = 1, NoMagic = 0, Failure = -1 }; //NOTEINDEXTYPE: Some signed integer-type. //UNOTEINDEXTYPE: Unsigned NOTEINDEXTYPE //RATIOTYPE: Some 'real figure' type able to present ratios. //STEPINDEXTYPE: Counter of steps between notes. If there is no 'finetune'(finestepcount == 0), //then 'step difference' between notes is the //same as differences in NOTEINDEXTYPE. In a way similar to ticks and rows in pattern - //ticks <-> STEPINDEX, rows <-> NOTEINDEX typedef int16 NOTEINDEXTYPE; typedef uint16 UNOTEINDEXTYPE; typedef float32 RATIOTYPE; //If changing RATIOTYPE, serialization methods may need modifications. typedef int32 STEPINDEXTYPE; typedef uint32 USTEPINDEXTYPE; typedef std::pair VRPAIR; typedef uint16 TUNINGTYPE; // Derived from old IsStepCountRangeSufficient(), this is actually a more // sensible value than what was calculated in earlier versions. static MPT_CONSTEXPR11_VAR STEPINDEXTYPE FINESTEPCOUNT_MAX = 0xffff; #define NOTEINDEXTYPE_MIN (std::numeric_limits::min)() #define NOTEINDEXTYPE_MAX (std::numeric_limits::max)() #define UNOTEINDEXTYPE_MAX (std::numeric_limits::max)() #define STEPINDEXTYPE_MIN (std::numeric_limits::min)() #define STEPINDEXTYPE_MAX (std::numeric_limits::max)() #define USTEPINDEXTYPE_MAX (std::numeric_limits::max)() class CTuningRTI; typedef CTuningRTI CTuning; } // namespace Tuning typedef Tuning::CTuning CTuning; OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Load_dbm.cpp0000644000372100037210000004414513161656666020332 00000000000000/* * Load_dbm.cpp * ------------ * Purpose: DigiBooster Pro module Loader (DBM) * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" #include "ChunkReader.h" #include "../common/StringFixer.h" #ifndef NO_PLUGINS #include "plugins/DigiBoosterEcho.h" #endif // NO_PLUGINS #ifdef LIBOPENMPT_BUILD #define MPT_DBM_USE_REAL_SUBSONGS #endif OPENMPT_NAMESPACE_BEGIN struct DBMFileHeader { char dbm0[4]; uint8 trkVerHi; uint8 trkVerLo; char reserved[2]; }; MPT_BINARY_STRUCT(DBMFileHeader, 8) // IFF-style Chunk struct DBMChunk { // 32-Bit chunk identifiers enum ChunkIdentifiers { idNAME = MAGIC4BE('N','A','M','E'), idINFO = MAGIC4BE('I','N','F','O'), idSONG = MAGIC4BE('S','O','N','G'), idINST = MAGIC4BE('I','N','S','T'), idVENV = MAGIC4BE('V','E','N','V'), idPENV = MAGIC4BE('P','E','N','V'), idPATT = MAGIC4BE('P','A','T','T'), idPNAM = MAGIC4BE('P','N','A','M'), idSMPL = MAGIC4BE('S','M','P','L'), idDSPE = MAGIC4BE('D','S','P','E'), idMPEG = MAGIC4BE('M','P','E','G'), }; uint32be id; uint32be length; size_t GetLength() const { return length; } ChunkIdentifiers GetID() const { return static_cast(id.get()); } }; MPT_BINARY_STRUCT(DBMChunk, 8) struct DBMInfoChunk { uint16be instruments; uint16be samples; uint16be songs; uint16be patterns; uint16be channels; }; MPT_BINARY_STRUCT(DBMInfoChunk, 10) // Instrument header struct DBMInstrument { enum DBMInstrFlags { smpLoop = 0x01, smpPingPongLoop = 0x02, }; char name[30]; uint16be sample; // Sample reference uint16be volume; // 0...64 uint32be sampleRate; uint32be loopStart; uint32be loopLength; int16be panning; // -128...128 uint16be flags; // See DBMInstrFlags }; MPT_BINARY_STRUCT(DBMInstrument, 50) // Volume or panning envelope struct DBMEnvelope { enum DBMEnvelopeFlags { envEnabled = 0x01, envSustain = 0x02, envLoop = 0x04, }; uint16be instrument; uint8be flags; // See DBMEnvelopeFlags uint8be numSegments; // Number of envelope points - 1 uint8be sustain1; uint8be loopBegin; uint8be loopEnd; uint8be sustain2; // Second sustain point uint16be data[2 * 32]; }; MPT_BINARY_STRUCT(DBMEnvelope, 136) // Note: Unlike in MOD, 1Fx, 2Fx, 5Fx / 5xF, 6Fx / 6xF and AFx / AxF are fine slides. static const ModCommand::COMMAND dbmEffects[] = { CMD_ARPEGGIO, CMD_PORTAMENTOUP, CMD_PORTAMENTODOWN, CMD_TONEPORTAMENTO, CMD_VIBRATO, CMD_TONEPORTAVOL, CMD_VIBRATOVOL, CMD_TREMOLO, CMD_PANNING8, CMD_OFFSET, CMD_VOLUMESLIDE, CMD_POSITIONJUMP, CMD_VOLUME, CMD_PATTERNBREAK, CMD_MODCMDEX, CMD_TEMPO, CMD_GLOBALVOLUME, CMD_GLOBALVOLSLIDE, CMD_KEYOFF, CMD_SETENVPOSITION, CMD_CHANNELVOLUME, CMD_CHANNELVOLSLIDE, CMD_NONE, CMD_NONE, CMD_NONE, CMD_PANNINGSLIDE, CMD_NONE, CMD_NONE, CMD_NONE, CMD_NONE, CMD_NONE, #ifndef NO_PLUGINS CMD_DBMECHO, // Toggle DSP CMD_MIDI, // Wxx Echo Delay CMD_MIDI, // Xxx Echo Feedback CMD_MIDI, // Yxx Echo Mix CMD_MIDI, // Zxx Echo Cross #endif // NO_PLUGINS }; static void ConvertDBMEffect(uint8 &command, uint8 ¶m) { uint8 oldCmd = command; if(command < CountOf(dbmEffects)) command = dbmEffects[command]; else command = CMD_NONE; switch(command) { case CMD_ARPEGGIO: if(param == 0) command = CMD_NONE; break; #ifdef MODPLUG_TRACKER case CMD_VIBRATO: if(param & 0x0F) { // DBM vibrato is half as deep as most other trackers. Convert it to IT fine vibrato range if possible. uint8 depth = (param & 0x0F) * 2u; param &= 0xF0; if(depth < 16) command = CMD_FINEVIBRATO; else depth = (depth + 2u) / 4u; param |= depth; } break; #endif // Volume slide nibble priority - first nibble (slide up) has precedence. case CMD_VOLUMESLIDE: case CMD_TONEPORTAVOL: case CMD_VIBRATOVOL: if((param & 0xF0) != 0x00 && (param & 0xF0) != 0xF0 && (param & 0x0F) != 0x0F) param &= 0xF0; break; case CMD_GLOBALVOLUME: if(param <= 64) param *= 2; else param = 128; break; case CMD_MODCMDEX: switch(param & 0xF0) { case 0x00: // set filter command = CMD_NONE; break; case 0x30: // play backwards command = CMD_S3MCMDEX; param = 0x9F; break; case 0x40: // turn off sound in channel (volume / portamento commands after this can't pick up the note anymore) command = CMD_S3MCMDEX; param = 0xC0; break; case 0x50: // turn on/off channel // TODO: Apparently this should also kill the playing note. if((param & 0x0F) <= 0x01) { command = CMD_CHANNELVOLUME; param = (param == 0x50) ? 0x00 : 0x40; } break; case 0x60: // set loop begin / loop // TODO break; case 0x70: // set offset // TODO break; default: // Rest will be converted later from CMD_MODCMDEX to CMD_S3MCMDEX. break; } break; case CMD_TEMPO: if(param <= 0x1F) command = CMD_SPEED; break; case CMD_KEYOFF: if (param == 0) { // TODO key of at tick 0 } break; case CMD_MIDI: // Encode echo parameters into fixed MIDI macros param = 128 + (oldCmd - 32) * 32 + param / 8; } } // Read a chunk of volume or panning envelopes static void ReadDBMEnvelopeChunk(FileReader chunk, EnvelopeType envType, CSoundFile &sndFile, bool scaleEnv) { uint16 numEnvs = chunk.ReadUint16BE(); for(uint16 env = 0; env < numEnvs; env++) { DBMEnvelope dbmEnv; chunk.ReadStruct(dbmEnv); uint16 dbmIns = dbmEnv.instrument; if(dbmIns > 0 && dbmIns <= sndFile.GetNumInstruments() && (sndFile.Instruments[dbmIns] != nullptr)) { ModInstrument *mptIns = sndFile.Instruments[dbmIns]; InstrumentEnvelope &mptEnv = mptIns->GetEnvelope(envType); if(dbmEnv.numSegments) { if(dbmEnv.flags & DBMEnvelope::envEnabled) mptEnv.dwFlags.set(ENV_ENABLED); if(dbmEnv.flags & DBMEnvelope::envSustain) mptEnv.dwFlags.set(ENV_SUSTAIN); if(dbmEnv.flags & DBMEnvelope::envLoop) mptEnv.dwFlags.set(ENV_LOOP); } uint8 numPoints = std::min(dbmEnv.numSegments, 31) + 1; mptEnv.resize(numPoints); mptEnv.nLoopStart = dbmEnv.loopBegin; mptEnv.nLoopEnd = dbmEnv.loopEnd; mptEnv.nSustainStart = mptEnv.nSustainEnd = dbmEnv.sustain1; for(uint8 i = 0; i < numPoints; i++) { mptEnv[i].tick = dbmEnv.data[i * 2]; uint16 val = dbmEnv.data[i * 2 + 1]; if(scaleEnv) { // Panning envelopes are -128...128 in DigiBooster Pro 3.x val = (val + 128) / 4; } LimitMax(val, uint16(64)); mptEnv[i].value = static_cast(val); } } } } static bool ValidateHeader(const DBMFileHeader &fileHeader) { if(std::memcmp(fileHeader.dbm0, "DBM0", 4) || fileHeader.trkVerHi > 3) { return false; } return true; } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderDBM(MemoryFileReader file, const uint64 *pfilesize) { DBMFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return ProbeWantMoreData; } if(!ValidateHeader(fileHeader)) { return ProbeFailure; } MPT_UNREFERENCED_PARAMETER(pfilesize); return ProbeSuccess; } bool CSoundFile::ReadDBM(FileReader &file, ModLoadingFlags loadFlags) { file.Rewind(); DBMFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return false; } if(!ValidateHeader(fileHeader)) { return false; } if(loadFlags == onlyVerifyHeader) { return true; } ChunkReader chunkFile(file); auto chunks = chunkFile.ReadChunks(1); // Globals DBMInfoChunk infoData; if(!chunks.GetChunk(DBMChunk::idINFO).ReadStruct(infoData)) { return false; } InitializeGlobals(MOD_TYPE_DBM); InitializeChannels(); m_SongFlags = SONG_ITCOMPATGXX | SONG_ITOLDEFFECTS; m_nChannels = Clamp(infoData.channels, 1, MAX_BASECHANNELS); // note: MAX_BASECHANNELS is currently 127, but DBPro 2 supports up to 128 channels, DBPro 3 apparently up to 254. m_nInstruments = std::min(infoData.instruments, MAX_INSTRUMENTS - 1); m_nSamples = std::min(infoData.samples, MAX_SAMPLES - 1); m_madeWithTracker = mpt::format(MPT_USTRING("DigiBooster Pro %1.%2"))(mpt::ufmt::hex(fileHeader.trkVerHi), mpt::ufmt::hex(fileHeader.trkVerLo)); m_playBehaviour.set(kSlidesAtSpeed1); m_playBehaviour.reset(kITVibratoTremoloPanbrello); // Name chunk FileReader nameChunk = chunks.GetChunk(DBMChunk::idNAME); nameChunk.ReadString(m_songName, nameChunk.GetLength()); // Song chunk FileReader songChunk = chunks.GetChunk(DBMChunk::idSONG); Order().clear(); uint16 numSongs = infoData.songs; for(uint16 i = 0; i < numSongs && songChunk.CanRead(46); i++) { char name[44]; songChunk.ReadString(name, 44); if(m_songName.empty()) { m_songName = name; } uint16 numOrders = songChunk.ReadUint16BE(); #ifdef MPT_DBM_USE_REAL_SUBSONGS if(!Order().empty()) { // Add a new sequence for this song if(Order.AddSequence(false) == SEQUENCEINDEX_INVALID) break; } Order().SetName(name); ReadOrderFromFile(Order(), songChunk, numOrders); #else const ORDERINDEX startIndex = Order().GetLength(); if(startIndex < MAX_ORDERS && songChunk.CanRead(numOrders * 2u)) { LimitMax(numOrders, static_cast(MAX_ORDERS - startIndex - 1)); Order().resize(startIndex + numOrders + 1); for(uint16 ord = 0; ord < numOrders; ord++) { Order()[startIndex + ord] = static_cast(songChunk.ReadUint16BE()); } } #endif // MPT_DBM_USE_REAL_SUBSONGS } #ifdef MPT_DBM_USE_REAL_SUBSONGS Order.SetSequence(0); #endif // MPT_DBM_USE_REAL_SUBSONGS // Read instruments if(FileReader instChunk = chunks.GetChunk(DBMChunk::idINST)) { for(INSTRUMENTINDEX i = 1; i <= GetNumInstruments(); i++) { DBMInstrument instrHeader; instChunk.ReadStruct(instrHeader); ModInstrument *mptIns = AllocateInstrument(i, instrHeader.sample); if(mptIns == nullptr || instrHeader.sample >= MAX_SAMPLES) { continue; } ModSample &mptSmp = Samples[instrHeader.sample]; mpt::String::Read(mptIns->name, instrHeader.name); mpt::String::Read(m_szNames[instrHeader.sample], instrHeader.name); mptIns->nFadeOut = 0; mptIns->nPan = static_cast(instrHeader.panning + 128); LimitMax(mptIns->nPan, uint32(256)); mptIns->dwFlags.set(INS_SETPANNING); // Sample Info mptSmp.Initialize(); mptSmp.nVolume = std::min(instrHeader.volume, 64) * 4u; mptSmp.nC5Speed = instrHeader.sampleRate; if(instrHeader.loopLength && (instrHeader.flags & (DBMInstrument::smpLoop | DBMInstrument::smpPingPongLoop))) { mptSmp.nLoopStart = instrHeader.loopStart; mptSmp.nLoopEnd = mptSmp.nLoopStart + instrHeader.loopLength; mptSmp.uFlags.set(CHN_LOOP); if(instrHeader.flags & DBMInstrument::smpPingPongLoop) mptSmp.uFlags.set(CHN_PINGPONGLOOP); } } // Read envelopes ReadDBMEnvelopeChunk(chunks.GetChunk(DBMChunk::idVENV), ENV_VOLUME, *this, false); ReadDBMEnvelopeChunk(chunks.GetChunk(DBMChunk::idPENV), ENV_PANNING, *this, fileHeader.trkVerHi > 2); // Note-Off cuts samples if there's no envelope. for(INSTRUMENTINDEX i = 1; i <= GetNumInstruments(); i++) { if(Instruments[i] != nullptr && !Instruments[i]->VolEnv.dwFlags[ENV_ENABLED]) { Instruments[i]->nFadeOut = 32767; } } } // Patterns FileReader patternChunk = chunks.GetChunk(DBMChunk::idPATT); #ifndef NO_PLUGINS bool hasEchoEnable = false, hasEchoParams = false; #endif // NO_PLUGINS if(patternChunk.IsValid() && (loadFlags & loadPatternData)) { FileReader patternNameChunk = chunks.GetChunk(DBMChunk::idPNAM); patternNameChunk.Skip(1); // Encoding, should be UTF-8 or ASCII Patterns.ResizeArray(infoData.patterns); for(PATTERNINDEX pat = 0; pat < infoData.patterns; pat++) { uint16 numRows = patternChunk.ReadUint16BE(); uint32 packedSize = patternChunk.ReadUint32BE(); FileReader chunk = patternChunk.ReadChunk(packedSize); if(!Patterns.Insert(pat, numRows)) { continue; } std::string patName; patternNameChunk.ReadSizedString(patName); Patterns[pat].SetName(patName); PatternRow patRow = Patterns[pat].GetRow(0); ROWINDEX row = 0; while(chunk.CanRead(1)) { const uint8 ch = chunk.ReadUint8(); if(!ch) { // End Of Row if(++row >= numRows) break; patRow = Patterns[pat].GetRow(row); continue; } ModCommand dummy; ModCommand &m = ch <= GetNumChannels() ? patRow[ch - 1] : dummy; const uint8 b = chunk.ReadUint8(); if(b & 0x01) { uint8 note = chunk.ReadUint8(); if(note == 0x1F) note = NOTE_KEYOFF; else if(note > 0 && note < 0xFE) { note = ((note >> 4) * 12) + (note & 0x0F) + 13; } m.note = note; } if(b & 0x02) { m.instr = chunk.ReadUint8(); } if(b & 0x3C) { uint8 cmd1 = CMD_NONE, cmd2 = CMD_NONE; uint8 param1 = 0, param2 = 0; if(b & 0x04) cmd2 = chunk.ReadUint8(); if(b & 0x08) param2 = chunk.ReadUint8(); if(b & 0x10) cmd1 = chunk.ReadUint8(); if(b & 0x20) param1 = chunk.ReadUint8(); ConvertDBMEffect(cmd1, param1); ConvertDBMEffect(cmd2, param2); if (cmd2 == CMD_VOLUME || (cmd2 == CMD_NONE && cmd1 != CMD_VOLUME)) { std::swap(cmd1, cmd2); std::swap(param1, param2); } ModCommand::TwoRegularCommandsToMPT(cmd1, param1, cmd2, param2); m.volcmd = cmd1; m.vol = param1; m.command = cmd2; m.param = param2; #ifdef MODPLUG_TRACKER m.ExtendedMODtoS3MEffect(); #endif // MODPLUG_TRACKER #ifndef NO_PLUGINS if(m.command == CMD_DBMECHO) hasEchoEnable = true; else if(m.command == CMD_MIDI) hasEchoParams = true; #endif // NO_PLUGINS } } } } #ifndef NO_PLUGINS // Echo DSP if(loadFlags & loadPluginData) { if(hasEchoEnable) { // If there are any Vxx effects to dynamically enable / disable echo, use the CHN_NOFX flag. for(CHANNELINDEX i = 0; i < m_nChannels; i++) { ChnSettings[i].nMixPlugin = 1; ChnSettings[i].dwFlags.set(CHN_NOFX); } } bool anyEnabled = hasEchoEnable; // DBP 3 Documentation says that the defaults are 64/128/128/255, but they appear to be 80/150/80/255 in DBP 2.21 uint8 settings[8] = { 0, 80, 0, 150, 0, 80, 0, 255 }; if(FileReader dspChunk = chunks.GetChunk(DBMChunk::idDSPE)) { uint16 maskLen = dspChunk.ReadUint16BE(); for(uint16 i = 0; i < maskLen; i++) { bool enabled = (dspChunk.ReadUint8() == 0); if(i < m_nChannels) { if(hasEchoEnable) { // If there are any Vxx effects to dynamically enable / disable echo, use the CHN_NOFX flag. ChnSettings[i].dwFlags.set(CHN_NOFX, !enabled); } else if(enabled) { ChnSettings[i].nMixPlugin = 1; anyEnabled = true; } } } dspChunk.ReadArray(settings); } if(anyEnabled) { // Note: DigiBooster Pro 3 has a more versatile per-channel echo effect. // In this case, we'd have to create one plugin per channel. SNDMIXPLUGIN &plugin = m_MixPlugins[0]; plugin.Destroy(); memcpy(&plugin.Info.dwPluginId1, "DBM0", 4); memcpy(&plugin.Info.dwPluginId2, "Echo", 4); plugin.Info.routingFlags = SNDMIXPLUGININFO::irAutoSuspend; plugin.Info.mixMode = 0; plugin.Info.gain = 10; plugin.Info.reserved = 0; plugin.Info.dwOutputRouting = 0; std::fill(plugin.Info.dwReserved, plugin.Info.dwReserved + mpt::size(plugin.Info.dwReserved), 0); mpt::String::Write(plugin.Info.szName, "Echo"); mpt::String::Write(plugin.Info.szLibraryName, "DigiBooster Pro Echo"); plugin.pluginData.resize(sizeof(DigiBoosterEcho::PluginChunk)); new (plugin.pluginData.data()) DigiBoosterEcho::PluginChunk(settings[1], settings[3], settings[5], settings[7]); } } // Encode echo parameters into fixed MIDI macros if(hasEchoParams) { for(uint32 i = 0; i < 32; i++) { uint32 param = (i * 127u) / 32u; sprintf(m_MidiCfg.szMidiZXXExt[i ], "F0F080%02X", param); sprintf(m_MidiCfg.szMidiZXXExt[i + 32], "F0F081%02X", param); sprintf(m_MidiCfg.szMidiZXXExt[i + 64], "F0F082%02X", param); sprintf(m_MidiCfg.szMidiZXXExt[i + 96], "F0F083%02X", param); } } #endif // NO_PLUGINS // Samples FileReader sampleChunk = chunks.GetChunk(DBMChunk::idSMPL); if(sampleChunk.IsValid() && (loadFlags & loadSampleData)) { for(SAMPLEINDEX smp = 1; smp <= GetNumSamples(); smp++) { uint32 sampleFlags = sampleChunk.ReadUint32BE(); uint32 sampleLength = sampleChunk.ReadUint32BE(); ModSample &sample = Samples[smp]; sample.nLength = sampleLength; if(sampleFlags & 7) { SampleIO( (sampleFlags & 4) ? SampleIO::_32bit : ((sampleFlags & 2) ? SampleIO::_16bit : SampleIO::_8bit), SampleIO::mono, SampleIO::bigEndian, SampleIO::signedPCM) .ReadSample(sample, sampleChunk); } } } #if defined(MPT_ENABLE_MP3_SAMPLES) && 0 // Compressed samples - this does not quite work yet... FileReader mpegChunk = chunks.GetChunk(DBMChunk::idMPEG); if(mpegChunk.IsValid() && (loadFlags & loadSampleData)) { for(SAMPLEINDEX smp = 1; smp <= GetNumSamples(); smp++) { Samples[smp].nLength = mpegChunk.ReadUint32BE(); } mpegChunk.Skip(2); // 0x00 0x40 // Read whole MPEG stream into one sample and then split it up. FileReader chunk = mpegChunk.GetChunk(mpegChunk.BytesLeft()); if(ReadMP3Sample(0, chunk)) { ModSample &srcSample = Samples[0]; const int8 *smpData = srcSample.pSample8; uint32 predelay = Util::muldiv_unsigned(20116, srcSample.nC5Speed, 100000); smpData += predelay * srcSample.GetBytesPerSample(); srcSample.nLength -= predelay; for(SAMPLEINDEX smp = 1; smp <= GetNumSamples(); smp++) { ModSample &sample = Samples[smp]; sample.uFlags.set(srcSample.uFlags); LimitMax(sample.nLength, srcSample.nLength); if(sample.nLength) { sample.AllocateSample(); memcpy(sample.pSample, smpData, sample.GetSampleSizeInBytes()); smpData += sample.GetSampleSizeInBytes(); srcSample.nLength -= sample.nLength; uint32 gap = Util::muldiv_unsigned(454, srcSample.nC5Speed, 10000); smpData += gap * srcSample.GetBytesPerSample(); srcSample.nLength -= gap; } } srcSample.FreeSample(); } } #endif // MPT_ENABLE_MP3_SAMPLES return true; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/SoundFilePlayConfig.h0000644000372100037210000000636712537023156022132 00000000000000/* * SoundFilePlayConfig.h * --------------------- * Purpose: Configuration of sound levels, pan laws, etc... for various mix configurations. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once OPENMPT_NAMESPACE_BEGIN enum { NO_ATTENUATION = 1, }; enum TempoMode { tempoModeClassic = 0, tempoModeAlternative = 1, tempoModeModern = 2, tempoModeMax }; enum MixLevels { mixLevelsOriginal = 0, mixLevels1_17RC1 = 1, mixLevels1_17RC2 = 2, mixLevels1_17RC3 = 3, mixLevelsCompatible = 4, mixLevelsCompatibleFT2 = 5, mixLevelsMax }; enum ForcePanningMode { dontForcePanningMode, forceSoftPanning, forceNoSoftPanning, forceFT2Panning, }; // Class used to store settings for a song file. class CSoundFilePlayConfig { public: CSoundFilePlayConfig(void); ~CSoundFilePlayConfig(void); void SetMixLevels(MixLevels mixLevelType); //getters/setters bool getGlobalVolumeAppliesToMaster() const { return m_globalVolumeAppliesToMaster; } void setGlobalVolumeAppliesToMaster(bool inGlobalVolumeAppliesToMaster) { m_globalVolumeAppliesToMaster=inGlobalVolumeAppliesToMaster; } // user-controllable VSTi gain factor. float getVSTiVolume() const { return m_VSTiVolume; } void setVSTiVolume(float inVSTiVolume) { m_VSTiVolume = inVSTiVolume; } // default VSTi gain factor, different depending on the MPT version we're "emulating" float getVSTiAttenuation() const { return m_VSTiAttenuation; } void setVSTiAttenuation(float inVSTiAttenuation) { m_VSTiAttenuation = inVSTiAttenuation; } float getIntToFloat() const { return m_IntToFloat; } void setIntToFloat(float inIntToFloat) { m_IntToFloat = inIntToFloat; } float getFloatToInt() const { return m_FloatToInt; } void setFloatToInt(float inFloatToInt) { m_FloatToInt = inFloatToInt; } bool getUseGlobalPreAmp() const { return m_ignorePreAmp; } void setUseGlobalPreAmp(bool inUseGlobalPreAmp) { m_ignorePreAmp = inUseGlobalPreAmp; } ForcePanningMode getForcePanningMode() const { return m_forceSoftPanning; } void setForcePanningMode(ForcePanningMode inForceSoftPanning) { m_forceSoftPanning = inForceSoftPanning; } bool getDisplayDBValues() const { return m_displayDBValues; } void setDisplayDBValues(bool in) { m_displayDBValues = in; } // Values at which volumes are unchanged double getNormalSamplePreAmp() const { return m_normalSamplePreAmp; } void setNormalSamplePreAmp(double in) { m_normalSamplePreAmp = in; } double getNormalVSTiVol() const { return m_normalVSTiVol; } void setNormalVSTiVol(double in) { m_normalVSTiVol = in; } double getNormalGlobalVol() const { return m_normalGlobalVol; } void setNormalGlobalVol(double in) { m_normalGlobalVol = in; } // Extra sample attenuation in bits int getExtraSampleAttenuation() const { return m_extraAttenuation; } void setExtraSampleAttenuation(int attn) { m_extraAttenuation = attn; } protected: float m_IntToFloat; float m_FloatToInt; float m_VSTiAttenuation; float m_VSTiVolume; double m_normalSamplePreAmp; double m_normalVSTiVol; double m_normalGlobalVol; int m_extraAttenuation; ForcePanningMode m_forceSoftPanning; bool m_globalVolumeAppliesToMaster; bool m_ignorePreAmp; bool m_displayDBValues; }; OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Load_ult.cpp0000644000372100037210000002550613161656666020374 00000000000000/* * Load_ult.cpp * ------------ * Purpose: ULT (UltraTracker) module loader * Notes : (currently none) * Authors: Storlek (Original author - http://schismtracker.org/ - code ported with permission) * Johannes Schultz (OpenMPT Port, tweaks) * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" OPENMPT_NAMESPACE_BEGIN struct UltFileHeader { char signature[14]; // "MAS_UTrack_V00" uint8 version; // '1'...'4' char songName[32]; // Song Name, not guaranteed to be null-terminated uint8 messageLength; // Number of Lines }; MPT_BINARY_STRUCT(UltFileHeader, 48) struct UltSample { enum UltSampleFlags { ULT_16BIT = 4, ULT_LOOP = 8, ULT_PINGPONGLOOP = 16, }; char name[32]; char filename[12]; uint32le loopStart; uint32le loopEnd; uint32le sizeStart; uint32le sizeEnd; uint8le volume; // 0-255, apparently prior to 1.4 this was logarithmic? uint8le flags; // above uint16le speed; // only exists for 1.4+ int16le finetune; // Convert an ULT sample header to OpenMPT's internal sample header. void ConvertToMPT(ModSample &mptSmp) const { mptSmp.Initialize(); mpt::String::Read(mptSmp.filename, filename); if(sizeEnd <= sizeStart) { return; } mptSmp.nLength = sizeEnd - sizeStart; mptSmp.nSustainStart = loopStart; mptSmp.nSustainEnd = std::min(static_cast(loopEnd), mptSmp.nLength); mptSmp.nVolume = volume; mptSmp.nC5Speed = speed; if(finetune) { mptSmp.Transpose(finetune / (12.0 * 32768.0)); } if(flags & ULT_LOOP) mptSmp.uFlags.set(CHN_SUSTAINLOOP); if(flags & ULT_PINGPONGLOOP) mptSmp.uFlags.set(CHN_PINGPONGSUSTAIN); if(flags & ULT_16BIT) { mptSmp.uFlags.set(CHN_16BIT); mptSmp.nSustainStart /= 2; mptSmp.nSustainEnd /= 2; } } }; MPT_BINARY_STRUCT(UltSample, 66) /* Unhandled effects: 5x1 - do not loop sample (x is unused) 9xx - set sample offset to xx * 1024 with 9yy: set sample offset to xxyy * 4 E0x - set vibrato strength (2 is normal) The logarithmic volume scale used in older format versions here, or pretty much anywhere for that matter. I don't even think Ultra Tracker tries to convert them. */ static void TranslateULTCommands(uint8 &effect, uint8 ¶m, uint8 version) { static const uint8 ultEffTrans[] = { CMD_ARPEGGIO, CMD_PORTAMENTOUP, CMD_PORTAMENTODOWN, CMD_TONEPORTAMENTO, CMD_VIBRATO, CMD_NONE, CMD_NONE, CMD_TREMOLO, CMD_NONE, CMD_OFFSET, CMD_VOLUMESLIDE, CMD_PANNING8, CMD_VOLUME, CMD_PATTERNBREAK, CMD_NONE, // extended effects, processed separately CMD_SPEED, }; uint8 e = effect & 0x0F; effect = ultEffTrans[e]; switch(e) { case 0x00: if(!param || version < '3') effect = CMD_NONE; break; case 0x05: // play backwards if((param & 0x0F) == 0x02 || (param & 0xF0) == 0x20) { effect = CMD_S3MCMDEX; param = 0x9F; } if(((param & 0x0F) == 0x0C || (param & 0xF0) == 0xC0) && version >= '3') { effect = CMD_KEYOFF; param = 0; } break; case 0x07: if(version < '4') effect = CMD_NONE; break; case 0x0A: if(param & 0xF0) param &= 0xF0; break; case 0x0B: param = (param & 0x0F) * 0x11; break; case 0x0C: // volume param /= 4u; break; case 0x0D: // pattern break param = 10 * (param >> 4) + (param & 0x0F); break; case 0x0E: // special switch(param >> 4) { case 0x01: effect = CMD_PORTAMENTOUP; param = 0xF0 | (param & 0x0F); break; case 0x02: effect = CMD_PORTAMENTODOWN; param = 0xF0 | (param & 0x0F); break; case 0x08: if(version >= '4') { effect = CMD_S3MCMDEX; param = 0x60 | (param & 0x0F); } break; case 0x09: effect = CMD_RETRIG; param &= 0x0F; break; case 0x0A: effect = CMD_VOLUMESLIDE; param = ((param & 0x0F) << 4) | 0x0F; break; case 0x0B: effect = CMD_VOLUMESLIDE; param = 0xF0 | (param & 0x0F); break; case 0x0C: case 0x0D: effect = CMD_S3MCMDEX; break; } break; case 0x0F: if(param > 0x2F) effect = CMD_TEMPO; break; } } static int ReadULTEvent(ModCommand &m, FileReader &file, uint8 version) { uint8 b, repeat = 1; uint8 cmd1, cmd2; // 1 = vol col, 2 = fx col in the original schismtracker code uint8 param1, param2; b = file.ReadUint8(); if (b == 0xFC) // repeat event { repeat = file.ReadUint8(); b = file.ReadUint8(); } m.note = (b > 0 && b < 61) ? b + 36 : NOTE_NONE; m.instr = file.ReadUint8(); b = file.ReadUint8(); cmd1 = b & 0x0F; cmd2 = b >> 4; param1 = file.ReadUint8(); param2 = file.ReadUint8(); TranslateULTCommands(cmd1, param1, version); TranslateULTCommands(cmd2, param2, version); // sample offset -- this is even more special than digitrakker's if(cmd1 == CMD_OFFSET && cmd2 == CMD_OFFSET) { uint32 off = ((param1 << 8) | param2) >> 6; cmd1 = CMD_NONE; param1 = mpt::saturate_cast(off); } else if(cmd1 == CMD_OFFSET) { uint32 off = param1 * 4; param1 = mpt::saturate_cast(off); } else if(cmd2 == CMD_OFFSET) { uint32 off = param2 * 4; param2 = mpt::saturate_cast(off); } else if(cmd1 == cmd2) { // don't try to figure out how ultratracker does this, it's quite random cmd2 = CMD_NONE; } if(cmd2 == CMD_VOLUME || (cmd2 == CMD_NONE && cmd1 != CMD_VOLUME)) { // swap commands std::swap(cmd1, cmd2); std::swap(param1, param2); } // Combine slide commands, if possible ModCommand::CombineEffects(cmd2, param2, cmd1, param1); ModCommand::TwoRegularCommandsToMPT(cmd1, param1, cmd2, param2); m.volcmd = cmd1; m.vol = param1; m.command = cmd2; m.param = param2; return repeat; } // Functor for postfixing ULT patterns (this is easier than just remembering everything WHILE we're reading the pattern events) struct PostFixUltCommands { PostFixUltCommands(CHANNELINDEX numChannels) { this->numChannels = numChannels; curChannel = 0; writeT125 = false; isPortaActive.resize(numChannels, false); } void operator()(ModCommand& m) { // Attempt to fix portamentos. // UltraTracker will slide until the destination note is reached or 300 is encountered. // Stop porta? if(m.command == CMD_TONEPORTAMENTO && m.param == 0) { isPortaActive[curChannel] = false; m.command = CMD_NONE; } if(m.volcmd == VOLCMD_TONEPORTAMENTO && m.vol == 0) { isPortaActive[curChannel] = false; m.volcmd = VOLCMD_NONE; } // Apply porta? if(m.note == NOTE_NONE && isPortaActive[curChannel]) { if(m.command == CMD_NONE && m.vol != VOLCMD_TONEPORTAMENTO) { m.command = CMD_TONEPORTAMENTO; m.param = 0; } else if(m.volcmd == VOLCMD_NONE && m.command != CMD_TONEPORTAMENTO) { m.volcmd = VOLCMD_TONEPORTAMENTO; m.vol = 0; } } else // new note -> stop porta (or initialize again) { isPortaActive[curChannel] = (m.command == CMD_TONEPORTAMENTO || m.volcmd == VOLCMD_TONEPORTAMENTO); } // attempt to fix F00 (reset to tempo 125, speed 6) if(writeT125 && m.command == CMD_NONE) { m.command = CMD_TEMPO; m.param = 125; } if(m.command == CMD_SPEED && m.param == 0) { m.param = 6; writeT125 = true; } if(m.command == CMD_TEMPO) // don't try to fix this anymore if the tempo has already changed. { writeT125 = false; } curChannel = (curChannel + 1) % numChannels; } std::vector isPortaActive; CHANNELINDEX numChannels, curChannel; bool writeT125; }; static bool ValidateHeader(const UltFileHeader &fileHeader) { if(fileHeader.version < '1' || fileHeader.version > '4' || std::memcmp(fileHeader.signature, "MAS_UTrack_V00", sizeof(fileHeader.signature)) ) { return false; } return true; } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderULT(MemoryFileReader file, const uint64 *pfilesize) { UltFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return ProbeWantMoreData; } if(!ValidateHeader(fileHeader)) { return ProbeFailure; } MPT_UNREFERENCED_PARAMETER(pfilesize); return ProbeSuccess; } bool CSoundFile::ReadUlt(FileReader &file, ModLoadingFlags loadFlags) { file.Rewind(); UltFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return false; } if(!ValidateHeader(fileHeader)) { return false; } if(loadFlags == onlyVerifyHeader) { return true; } InitializeGlobals(MOD_TYPE_ULT); mpt::String::Read(m_songName, fileHeader.songName); const MPT_UCHAR_TYPE *versions[] = {MPT_ULITERAL("<1.4"), MPT_ULITERAL("1.4"), MPT_ULITERAL("1.5"), MPT_ULITERAL("1.6")}; m_madeWithTracker = MPT_USTRING("UltraTracker "); m_madeWithTracker += versions[fileHeader.version - '1']; m_SongFlags = SONG_ITCOMPATGXX | SONG_ITOLDEFFECTS; // this will be converted to IT format by MPT. // read "messageLength" lines, each containing 32 characters. m_songMessage.ReadFixedLineLength(file, fileHeader.messageLength * 32, 32, 0); m_nSamples = static_cast(file.ReadUint8()); if(GetNumSamples() >= MAX_SAMPLES) return false; for(SAMPLEINDEX smp = 1; smp <= GetNumSamples(); smp++) { UltSample sampleHeader; // Annoying: v4 added a field before the end of the struct if(fileHeader.version >= '4') { file.ReadStruct(sampleHeader); } else { file.ReadStructPartial(sampleHeader, 64); sampleHeader.finetune = sampleHeader.speed; sampleHeader.speed = 8363; } sampleHeader.ConvertToMPT(Samples[smp]); mpt::String::Read(m_szNames[smp], sampleHeader.name); } ReadOrderFromFile(Order(), file, 256, 0xFF, 0xFE); m_nChannels = file.ReadUint8() + 1; PATTERNINDEX numPats = file.ReadUint8() + 1; if(GetNumChannels() > MAX_BASECHANNELS) return false; for(CHANNELINDEX chn = 0; chn < GetNumChannels(); chn++) { ChnSettings[chn].Reset(); if(fileHeader.version >= '3') ChnSettings[chn].nPan = ((file.ReadUint8() & 0x0F) << 4) + 8; else ChnSettings[chn].nPan = (chn & 1) ? 192 : 64; } Patterns.ResizeArray(numPats); for(PATTERNINDEX pat = 0; pat < numPats; pat++) { if(!Patterns.Insert(pat, 64)) return false; } for(CHANNELINDEX chn = 0; chn < m_nChannels; chn++) { ModCommand evnote; ModCommand *note; evnote.Clear(); for(PATTERNINDEX pat = 0; pat < numPats; pat++) { note = Patterns[pat].GetpModCommand(0, chn); ROWINDEX row = 0; while(row < 64) { int repeat = ReadULTEvent(evnote, file, fileHeader.version); if(repeat + row > 64) repeat = 64 - row; if(repeat == 0) break; while(repeat--) { *note = evnote; note += GetNumChannels(); row++; } } } } // Post-fix some effects. Patterns.ForEachModCommand(PostFixUltCommands(GetNumChannels())); if(loadFlags & loadSampleData) { for(SAMPLEINDEX smp = 1; smp <= GetNumSamples(); smp++) { SampleIO( Samples[smp].uFlags[CHN_16BIT] ? SampleIO::_16bit : SampleIO::_8bit, SampleIO::mono, SampleIO::littleEndian, SampleIO::signedPCM) .ReadSample(Samples[smp], file); } } return true; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/pattern.cpp0000644000372100037210000003553013161656666020304 00000000000000/* * Pattern.cpp * ----------- * Purpose: Module Pattern header class * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "pattern.h" #include "patternContainer.h" #include "../common/serialization_utils.h" #include "../common/version.h" #include "ITTools.h" #include "Sndfile.h" #include "mod_specifications.h" OPENMPT_NAMESPACE_BEGIN CSoundFile& CPattern::GetSoundFile() { return m_rPatternContainer.GetSoundFile(); } const CSoundFile& CPattern::GetSoundFile() const { return m_rPatternContainer.GetSoundFile(); } CHANNELINDEX CPattern::GetNumChannels() const { return GetSoundFile().GetNumChannels(); } // Check if there is any note data on a given row. bool CPattern::IsEmptyRow(ROWINDEX row) const { if(m_ModCommands.empty() || !IsValidRow(row)) { return true; } PatternRow data = GetRow(row); for(CHANNELINDEX chn = 0; chn < GetNumChannels(); chn++, data++) { if(!data->IsEmpty()) { return false; } } return true; } bool CPattern::SetSignature(const ROWINDEX rowsPerBeat, const ROWINDEX rowsPerMeasure) { if(rowsPerBeat < 1 || rowsPerBeat > GetSoundFile().GetModSpecifications().patternRowsMax || rowsPerMeasure < rowsPerBeat || rowsPerMeasure > GetSoundFile().GetModSpecifications().patternRowsMax) { return false; } m_RowsPerBeat = rowsPerBeat; m_RowsPerMeasure = rowsPerMeasure; return true; } // Add or remove rows from the pattern. bool CPattern::Resize(const ROWINDEX newRowCount, bool enforceFormatLimits, bool resizeAtEnd) { CSoundFile &sndFile = GetSoundFile(); if(newRowCount == m_Rows || newRowCount < 1 || newRowCount > MAX_PATTERN_ROWS) { return false; } if(enforceFormatLimits) { auto &specs = sndFile.GetModSpecifications(); if(newRowCount > specs.patternRowsMax || newRowCount < specs.patternRowsMin) return false; } try { size_t count = ((newRowCount > m_Rows) ? (newRowCount - m_Rows) : (m_Rows - newRowCount)) * GetNumChannels(); if(newRowCount > m_Rows) m_ModCommands.insert(resizeAtEnd ? m_ModCommands.end() : m_ModCommands.begin(), count, ModCommand::Empty()); else if(resizeAtEnd) m_ModCommands.erase(m_ModCommands.end() - count, m_ModCommands.end()); else m_ModCommands.erase(m_ModCommands.begin(), m_ModCommands.begin() + count); } MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e) { MPT_EXCEPTION_DELETE_OUT_OF_MEMORY(e); return false; } m_Rows = newRowCount; return true; } void CPattern::ClearCommands() { std::fill(m_ModCommands.begin(), m_ModCommands.end(), ModCommand::Empty()); } bool CPattern::AllocatePattern(ROWINDEX rows) { size_t newSize = GetNumChannels() * rows; if(rows == 0) { return false; } else if(rows == GetNumRows() && m_ModCommands.size() == newSize) { // Re-use allocated memory ClearCommands(); return true; } else { // Do this in two steps in order to keep the old pattern data in case of OOM decltype(m_ModCommands) newPattern(newSize, ModCommand::Empty()); m_ModCommands = std::move(newPattern); } m_Rows = rows; return true; } void CPattern::Deallocate() { m_Rows = m_RowsPerBeat = m_RowsPerMeasure = 0; m_ModCommands.clear(); m_PatternName.clear(); } bool CPattern::operator== (const CPattern &other) const { return GetNumRows() == other.GetNumRows() && GetNumChannels() == other.GetNumChannels() && GetOverrideSignature() == other.GetOverrideSignature() && GetRowsPerBeat() == other.GetRowsPerBeat() && GetRowsPerMeasure() == other.GetRowsPerMeasure() && GetTempoSwing() == other.GetTempoSwing() && m_ModCommands == other.m_ModCommands; } #ifdef MODPLUG_TRACKER bool CPattern::Expand() { const ROWINDEX newRows = m_Rows * 2; const CHANNELINDEX nChns = GetNumChannels(); if(m_ModCommands.empty() || newRows > GetSoundFile().GetModSpecifications().patternRowsMax) { return false; } decltype(m_ModCommands) newPattern; try { newPattern.assign(m_ModCommands.size() * 2, ModCommand::Empty()); } MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e) { MPT_EXCEPTION_DELETE_OUT_OF_MEMORY(e); return false; } for(auto mSrc = m_ModCommands.begin(), mDst = newPattern.begin(); mSrc != m_ModCommands.end(); mSrc += nChns, mDst += 2 * nChns) { std::copy(mSrc, mSrc + nChns, mDst); } m_ModCommands = std::move(newPattern); m_Rows = newRows; return true; } bool CPattern::Shrink() { if (m_ModCommands.empty() || m_Rows < GetSoundFile().GetModSpecifications().patternRowsMin * 2) { return false; } m_Rows /= 2; const CHANNELINDEX nChns = GetNumChannels(); for(ROWINDEX y = 0; y < m_Rows; y++) { const PatternRow srcRow = GetRow(y * 2); const PatternRow nextSrcRow = GetRow(y * 2 + 1); PatternRow destRow = GetRow(y); for(CHANNELINDEX x = 0; x < nChns; x++) { const ModCommand &src = srcRow[x]; const ModCommand &srcNext = nextSrcRow[x]; ModCommand &dest = destRow[x]; dest = src; if(dest.note == NOTE_NONE && !dest.instr) { // Fill in data from next row if field is empty dest.note = srcNext.note; dest.instr = srcNext.instr; if(srcNext.volcmd != VOLCMD_NONE) { dest.volcmd = srcNext.volcmd; dest.vol = srcNext.vol; } if(dest.command == CMD_NONE) { dest.command = srcNext.command; dest.param = srcNext.param; } } } } m_ModCommands.resize(m_ModCommands.size() / 2); return true; } #endif // MODPLUG_TRACKER bool CPattern::SetName(const std::string &newName) { m_PatternName = newName; return true; } bool CPattern::SetName(const char *newName, size_t maxChars) { if(newName == nullptr || maxChars == 0) { return false; } m_PatternName.assign(newName, strnlen(newName, maxChars)); return true; } // Write some kind of effect data to the pattern. Exact data to be written and write behaviour can be found in the EffectWriter object. bool CPattern::WriteEffect(EffectWriter &settings) { // First, reject invalid parameters. if(m_ModCommands.empty() || settings.m_row >= GetNumRows() || (settings.m_channel >= GetNumChannels() && settings.m_channel != CHANNELINDEX_INVALID)) { return false; } CHANNELINDEX scanChnMin = settings.m_channel, scanChnMax = settings.m_channel; // Scan all channels if(settings.m_channel == CHANNELINDEX_INVALID) { scanChnMin = 0; scanChnMax = GetNumChannels() - 1; } ModCommand * const baseCommand = GetpModCommand(settings.m_row, scanChnMin); ModCommand *m; // Scan channel(s) for same effect type - if an effect of the same type is already present, exit. if(!settings.m_allowMultiple) { m = baseCommand; for(CHANNELINDEX i = scanChnMin; i <= scanChnMax; i++, m++) { if(!settings.m_isVolEffect && m->command == settings.m_command) return true; if(settings.m_isVolEffect && m->volcmd == settings.m_volcmd) return true; } } // Easy case: check if there's some space left to put the effect somewhere m = baseCommand; for(CHANNELINDEX i = scanChnMin; i <= scanChnMax; i++, m++) { if(!settings.m_isVolEffect && m->command == CMD_NONE) { m->command = settings.m_command; m->param = settings.m_param; return true; } if(settings.m_isVolEffect && m->volcmd == VOLCMD_NONE) { m->volcmd = settings.m_volcmd; m->vol = settings.m_vol; return true; } } // Ok, apparently there's no space. If we haven't tried already, try to map it to the volume column or effect column instead. if(settings.m_retry) { const bool isS3M = (GetSoundFile().GetType() & MOD_TYPE_S3M); // Move some effects that also work in the volume column, so there's place for our new effect. if(!settings.m_isVolEffect) { m = baseCommand; for(CHANNELINDEX i = scanChnMin; i <= scanChnMax; i++, m++) { switch(m->command) { case CMD_VOLUME: if(!GetSoundFile().GetModSpecifications().HasVolCommand(VOLCMD_VOLUME)) { break; } m->volcmd = VOLCMD_VOLUME; m->vol = m->param; m->command = settings.m_command; m->param = settings.m_param; return true; case CMD_PANNING8: if(isS3M && m->param > 0x80) { break; } m->volcmd = VOLCMD_PANNING; m->command = settings.m_command; if(isS3M) m->vol = (m->param + 1u) / 2u; else m->vol = (m->param + 2u) / 4u; m->param = settings.m_param; return true; default: break; } } } // Let's try it again by writing into the "other" effect column. if(settings.m_isVolEffect) { // Convert volume effect to normal effect ModCommand::COMMAND newCommand = CMD_NONE; ModCommand::PARAM newParam = settings.m_vol; switch(settings.m_volcmd) { case VOLCMD_PANNING: newCommand = CMD_PANNING8; newParam = mpt::saturate_cast(settings.m_vol * (isS3M ? 2u : 4u)); break; case VOLCMD_VOLUME: newCommand = CMD_VOLUME; break; default: break; } if(newCommand != CMD_NONE) { settings.m_command = static_cast(newCommand); settings.m_param = newParam; settings.m_retry = false; } } else { // Convert normal effect to volume effect ModCommand::VOLCMD newVolCmd = VOLCMD_NONE; ModCommand::VOL newVol = settings.m_param; if(settings.m_command == CMD_PANNING8 && isS3M) { // This needs some manual fixing. if(settings.m_param <= 0x80) { // Can't have surround in volume column, only normal panning newVolCmd = VOLCMD_PANNING; newVol /= 2u; } } else { newVolCmd = settings.m_command; if(!ModCommand::ConvertVolEffect(newVolCmd, newVol, true)) { // No Success :( newVolCmd = VOLCMD_NONE; } } if(newVolCmd != CMD_NONE) { settings.m_volcmd = static_cast(newVolCmd); settings.m_vol = newVol; settings.m_retry = false; } } if(!settings.m_retry) { settings.m_isVolEffect = !settings.m_isVolEffect; if(WriteEffect(settings)) { return true; } } } // Try in the next row if possible (this may also happen if we already retried) if(settings.m_retryMode == EffectWriter::rmTryNextRow && settings.m_row + 1 < GetNumRows()) { settings.m_row++; settings.m_retry = true; return WriteEffect(settings); } else if(settings.m_retryMode == EffectWriter::rmTryPreviousRow && settings.m_row > 0) { settings.m_row--; settings.m_retry = true; return WriteEffect(settings); } return false; } //////////////////////////////////////////////////////////////////////// // // Pattern serialization functions // //////////////////////////////////////////////////////////////////////// enum maskbits { noteBit = (1 << 0), instrBit = (1 << 1), volcmdBit = (1 << 2), volBit = (1 << 3), commandBit = (1 << 4), effectParamBit = (1 << 5), extraData = (1 << 6) }; void WriteData(std::ostream& oStrm, const CPattern& pat); void ReadData(std::istream& iStrm, CPattern& pat, const size_t nSize = 0); void WriteModPattern(std::ostream& oStrm, const CPattern& pat) { srlztn::SsbWrite ssb(oStrm); ssb.BeginWrite(FileIdPattern, MptVersion::num); ssb.WriteItem(pat, "data", &WriteData); // pattern time signature if(pat.GetOverrideSignature()) { ssb.WriteItem(pat.GetRowsPerBeat(), "RPB."); ssb.WriteItem(pat.GetRowsPerMeasure(), "RPM."); } if(pat.HasTempoSwing()) { ssb.WriteItem(pat.GetTempoSwing(), "SWNG", TempoSwing::Serialize); } ssb.FinishWrite(); } void ReadModPattern(std::istream& iStrm, CPattern& pat, const size_t) { srlztn::SsbRead ssb(iStrm); ssb.BeginRead(FileIdPattern, MptVersion::num); if ((ssb.GetStatus() & srlztn::SNT_FAILURE) != 0) return; ssb.ReadItem(pat, "data", &ReadData); // pattern time signature uint32 nRPB = 0, nRPM = 0; ssb.ReadItem(nRPB, "RPB."); ssb.ReadItem(nRPM, "RPM."); pat.SetSignature(nRPB, nRPM); TempoSwing swing; ssb.ReadItem(swing, "SWNG", TempoSwing::Deserialize); if(!swing.empty()) swing.resize(nRPB); pat.SetTempoSwing(swing); } static uint8 CreateDiffMask(const ModCommand &chnMC, const ModCommand &newMC) { uint8 mask = 0; if(chnMC.note != newMC.note) mask |= noteBit; if(chnMC.instr != newMC.instr) mask |= instrBit; if(chnMC.volcmd != newMC.volcmd) mask |= volcmdBit; if(chnMC.vol != newMC.vol) mask |= volBit; if(chnMC.command != newMC.command) mask |= commandBit; if(chnMC.param != newMC.param) mask |= effectParamBit; return mask; } // Writes pattern data. Adapted from SaveIT. void WriteData(std::ostream& oStrm, const CPattern& pat) { if(!pat.IsValid()) return; const ROWINDEX rows = pat.GetNumRows(); const CHANNELINDEX chns = pat.GetNumChannels(); std::vector lastChnMC(chns); for(ROWINDEX r = 0; r(c+1); if(diffmask != 0) chval |= IT_bitmask_patternChanEnabled_c; mpt::IO::WriteIntLE(oStrm, chval); if(diffmask) { lastChnMC[c] = m; mpt::IO::WriteIntLE(oStrm, diffmask); if(diffmask & noteBit) mpt::IO::WriteIntLE(oStrm, m.note); if(diffmask & instrBit) mpt::IO::WriteIntLE(oStrm, m.instr); if(diffmask & volcmdBit) mpt::IO::WriteIntLE(oStrm, m.volcmd); if(diffmask & volBit) mpt::IO::WriteIntLE(oStrm, m.vol); if(diffmask & commandBit) mpt::IO::WriteIntLE(oStrm, m.command); if(diffmask & effectParamBit) mpt::IO::WriteIntLE(oStrm, m.param); } } mpt::IO::WriteIntLE(oStrm, 0); // Write end of row marker. } } #define READITEM(itembit,id) \ if(diffmask & itembit) \ { \ mpt::IO::ReadIntLE(iStrm, temp); \ if(ch < chns) \ lastChnMC[ch].id = temp; \ } \ if(ch < chns) \ m.id = lastChnMC[ch].id; void ReadData(std::istream& iStrm, CPattern& pat, const size_t) { if (!pat.IsValid()) // Expecting patterns to be allocated and resized properly. return; const CHANNELINDEX chns = pat.GetNumChannels(); const ROWINDEX rows = pat.GetNumRows(); std::vector lastChnMC(chns); ROWINDEX row = 0; while(row < rows && iStrm.good()) { uint8 t = 0; mpt::IO::ReadIntLE(iStrm, t); if(t == 0) { row++; continue; } CHANNELINDEX ch = (t & IT_bitmask_patternChanField_c); if(ch > 0) ch--; uint8 diffmask = 0; if((t & IT_bitmask_patternChanEnabled_c) != 0) mpt::IO::ReadIntLE(iStrm, diffmask); uint8 temp = 0; ModCommand dummy = ModCommand::Empty(); ModCommand& m = (ch < chns) ? *pat.GetpModCommand(row, ch) : dummy; READITEM(noteBit, note); READITEM(instrBit, instr); READITEM(volcmdBit, volcmd); READITEM(volBit, vol); READITEM(commandBit, command); READITEM(effectParamBit, param); if(diffmask & extraData) { //Ignore additional data. uint8 size; mpt::IO::ReadIntLE(iStrm, size); iStrm.ignore(size); } } } #undef READITEM OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/S3MTools.cpp0000644000372100037210000000604613161656666020252 00000000000000/* * S3MTools.cpp * ------------ * Purpose: Definition of S3M file structures and helper functions * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" #include "S3MTools.h" #include "../common/StringFixer.h" OPENMPT_NAMESPACE_BEGIN // Convert an S3M sample header to OpenMPT's internal sample header. void S3MSampleHeader::ConvertToMPT(ModSample &mptSmp) const { mptSmp.Initialize(MOD_TYPE_S3M); mpt::String::Read(mptSmp.filename, filename); if((sampleType == typePCM || sampleType == typeNone) && !memcmp(magic, "SCRS", 4)) { // Sample Length and Loops if(sampleType == typePCM) { mptSmp.nLength = length; mptSmp.nLoopStart = MIN(loopStart, mptSmp.nLength - 1); mptSmp.nLoopEnd = MIN(loopEnd, mptSmp.nLength); mptSmp.uFlags.set(CHN_LOOP, (flags & smpLoop) != 0); } if(mptSmp.nLoopEnd < 2 || mptSmp.nLoopStart >= mptSmp.nLoopEnd || mptSmp.nLoopEnd - mptSmp.nLoopStart < 1) { mptSmp.nLoopStart = mptSmp.nLoopEnd = 0; mptSmp.uFlags.reset(); } // Volume / Panning mptSmp.nVolume = MIN(defaultVolume, 64) * 4; // C-5 frequency mptSmp.nC5Speed = c5speed; if(mptSmp.nC5Speed == 0) { mptSmp.nC5Speed = 8363; } else if(mptSmp.nC5Speed < 1024) { mptSmp.nC5Speed = 1024; } } } // Convert OpenMPT's internal sample header to an S3M sample header. SmpLength S3MSampleHeader::ConvertToS3M(const ModSample &mptSmp) { SmpLength smpLength = 0; mpt::String::Write(filename, mptSmp.filename); if(mptSmp.pSample != nullptr) { sampleType = typePCM; length = static_cast(MIN(mptSmp.nLength, uint32_max)); loopStart = static_cast(MIN(mptSmp.nLoopStart, uint32_max)); loopEnd = static_cast(MIN(mptSmp.nLoopEnd, uint32_max)); smpLength = length; flags = (mptSmp.uFlags[CHN_LOOP] ? smpLoop : 0); if(mptSmp.uFlags[CHN_16BIT]) { flags |= smp16Bit; } if(mptSmp.uFlags[CHN_STEREO]) { flags |= smpStereo; } } else { sampleType = typeNone; } defaultVolume = static_cast(MIN(mptSmp.nVolume / 4, 64)); if(mptSmp.nC5Speed != 0) { c5speed = mptSmp.nC5Speed; } else { c5speed = ModSample::TransposeToFrequency(mptSmp.RelativeTone, mptSmp.nFineTune); } memcpy(magic, "SCRS", 4); return smpLength; } // Retrieve the internal sample format flags for this sample. SampleIO S3MSampleHeader::GetSampleFormat(bool signedSamples) const { if(pack == S3MSampleHeader::pADPCM && !(flags & S3MSampleHeader::smp16Bit) && !(flags & S3MSampleHeader::smpStereo)) { // MODPlugin :( return SampleIO(SampleIO::_8bit, SampleIO::mono, SampleIO::littleEndian, SampleIO::ADPCM); } else { return SampleIO( (flags & S3MSampleHeader::smp16Bit) ? SampleIO::_16bit : SampleIO::_8bit, (flags & S3MSampleHeader::smpStereo) ? SampleIO::stereoSplit : SampleIO::mono, SampleIO::littleEndian, signedSamples ? SampleIO::signedPCM : SampleIO::unsignedPCM); } } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/ChunkReader.h0000644000372100037210000000661613161656666020472 00000000000000/* * ChunkReader.h * ------------- * Purpose: An extended FileReader to read Iff-like chunk-based file structures. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "../common/FileReader.h" #include OPENMPT_NAMESPACE_BEGIN class ChunkReader : public FileReader { public: template ChunkReader(mpt::span bytedata) : FileReader(bytedata) { } ChunkReader(const FileReader &other) : FileReader(other) { } ChunkReader(FileReader &&other) : FileReader(std::move(other)) { } template class Item { private: T chunkHeader; FileReader chunkData; public: Item(const T &header, FileReader &&data) : chunkHeader(header), chunkData(std::move(data)) { } Item(const Item &) = default; Item(Item &&) noexcept = default; const T &GetHeader() const { return chunkHeader; } const FileReader &GetData() const { return chunkData; } }; template class ChunkList : public std::vector> { public: typedef decltype(T().GetID()) id_type; // Check if the list contains a given chunk. bool ChunkExists(id_type id) const { return std::find_if(this->cbegin(), this->cend(), [&id](const Item &item) { return item.GetHeader().GetID() == id; }) != this->cend(); } // Retrieve the first chunk with a given ID. FileReader GetChunk(id_type id) const { auto item = std::find_if(this->cbegin(), this->cend(), [&id](const Item &item) { return item.GetHeader().GetID() == id; }); if(item != this->cend()) return item->GetData(); return FileReader(); } // Retrieve all chunks with a given ID. std::vector GetAllChunks(id_type id) const { std::vector result; for(const auto &item : *this) { if(item.GetHeader().GetID() == id) { result.push_back(item.GetData()); } } return result; } }; // Read a single "T" chunk. // T is required to have the methods GetID() and GetLength(). // GetLength() must return the chunk size in bytes, and GetID() the chunk ID. template Item GetNextChunk(off_t padding) { T chunkHeader; off_t dataSize = 0; if(Read(chunkHeader)) { dataSize = chunkHeader.GetLength(); } Item resultItem(chunkHeader, ReadChunk(dataSize)); // Skip padding bytes if(padding != 0 && dataSize % padding != 0) { Skip(padding - (dataSize % padding)); } return resultItem; } // Read a series of "T" chunks until the end of file is reached. // T is required to have the methods GetID() and GetLength(). // GetLength() must return the chunk size in bytes, and GetID() the chunk ID. template ChunkList ReadChunks(off_t padding) { ChunkList result; while(CanRead(sizeof(T))) { result.push_back(GetNextChunk(padding)); } return result; } // Read a series of "T" chunks until a given chunk ID is found. // T is required to have the methods GetID() and GetLength(). // GetLength() must return the chunk size in bytes, and GetID() the chunk ID. template ChunkList ReadChunksUntil(off_t padding, decltype(T().GetID()) stopAtID) { ChunkList result; while(CanRead(sizeof(T))) { result.push_back(GetNextChunk(padding)); if(result.back().GetHeader().GetID() == stopAtID) { break; } } return result; } }; OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/ModSequence.h0000644000372100037210000002042113161656666020475 00000000000000/* * ModSequence.h * ------------- * Purpose: Order and sequence handling. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include #include #include "Snd_defs.h" OPENMPT_NAMESPACE_BEGIN class CSoundFile; class ModSequenceSet; class ModSequence: public std::vector { friend class ModSequenceSet; protected: std::string m_name; // Sequence name. CSoundFile &m_sndFile; // Associated CSoundFile. ORDERINDEX m_restartPos; // Restart position when playback of this order ended public: ModSequence(CSoundFile &sndFile); ModSequence(ModSequence &&) noexcept = default; ModSequence(const ModSequence &) = default; ModSequence& operator=(const ModSequence &other); bool operator==(const ModSequence &other) const; bool operator!=(const ModSequence &other) const { return !(*this == other); } ORDERINDEX GetLength() const { return mpt::saturate_cast(size()); } // Returns last accessible index, i.e. GetLength() - 1, or 0 if the order list is empty. ORDERINDEX GetLastIndex() const { return std::max(ORDERINDEX(1), GetLength()) - 1u; } // Returns length of sequence without counting trailing '---' items. ORDERINDEX GetLengthTailTrimmed() const; // Returns length of sequence stopping counting on first '---' (or at the end of sequence). ORDERINDEX GetLengthFirstEmpty() const; // Replaces order list with 'newSize' copies of 'pat'. void assign(ORDERINDEX newSize, PATTERNINDEX pat); // Inserts 'count' orders starting from 'pos' using 'fill' as the pattern index for all inserted orders. // Sequence will automatically grow if needed and if it can't grow enough, some tail orders will be discarded. // Return: Number of orders inserted (up to 'count' many). ORDERINDEX insert(ORDERINDEX pos, ORDERINDEX count) { return insert(pos, count, GetInvalidPatIndex()); } ORDERINDEX insert(ORDERINDEX pos, ORDERINDEX count, PATTERNINDEX fill); void push_back() { push_back(GetInvalidPatIndex()); } void push_back(PATTERNINDEX pat) { if(GetLength() < MAX_ORDERS) std::vector::push_back(pat); } void resize(ORDERINDEX newSize) { resize(newSize, GetInvalidPatIndex()); } void resize(ORDERINDEX newSize, PATTERNINDEX pat) { std::vector::resize(std::min(MAX_ORDERS, newSize), pat); } // Removes orders from range [posBegin, posEnd]. void Remove(ORDERINDEX posBegin, ORDERINDEX posEnd); // Remove all references to a given pattern index from the order list. Jump commands are updated accordingly. void RemovePattern(PATTERNINDEX pat); // Replaces all occurences of oldPat with newPat. void Replace(PATTERNINDEX oldPat, PATTERNINDEX newPat) { if(oldPat != newPat) std::replace(begin(), end(), oldPat, newPat); } // Removes any "---" patterns at the end of the list. void Shrink() { resize(GetLengthTailTrimmed()); } // Check if pattern at sequence position ord is valid. bool IsValidPat(ORDERINDEX ord) const; void AdjustToNewModType(const MODTYPE oldtype); // Returns the internal representation of a stop '---' index static PATTERNINDEX GetInvalidPatIndex() { return uint16_max; } // Returns the internal representation of an ignore '+++' index static PATTERNINDEX GetIgnoreIndex() { return uint16_max - 1; } // Returns the previous/next order ignoring skip indices (+++). // If no previous/next order exists, return first/last order, and zero // when orderlist is empty. ORDERINDEX GetPreviousOrderIgnoringSkips(const ORDERINDEX start) const; ORDERINDEX GetNextOrderIgnoringSkips(const ORDERINDEX start) const; // Find an order item that contains a given pattern number. ORDERINDEX FindOrder(PATTERNINDEX pat, ORDERINDEX startSearchAt = 0, bool searchForward = true) const; // Ensures that the pattern at the specified order position is used only once (across all sequences). // If another usage is found, the pattern is replaced by a copy and the new index is returned. PATTERNINDEX EnsureUnique(ORDERINDEX ord); // Write order items as bytes. '---' is written as stopIndex, '+++' is written as ignoreIndex size_t WriteAsByte(FILE *f, const ORDERINDEX count, uint8 stopIndex = 0xFF, uint8 ignoreIndex = 0xFE) const; // Returns true if the IT orderlist datafield is not sufficient to store orderlist information. bool NeedsExtraDatafield() const; #ifdef MODPLUG_TRACKER // Check if a playback position is currently locked (inaccessible) bool IsPositionLocked(ORDERINDEX position) const; #endif // MODPLUG_TRACKER // Sequence name setter / getter inline void SetName(const std::string &newName) { m_name = newName;} inline std::string GetName() const { return m_name; } // Restart position setter / getter inline void SetRestartPos(ORDERINDEX restartPos) { m_restartPos = restartPos; } inline ORDERINDEX GetRestartPos() const { return m_restartPos; } }; class ModSequenceSet { friend void ReadModSequenceOld(std::istream& iStrm, ModSequenceSet& seq, const size_t); friend void ReadModSequences(std::istream& iStrm, ModSequenceSet& seq, const size_t); protected: std::vector m_Sequences; // Array of sequences. CSoundFile &m_sndFile; SEQUENCEINDEX m_currentSeq; // Index of current sequence. public: ModSequenceSet(CSoundFile &sndFile); ModSequenceSet(ModSequenceSet &&) noexcept = default; // Remove all sequences and initialize default sequence void Initialize(); // Get the working sequence ModSequence& operator() () { return m_Sequences[m_currentSeq]; } const ModSequence& operator() () const { return m_Sequences[m_currentSeq]; } // Get an arbitrary sequence ModSequence& operator() (SEQUENCEINDEX seq) { return m_Sequences[seq]; } const ModSequence& operator() (SEQUENCEINDEX seq) const { return m_Sequences[seq]; } SEQUENCEINDEX GetNumSequences() const { return static_cast(m_Sequences.size()); } SEQUENCEINDEX GetCurrentSequenceIndex() const { return m_currentSeq; } // Sets working sequence. void SetSequence(SEQUENCEINDEX); // Add new sequence. // If duplicate is true, new sequence is a duplicate of the current sequence. // Returns the ID of the new sequence, or SEQUENCEINDEX_INVALID on failure. SEQUENCEINDEX AddSequence(bool duplicate = true); // Removes given sequence. void RemoveSequence(SEQUENCEINDEX); // Returns the internal representation of a stop '---' index static PATTERNINDEX GetInvalidPatIndex() { return ModSequence::GetInvalidPatIndex(); } // Returns the internal representation of an ignore '+++' index static PATTERNINDEX GetIgnoreIndex() { return ModSequence::GetIgnoreIndex(); } #ifdef MODPLUG_TRACKER // Adjust sequence when converting between module formats void OnModTypeChanged(MODTYPE oldType); // If there are subsongs (separated by "---" patterns) in the module, // asks user whether to convert these into multiple sequences (given that the // modformat supports multiple sequences). // Returns true if sequences were modified, false otherwise. bool ConvertSubsongsToMultipleSequences(); // Convert the sequence's restart position information to a pattern command. bool RestartPosToPattern(SEQUENCEINDEX seq); // Merges multiple sequences into one and destroys all other sequences. // Returns false if there were no sequences to merge, true otherwise. bool MergeSequences(); #endif // MODPLUG_TRACKER std::vector::iterator begin() { return m_Sequences.begin(); } std::vector::const_iterator begin() const { return m_Sequences.begin(); } std::vector::const_iterator cbegin() const { return m_Sequences.cbegin(); } std::vector::iterator end() { return m_Sequences.end(); } std::vector::const_iterator end() const { return m_Sequences.end(); } std::vector::const_iterator cend() const { return m_Sequences.cend(); } }; const char FileIdSequences[] = "mptSeqC"; const char FileIdSequence[] = "mptSeq"; void WriteModSequences(std::ostream& oStrm, const ModSequenceSet& seq); void ReadModSequences(std::istream& iStrm, ModSequenceSet& seq, const size_t nSize = 0); void WriteModSequence(std::ostream& oStrm, const ModSequence& seq); void ReadModSequence(std::istream& iStrm, ModSequence& seq, const size_t); void WriteModSequenceOld(std::ostream& oStrm, const ModSequenceSet& seq); void ReadModSequenceOld(std::istream& iStrm, ModSequenceSet& seq, const size_t); OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Resampler.h0000644000372100037210000000654513161656666020232 00000000000000/* * Resampler.h * ----------- * Purpose: Holds the tables for all available resamplers. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "WindowedFIR.h" #include "Mixer.h" #include "MixerSettings.h" OPENMPT_NAMESPACE_BEGIN #ifdef LIBOPENMPT_BUILD // All these optimizations are not applicable to the tracker // because cutoff and firtype are configurable there. // Cache resampler tables across resampler object creation. // A C++11-style function-static singleton is holding the cached values. #define MPT_RESAMPLER_TABLES_CACHED // Prime the tables cache when the library is loaded. // Caching gets triggered via a global object that primes the cache during // construction. // This is only really useful with MPT_RESAMPLER_TABLES_CACHED. #define MPT_RESAMPLER_TABLES_CACHED_ONSTARTUP #endif // LIBOPENMPT_BUILD #define SINC_WIDTH 8 #define SINC_PHASES_BITS 12 #define SINC_PHASES (1<= SRCMODE_SPLINE && m_Settings.SrcMode < SRCMODE_DEFAULT; } private: void InitFloatmixerTables(); void InitializeTablesFromScratch(bool force=false); #ifdef MPT_RESAMPLER_TABLES_CACHED void InitializeTablesFromCache(); #endif }; OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/plugins/0000755000372100037210000000000013235362226017642 500000000000000libopenmpt-0.3.6+release.autotools/soundlib/plugins/dmo/0000755000372100037210000000000013235362226020421 500000000000000libopenmpt-0.3.6+release.autotools/soundlib/plugins/dmo/ParamEq.cpp0000644000372100037210000001022613232424315022367 00000000000000/* * ParamEq.cpp * ----------- * Purpose: Implementation of the DMO Parametric Equalizer DSP (for non-Windows platforms) * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #ifndef NO_PLUGINS #include "../../Sndfile.h" #include "ParamEq.h" #endif // !NO_PLUGINS OPENMPT_NAMESPACE_BEGIN #ifndef NO_PLUGINS namespace DMO { IMixPlugin* ParamEq::Create(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct) { return new (std::nothrow) ParamEq(factory, sndFile, mixStruct); } ParamEq::ParamEq(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct) : IMixPlugin(factory, sndFile, mixStruct) , m_maxFreqParam(1.0f) { m_param[kEqCenter] = (8000.0f - 80.0f) / 15920.0f; m_param[kEqBandwidth] = 0.314286f; m_param[kEqGain] = 0.5f; m_mixBuffer.Initialize(2, 2); InsertIntoFactoryList(); } void ParamEq::Process(float *pOutL, float *pOutR, uint32 numFrames) { if(!m_mixBuffer.Ok()) return; const float *in[2] = { m_mixBuffer.GetInputBuffer(0), m_mixBuffer.GetInputBuffer(1) }; float *out[2] = { m_mixBuffer.GetOutputBuffer(0), m_mixBuffer.GetOutputBuffer(1) }; if(m_param[kEqGain] == 0.5f) { memcpy(out[0], in[0], numFrames * sizeof(float)); memcpy(out[1], in[1], numFrames * sizeof(float)); } else { for(uint32 i = numFrames; i != 0; i--) { for(uint8 channel = 0; channel < 2; channel++) { float x = *(in[channel])++; float y = b0DIVa0 * x + b1DIVa0 * x1[channel] + b2DIVa0 * x2[channel] - a1DIVa0 * y1[channel] - a2DIVa0 * y2[channel]; x2[channel] = x1[channel]; x1[channel] = x; y2[channel] = y1[channel]; y1[channel] = y; *(out[channel])++ = y; } } } ProcessMixOps(pOutL, pOutR, m_mixBuffer.GetOutputBuffer(0), m_mixBuffer.GetOutputBuffer(1), numFrames); } PlugParamValue ParamEq::GetParameter(PlugParamIndex index) { if(index < kEqNumParameters) { return m_param[index]; } return 0; } void ParamEq::SetParameter(PlugParamIndex index, PlugParamValue value) { if(index < kEqNumParameters) { Limit(value, 0.0f, 1.0f); m_param[index] = value; RecalculateEqParams(); } } void ParamEq::Resume() { m_isResumed = true; // Limit center frequency to a third of the sampling rate. m_maxFreqParam = Clamp((m_SndFile.GetSampleRate() / 3.0f - 80.0f) / 15920.0f, 0.0f, 1.0f); RecalculateEqParams(); PositionChanged(); } void ParamEq::PositionChanged() { // Reset filter state x1[0] = x2[0] = 0; x1[1] = x2[1] = 0; y1[0] = y2[0] = 0; y1[1] = y2[1] = 0; } #ifdef MODPLUG_TRACKER CString ParamEq::GetParamName(PlugParamIndex param) { switch(param) { case kEqCenter: return _T("Center"); case kEqBandwidth: return _T("Bandwidth"); case kEqGain: return _T("Gain"); } return CString(); } CString ParamEq::GetParamLabel(PlugParamIndex param) { switch(param) { case kEqCenter: return _T("Hz"); case kEqBandwidth: return _T("Semitones"); case kEqGain: return _T("dB"); } return CString(); } CString ParamEq::GetParamDisplay(PlugParamIndex param) { float value = 0.0f; switch(param) { case kEqCenter: value = FreqInHertz(); break; case kEqBandwidth: value = BandwidthInSemitones(); break; case kEqGain: value = GainInDecibel(); break; } CString s; s.Format(_T("%.2f"), value); return s; } #endif // MODPLUG_TRACKER void ParamEq::RecalculateEqParams() { LimitMax(m_param[kEqCenter], m_maxFreqParam); const float freq = FreqInHertz() / m_SndFile.GetSampleRate(); const float a = std::pow(10.0f, GainInDecibel() / 40.0f); const float w0 = 2.0f * float(M_PI) * freq; const float sinW0 = std::sin(w0); const float cosW0 = std::cos(w0); const float alpha = sinW0 * std::sinh((BandwidthInSemitones() * (float(M_LN2) / 24.0f)) * w0 / sinW0); const float b0 = 1.0f + alpha * a; const float b1 = -2.0f * cosW0; const float b2 = 1.0f - alpha * a; const float a0 = 1.0f + alpha / a; const float a1 = -2.0f * cosW0; const float a2 = 1.0f - alpha / a; b0DIVa0 = b0 / a0; b1DIVa0 = b1 / a0; b2DIVa0 = b2 / a0; a1DIVa0 = a1 / a0; a2DIVa0 = a2 / a0; } } // namespace DMO #else MPT_MSVC_WORKAROUND_LNK4221(ParamEq) #endif // !NO_PLUGINS OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/plugins/dmo/Chorus.h0000644000372100037210000000660413161656666021777 00000000000000/* * Chorus.h * -------- * Purpose: Implementation of the DMO Chorus DSP (for non-Windows platforms) * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #ifndef NO_PLUGINS #include "../PlugInterface.h" OPENMPT_NAMESPACE_BEGIN namespace DMO { class Chorus : public IMixPlugin { protected: enum Parameters { kChorusWetDryMix = 0, kChorusDepth, kChorusFrequency, kChorusWaveShape, kChorusPhase, kChorusFeedback, kChorusDelay, kChorusNumParameters }; float m_param[kChorusNumParameters]; // Calculated parameters float m_waveShapeMin, m_waveShapeMax, m_waveShapeVal; float m_depthDelay; float m_frequency; int32 m_delayOffset; // State std::vector m_buffer; int32 m_bufPos, m_bufSize; int32 m_delayL1, m_delayL2, m_delayR1, m_delayR2; public: static IMixPlugin* Create(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct); Chorus(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct); void Release() override { delete this; } int32 GetUID() const override { return 0xEFE6629C; } int32 GetVersion() const override { return 0; } void Idle() override { } uint32 GetLatency() const override { return 0; } void Process(float *pOutL, float *pOutR, uint32 numFrames) override; float RenderSilence(uint32) override { return 0.0f; } int32 GetNumPrograms() const override { return 0; } int32 GetCurrentProgram() override { return 0; } void SetCurrentProgram(int32) override { } PlugParamIndex GetNumParameters() const override { return kChorusNumParameters; } PlugParamValue GetParameter(PlugParamIndex index) override; void SetParameter(PlugParamIndex index, PlugParamValue value) override; void Resume() override; void Suspend() override { m_isResumed = false; } void PositionChanged() override; bool IsInstrument() const override { return false; } bool CanRecieveMidiEvents() override { return false; } bool ShouldProcessSilence() override { return true; } #ifdef MODPLUG_TRACKER CString GetDefaultEffectName() override { return _T("Chorus"); } CString GetParamName(PlugParamIndex param) override; CString GetParamLabel(PlugParamIndex) override; CString GetParamDisplay(PlugParamIndex param) override; CString GetCurrentProgramName() override { return CString(); } void SetCurrentProgramName(const CString &) override { } CString GetProgramName(int32) override { return CString(); } bool HasEditor() const override { return false; } #endif void BeginSetProgram(int32) override { } void EndSetProgram() override { } int GetNumInputChannels() const override { return 2; } int GetNumOutputChannels() const override { return 2; } protected: int32 GetBufferIntOffset(int32 fpOffset) const; virtual float WetDryMix() const { return m_param[kChorusWetDryMix]; } virtual bool IsTriangle() const { return m_param[kChorusWaveShape] < 1; } virtual float Depth() const { return m_param[kChorusDepth]; } virtual float Feedback() const { return -99.0f + m_param[kChorusFeedback] * 198.0f; } virtual float Delay() const { return m_param[kChorusDelay] * 20.0f; } virtual float FrequencyInHertz() const { return m_param[kChorusFrequency] * 10.0f; } virtual int Phase() const { return Util::Round(m_param[kChorusPhase] * 4.0f); } void RecalculateChorusParams(); }; } // namespace DMO OPENMPT_NAMESPACE_END #endif // !NO_PLUGINS libopenmpt-0.3.6+release.autotools/soundlib/plugins/dmo/WavesReverb.cpp0000644000372100037210000001647613161656666023332 00000000000000/* * WavesReverb.cpp * --------------- * Purpose: Implementation of the DMO WavesReverb DSP (for non-Windows platforms) * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #ifndef NO_PLUGINS #include "../../Sndfile.h" #include "WavesReverb.h" #endif // !NO_PLUGINS OPENMPT_NAMESPACE_BEGIN #ifndef NO_PLUGINS namespace DMO { IMixPlugin* WavesReverb::Create(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct) { return new (std::nothrow) WavesReverb(factory, sndFile, mixStruct); } WavesReverb::WavesReverb(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct) : IMixPlugin(factory, sndFile, mixStruct) { m_param[kRvbInGain] = 1.0f; m_param[kRvbReverbMix] = 1.0f; m_param[kRvbReverbTime] = 1.0f / 3.0f; m_param[kRvbHighFreqRTRatio] = 0.0f; m_mixBuffer.Initialize(2, 2); InsertIntoFactoryList(); } void WavesReverb::Process(float *pOutL, float *pOutR, uint32 numFrames) { if(!m_mixBuffer.Ok()) return; const float *in[2] = { m_mixBuffer.GetInputBuffer(0), m_mixBuffer.GetInputBuffer(1) }; float *out[2] = { m_mixBuffer.GetOutputBuffer(0), m_mixBuffer.GetOutputBuffer(1) }; uint32 combPos = m_state.combPos, allpassPos = m_state.allpassPos; uint32 delay0 = (m_delay[0] + combPos + 1) & 0xFFF; uint32 delay1 = (m_delay[1] + combPos + 1) & 0xFFF; uint32 delay2 = (m_delay[2] + combPos + 1) & 0xFFF; uint32 delay3 = (m_delay[3] + combPos + 1) & 0xFFF; uint32 delay4 = (m_delay[4] + allpassPos) & 0x3FF; uint32 delay5 = (m_delay[5] + allpassPos) & 0x3FF; float delay0old = m_state.comb[delay0][0]; float delay1old = m_state.comb[delay1][1]; float delay2old = m_state.comb[delay2][2]; float delay3old = m_state.comb[delay3][3]; for(uint32 i = numFrames; i != 0; i--) { const float leftIn = *(in[0])++ + 1e-30f; // Prevent denormals const float rightIn = *(in[1])++ + 1e-30f; // Prevent denormals // Advance buffer index for the four comb filters delay0 = (delay0 - 1) & 0xFFF; delay1 = (delay1 - 1) & 0xFFF; delay2 = (delay2 - 1) & 0xFFF; delay3 = (delay3 - 1) & 0xFFF; float &delay0new = m_state.comb[delay0][0]; float &delay1new = m_state.comb[delay1][1]; float &delay2new = m_state.comb[delay2][2]; float &delay3new = m_state.comb[delay3][3]; float r1, r2; r1 = delay1new * 0.61803401f + m_state.allpass1[delay4][0] * m_coeffs[0]; r2 = m_state.allpass1[delay4][1] * m_coeffs[0] - delay0new * 0.61803401f; m_state.allpass1[allpassPos][0] = r2 * 0.61803401f + delay0new; m_state.allpass1[allpassPos][1] = delay1new - r1 * 0.61803401f; delay0new = r1; delay1new = r2; r1 = delay3new * 0.61803401f + m_state.allpass2[delay5][0] * m_coeffs[1]; r2 = m_state.allpass2[delay5][1] * m_coeffs[1] - delay2new * 0.61803401f; m_state.allpass2[allpassPos][0] = r2 * 0.61803401f + delay2new; m_state.allpass2[allpassPos][1] = delay3new - r1 * 0.61803401f; delay2new = r1; delay3new = r2; *(out[0])++ = (leftIn * m_dryFactor) + delay0new + delay2new; *(out[1])++ = (rightIn * m_dryFactor) + delay1new + delay3new; const float leftWet = leftIn * m_wetFactor; const float rightWet = rightIn * m_wetFactor; m_state.comb[combPos][0] = (delay0new * m_coeffs[2]) + (delay0old * m_coeffs[3]) + leftWet; m_state.comb[combPos][1] = (delay1new * m_coeffs[4]) + (delay1old * m_coeffs[5]) + rightWet; m_state.comb[combPos][2] = (delay2new * m_coeffs[6]) + (delay2old * m_coeffs[7]) - rightWet; m_state.comb[combPos][3] = (delay3new * m_coeffs[8]) + (delay3old * m_coeffs[9]) + leftWet; delay0old = delay0new; delay1old = delay1new; delay2old = delay2new; delay3old = delay3new; // Advance buffer index combPos = (combPos - 1) & 0xFFF; allpassPos = (allpassPos - 1) & 0x3FF; delay4 = (delay4 - 1) & 0x3FF; delay5 = (delay5 - 1) & 0x3FF; } m_state.combPos = combPos; m_state.allpassPos = allpassPos; ProcessMixOps(pOutL, pOutR, m_mixBuffer.GetOutputBuffer(0), m_mixBuffer.GetOutputBuffer(1), numFrames); } PlugParamValue WavesReverb::GetParameter(PlugParamIndex index) { if(index < kDistNumParameters) { return m_param[index]; } return 0; } void WavesReverb::SetParameter(PlugParamIndex index, PlugParamValue value) { if(index < kDistNumParameters) { Limit(value, 0.0f, 1.0f); m_param[index] = value; RecalculateWavesReverbParams(); } } void WavesReverb::Resume() { m_isResumed = true; // Recalculate delays uint32 delay0 = Util::Round(m_SndFile.GetSampleRate() * 0.045f); uint32 delay1 = Util::Round(delay0 * 1.18920707f); // 2^0.25 uint32 delay2 = Util::Round(delay1 * 1.18920707f); uint32 delay3 = Util::Round(delay2 * 1.18920707f); uint32 delay4 = Util::Round((delay0 + delay2) * 0.11546667f); uint32 delay5 = Util::Round((delay1 + delay3) * 0.11546667f); // Comb delays m_delay[0] = delay0 - delay4; m_delay[1] = delay2 - delay4; m_delay[2] = delay1 - delay5; m_delay[3] = delay3 - delay5; // Allpass delays m_delay[4] = delay4; m_delay[5] = delay5; RecalculateWavesReverbParams(); PositionChanged(); } void WavesReverb::PositionChanged() { MemsetZero(m_state); } #ifdef MODPLUG_TRACKER CString WavesReverb::GetParamName(PlugParamIndex param) { switch(param) { case kRvbInGain: return _T("InGain"); case kRvbReverbMix: return _T("ReverbMix"); case kRvbReverbTime: return _T("ReverbTime"); case kRvbHighFreqRTRatio: return _T("HighFreqRTRatio"); } return CString(); } CString WavesReverb::GetParamLabel(PlugParamIndex param) { switch(param) { case kRvbInGain: case kRvbReverbMix: return _T("dB"); case kRvbReverbTime: return _T("ms"); } return CString(); } CString WavesReverb::GetParamDisplay(PlugParamIndex param) { float value = m_param[param]; switch(param) { case kRvbInGain: case kRvbReverbMix: value = GainInDecibel(value); break; case kRvbReverbTime: value = ReverbTime(); break; case kRvbHighFreqRTRatio: value = HighFreqRTRatio(); break; } CString s; s.Format(_T("%.2f"), value); return s; } #endif // MODPLUG_TRACKER void WavesReverb::RecalculateWavesReverbParams() { // Recalculate filters const double ReverbTimeSmp = -3000.0 / (m_SndFile.GetSampleRate() * ReverbTime()); const double ReverbTimeSmpHF = ReverbTimeSmp * (1.0 / HighFreqRTRatio() - 1.0); m_coeffs[0] = static_cast(std::pow(10.0, m_delay[4] * ReverbTimeSmp)); m_coeffs[1] = static_cast(std::pow(10.0, m_delay[5] * ReverbTimeSmp)); double sum = 0.0; for(uint32 pair = 0; pair < 4; pair++) { double gain1 = std::pow(10.0, m_delay[pair] * ReverbTimeSmp); double gain2 = (1.0 - std::pow(10.0, (m_delay[pair] + m_delay[4 + pair / 2]) * ReverbTimeSmpHF)) * 0.5; double gain3 = gain1 * m_coeffs[pair / 2]; double gain4 = gain3 * (((gain3 + 1.0) * gain3 + 1.0) * gain3 + 1.0) + 1.0; m_coeffs[2 + pair * 2] = static_cast(gain1 * (1.0 - gain2)); m_coeffs[3 + pair * 2] = static_cast(gain1 * gain2); sum += gain4 * gain4; } double inGain = std::pow(10.0, GainInDecibel(m_param[kRvbInGain]) * 0.05); double reverbMix = std::pow(10.0, GainInDecibel(m_param[kRvbReverbMix]) * 0.1); m_dryFactor = static_cast(std::sqrt(1.0 - reverbMix) * inGain); m_wetFactor = static_cast(std::sqrt(reverbMix) * (4.0 / std::sqrt(sum) * inGain)); } } // namespace DMO #else MPT_MSVC_WORKAROUND_LNK4221(WavesReverb) #endif // !NO_PLUGINS OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/plugins/dmo/Echo.h0000644000372100037210000000531413161656666021407 00000000000000/* * Echo.h * ------ * Purpose: Implementation of the DMO Echo DSP (for non-Windows platforms) * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #ifndef NO_PLUGINS #include "../PlugInterface.h" OPENMPT_NAMESPACE_BEGIN namespace DMO { class Echo : public IMixPlugin { protected: enum Parameters { kEchoWetDry = 0, kEchoFeedback, kEchoLeftDelay, kEchoRightDelay, kEchoPanDelay, kEchoNumParameters }; std::vector m_delayLine; // Echo delay line float m_param[kEchoNumParameters]; uint32 m_bufferSize; // Delay line length in frames uint32 m_writePos; // Current write position in the delay line uint32 m_delayTime[2]; // In frames uint32 m_sampleRate; // Echo calculation coefficients float m_initialFeedback; bool m_crossEcho; public: static IMixPlugin* Create(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct); Echo(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct); void Release() override { delete this; } int32 GetUID() const override { return 0xEF3E932C; } int32 GetVersion() const override { return 0; } void Idle() override { } uint32 GetLatency() const override { return 0; } void Process(float *pOutL, float *pOutR, uint32 numFrames)override; float RenderSilence(uint32) override { return 0.0f; } int32 GetNumPrograms() const override { return 0; } int32 GetCurrentProgram() override { return 0; } void SetCurrentProgram(int32) override { } PlugParamIndex GetNumParameters() const override { return kEchoNumParameters; } PlugParamValue GetParameter(PlugParamIndex index) override; void SetParameter(PlugParamIndex index, PlugParamValue value) override; void Resume() override; void Suspend() override { m_isResumed = false; } void PositionChanged() override; bool IsInstrument() const override { return false; } bool CanRecieveMidiEvents() override { return false; } bool ShouldProcessSilence() override { return true; } #ifdef MODPLUG_TRACKER CString GetDefaultEffectName() override { return _T("Echo"); } CString GetParamName(PlugParamIndex param) override; CString GetParamLabel(PlugParamIndex) override; CString GetParamDisplay(PlugParamIndex param) override; CString GetCurrentProgramName() override { return CString(); } void SetCurrentProgramName(const CString &) override { } CString GetProgramName(int32) override { return CString(); } bool HasEditor() const override { return false; } #endif int GetNumInputChannels() const override { return 2; } int GetNumOutputChannels() const override { return 2; } protected: void RecalculateEchoParams(); }; } // namespace DMO OPENMPT_NAMESPACE_END #endif // !NO_PLUGINS libopenmpt-0.3.6+release.autotools/soundlib/plugins/dmo/Compressor.h0000644000372100037210000000620713161656666022667 00000000000000/* * Compressor.h * ------------- * Purpose: Implementation of the DMO Compressor DSP (for non-Windows platforms) * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #ifndef NO_PLUGINS #include "../PlugInterface.h" OPENMPT_NAMESPACE_BEGIN namespace DMO { class Compressor : public IMixPlugin { protected: enum Parameters { kCompGain = 0, kCompAttack, kCompRelease, kCompThreshold, kCompRatio, kCompPredelay, kCompNumParameters }; float m_param[kCompNumParameters]; // Calculated parameters and coefficients float m_gain; float m_attack; float m_release; float m_threshold; float m_ratio; int32 m_predelay; // State std::vector m_buffer; int32 m_bufPos, m_bufSize; float m_peak; public: static IMixPlugin* Create(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct); Compressor(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct); void Release() override { delete this; } int32 GetUID() const override { return 0xEF011F79; } int32 GetVersion() const override { return 0; } void Idle() override { } uint32 GetLatency() const override { return 0; } void Process(float *pOutL, float *pOutR, uint32 numFrames) override; float RenderSilence(uint32) override { return 0.0f; } int32 GetNumPrograms() const override { return 0; } int32 GetCurrentProgram() override { return 0; } void SetCurrentProgram(int32) override { } PlugParamIndex GetNumParameters() const override { return kCompNumParameters; } PlugParamValue GetParameter(PlugParamIndex index) override; void SetParameter(PlugParamIndex index, PlugParamValue value) override; void Resume() override; void Suspend() override { m_isResumed = false; } void PositionChanged() override; bool IsInstrument() const override { return false; } bool CanRecieveMidiEvents() override { return false; } bool ShouldProcessSilence() override { return true; } #ifdef MODPLUG_TRACKER CString GetDefaultEffectName() override { return _T("Compressor"); } CString GetParamName(PlugParamIndex param) override; CString GetParamLabel(PlugParamIndex) override; CString GetParamDisplay(PlugParamIndex param) override; CString GetCurrentProgramName() override { return CString(); } void SetCurrentProgramName(const CString &) override { } CString GetProgramName(int32) override { return CString(); } bool HasEditor() const override { return false; } #endif int GetNumInputChannels() const override { return 2; } int GetNumOutputChannels() const override { return 2; } protected: float GainInDecibel() const { return -60.0f + m_param[kCompGain] * 120.0f; } float AttackTime() const { return 0.01f + m_param[kCompAttack] * 499.99f; } float ReleaseTime() const { return 50.0f + m_param[kCompRelease] * 2950.0f; } float ThresholdInDecibel() const { return -60.0f + m_param[kCompThreshold] * 60.0f; } float CompressorRatio() const { return 1.0f + m_param[kCompRatio] * 99.0f; } float PreDelay() const { return m_param[kCompPredelay] * 4.0f; } void RecalculateCompressorParams(); }; } // namespace DMO OPENMPT_NAMESPACE_END #endif // !NO_PLUGINS && NO_DMO libopenmpt-0.3.6+release.autotools/soundlib/plugins/dmo/Echo.cpp0000644000372100037210000001052113161656666021736 00000000000000/* * Echo.cpp * -------- * Purpose: Implementation of the DMO Echo DSP (for non-Windows platforms) * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #ifndef NO_PLUGINS #include "../../Sndfile.h" #include "Echo.h" #endif // !NO_PLUGINS OPENMPT_NAMESPACE_BEGIN #ifndef NO_PLUGINS namespace DMO { IMixPlugin* Echo::Create(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct) { return new (std::nothrow) Echo(factory, sndFile, mixStruct); } Echo::Echo(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct) : IMixPlugin(factory, sndFile, mixStruct) , m_bufferSize(0) , m_writePos(0) , m_sampleRate(sndFile.GetSampleRate()) , m_initialFeedback(0.0f) { m_param[kEchoWetDry] = 0.5f; m_param[kEchoFeedback] = 0.5f; m_param[kEchoLeftDelay] = 0.25f; m_param[kEchoRightDelay] = 0.25f; m_param[kEchoPanDelay] = 0.0f; m_mixBuffer.Initialize(2, 2); InsertIntoFactoryList(); } void Echo::Process(float *pOutL, float *pOutR, uint32 numFrames) { if(!m_bufferSize || !m_mixBuffer.Ok()) return; const float wetMix = m_param[kEchoWetDry], dryMix = 1 - wetMix; const float *in[2] = { m_mixBuffer.GetInputBuffer(0), m_mixBuffer.GetInputBuffer(1) }; float *out[2] = { m_mixBuffer.GetOutputBuffer(0), m_mixBuffer.GetOutputBuffer(1) }; for(uint32 i = numFrames; i != 0; i--) { for(uint8 channel = 0; channel < 2; channel++) { const uint8 readChannel = (m_crossEcho ? (1 - channel) : channel); int readPos = m_writePos - m_delayTime[readChannel]; if(readPos < 0) readPos += m_bufferSize; float chnInput = *(in[channel])++; float chnDelay = m_delayLine[readPos * 2 + readChannel]; // Calculate the delay float chnOutput = chnInput * m_initialFeedback; chnOutput += chnDelay * m_param[kEchoFeedback]; // Prevent denormals if(mpt::abs(chnOutput) < 1e-24f) chnOutput = 0.0f; m_delayLine[m_writePos * 2 + channel] = chnOutput; // Output samples now *(out[channel])++ = (chnInput * dryMix + chnDelay * wetMix); } m_writePos++; if(m_writePos == m_bufferSize) m_writePos = 0; } ProcessMixOps(pOutL, pOutR, m_mixBuffer.GetOutputBuffer(0), m_mixBuffer.GetOutputBuffer(1), numFrames); } PlugParamValue Echo::GetParameter(PlugParamIndex index) { if(index < kEchoNumParameters) { return m_param[index]; } return 0; } void Echo::SetParameter(PlugParamIndex index, PlugParamValue value) { if(index < kEchoNumParameters) { Limit(value, 0.0f, 1.0f); if(index == kEchoPanDelay) value = Util::Round(value); m_param[index] = value; RecalculateEchoParams(); } } void Echo::Resume() { m_isResumed = true; m_sampleRate = m_SndFile.GetSampleRate(); RecalculateEchoParams(); PositionChanged(); } void Echo::PositionChanged() { m_bufferSize = m_sampleRate * 2u; try { m_delayLine.assign(m_bufferSize * 2, 0); } MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e) { MPT_EXCEPTION_DELETE_OUT_OF_MEMORY(e); m_bufferSize = 0; } m_writePos = 0; } #ifdef MODPLUG_TRACKER CString Echo::GetParamName(PlugParamIndex param) { switch(param) { case kEchoWetDry: return _T("WetDryMix"); case kEchoFeedback: return _T("Feedback"); case kEchoLeftDelay: return _T("LeftDelay"); case kEchoRightDelay: return _T("RightDelay"); case kEchoPanDelay: return _T("PanDelay"); } return CString(); } CString Echo::GetParamLabel(PlugParamIndex param) { if(param == kEchoLeftDelay || param == kEchoRightDelay) return _T("ms"); return CString(); } CString Echo::GetParamDisplay(PlugParamIndex param) { CString s; switch(param) { case kEchoWetDry: case kEchoFeedback: s.Format(_T("%.2f"), m_param[param] * 100.0f); break; case kEchoLeftDelay: case kEchoRightDelay: s.Format(_T("%.2f"), m_param[param] * 2000.0f); break; case kEchoPanDelay: s = (m_param[param] <= 0.5) ? _T("No") : _T("Yes"); } return s; } #endif // MODPLUG_TRACKER void Echo::RecalculateEchoParams() { m_initialFeedback = std::sqrt(1.0f - (m_param[kEchoFeedback] * m_param[kEchoFeedback])); m_delayTime[0] = static_cast(m_param[kEchoLeftDelay] * (2 * m_sampleRate)); m_delayTime[1] = static_cast(m_param[kEchoRightDelay] * (2 * m_sampleRate)); m_crossEcho = (m_param[kEchoPanDelay]) > 0.5f; } } // namespace DMO #else MPT_MSVC_WORKAROUND_LNK4221(Echo) #endif // !NO_PLUGINS OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/plugins/dmo/DMOPlugin.h0000644000372100037210000000560713161656666022334 00000000000000/* * DMOPlugin.h * ----------- * Purpose: DirectX Media Object plugin handling / processing. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #ifndef NO_DMO #include "../PlugInterface.h" #include #include typedef interface IMediaObject IMediaObject; typedef interface IMediaObjectInPlace IMediaObjectInPlace; typedef interface IMediaParamInfo IMediaParamInfo; typedef interface IMediaParams IMediaParams; OPENMPT_NAMESPACE_BEGIN class DMOPlugin : public IMixPlugin { protected: IMediaObject *m_pMediaObject; IMediaObjectInPlace *m_pMediaProcess; IMediaParamInfo *m_pParamInfo; IMediaParams *m_pMediaParams; uint32 m_nSamplesPerSec; uint32 m_uid; union { int16 *i16; float *f32; } m_alignedBuffer; union { int16 i16[MIXBUFFERSIZE * 2 + 16]; // 16-bit PCM Stereo interleaved float f32[MIXBUFFERSIZE * 2 + 16]; // 32-bit Float Stereo interleaved } m_interleavedBuffer; bool m_useFloat; public: static IMixPlugin* Create(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct); protected: DMOPlugin(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct, IMediaObject *pMO, IMediaObjectInPlace *pMOIP, uint32 uid); ~DMOPlugin(); public: void Release() override { delete this; } int32 GetUID() const override { return m_uid; } int32 GetVersion() const override { return 2; } void Idle() override { } uint32 GetLatency() const override; void Process(float *pOutL, float *pOutR, uint32 numFrames) override; int32 GetNumPrograms() const override { return 0; } int32 GetCurrentProgram() override { return 0; } void SetCurrentProgram(int32 /*nIndex*/) override { } PlugParamIndex GetNumParameters() const override; PlugParamValue GetParameter(PlugParamIndex index) override; void SetParameter(PlugParamIndex index, PlugParamValue value) override; void Resume() override; void Suspend() override; void PositionChanged() override; bool IsInstrument() const override { return false; } bool CanRecieveMidiEvents() override { return false; } bool ShouldProcessSilence() override { return true; } #ifdef MODPLUG_TRACKER CString GetDefaultEffectName() override { return CString(); } CString GetParamName(PlugParamIndex param) override; CString GetParamLabel(PlugParamIndex param) override; CString GetParamDisplay(PlugParamIndex param) override; // TODO we could simply add our own preset mechanism. But is it really useful for these plugins? CString GetCurrentProgramName() override { return CString(); } void SetCurrentProgramName(const CString &) override { } CString GetProgramName(int32) override { return CString(); } bool HasEditor() const override { return false; } #endif int GetNumInputChannels() const override { return 2; } int GetNumOutputChannels() const override { return 2; } }; OPENMPT_NAMESPACE_END #endif // NO_DMO libopenmpt-0.3.6+release.autotools/soundlib/plugins/dmo/Compressor.cpp0000644000372100037210000001303613161656666023220 00000000000000/* * Compressor.cpp * --------------- * Purpose: Implementation of the DMO Compressor DSP (for non-Windows platforms) * Notes : The original plugin's integer and floating point code paths only * behave identically when feeding floating point numbers in range * [-32768, +32768] rather than the usual [-1, +1] into the plugin. * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #ifndef NO_PLUGINS #include "../../Sndfile.h" #include "Compressor.h" #endif // !NO_PLUGINS OPENMPT_NAMESPACE_BEGIN #ifndef NO_PLUGINS namespace DMO { // See Distortion.cpp float logGain(float x, int32 shiftL, int32 shiftR); IMixPlugin* Compressor::Create(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct) { return new (std::nothrow) Compressor(factory, sndFile, mixStruct); } Compressor::Compressor(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct) : IMixPlugin(factory, sndFile, mixStruct) { m_param[kCompGain] = 0.5f; m_param[kCompAttack] = 0.02f; m_param[kCompRelease] = 150.0f / 2950.0f; m_param[kCompThreshold] = 2.0f / 3.0f; m_param[kCompRatio] = 0.02f; m_param[kCompPredelay] = 1.0f; m_mixBuffer.Initialize(2, 2); InsertIntoFactoryList(); } void Compressor::Process(float *pOutL, float *pOutR, uint32 numFrames) { if(!m_bufSize || !m_mixBuffer.Ok()) return; const float *in[2] = { m_mixBuffer.GetInputBuffer(0), m_mixBuffer.GetInputBuffer(1) }; float *out[2] = { m_mixBuffer.GetOutputBuffer(0), m_mixBuffer.GetOutputBuffer(1) }; for(uint32 i = numFrames; i != 0; i--) { float leftIn = *(in[0])++; float rightIn = *(in[1])++; m_buffer[m_bufPos * 2] = leftIn; m_buffer[m_bufPos * 2 + 1] = rightIn; leftIn = mpt::abs(leftIn); rightIn = mpt::abs(rightIn); float mono = (leftIn + rightIn) * (0.5f * 32768.0f * 32768.0f); float monoLog = mpt::abs(logGain(mono, 31, 5)) * (1.0f / float(1u << 31)); float newPeak = monoLog + (m_peak - monoLog) * ((m_peak <= monoLog) ? m_attack : m_release); m_peak = newPeak; if(newPeak < m_threshold) newPeak = m_threshold; float compGain = (m_threshold - newPeak) * m_ratio + 0.9999999f; // Computes 2 ^ (2 ^ (log2(x) - 26) - 1) (x = 0...2^31) uint32 compGainInt = static_cast(compGain * 2147483648.0f); uint32 compGainPow = compGainInt << 5; compGainInt >>= 26; if(compGainInt) // compGainInt >= 2^26 { compGainPow |= 0x80000000u; compGainInt--; } compGainPow >>= (31 - compGainInt); int32 readOffset = m_predelay + m_bufPos * 4096 + m_bufSize - 1; readOffset /= 4096; readOffset %= m_bufSize; float outGain = (compGainPow * (1.0f / 2147483648.0f)) * m_gain; *(out[0])++ = m_buffer[readOffset * 2] * outGain; *(out[1])++ = m_buffer[readOffset * 2 + 1] * outGain; if(m_bufPos-- == 0) m_bufPos += m_bufSize; } ProcessMixOps(pOutL, pOutR, m_mixBuffer.GetOutputBuffer(0), m_mixBuffer.GetOutputBuffer(1), numFrames); } PlugParamValue Compressor::GetParameter(PlugParamIndex index) { if(index < kCompNumParameters) { return m_param[index]; } return 0; } void Compressor::SetParameter(PlugParamIndex index, PlugParamValue value) { if(index < kCompNumParameters) { Limit(value, 0.0f, 1.0f); m_param[index] = value; RecalculateCompressorParams(); } } void Compressor::Resume() { m_isResumed = true; PositionChanged(); RecalculateCompressorParams(); } void Compressor::PositionChanged() { m_bufSize = Util::muldiv(m_SndFile.GetSampleRate(), 200, 1000); try { m_buffer.assign(m_bufSize * 2, 0.0f); } MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e) { MPT_EXCEPTION_DELETE_OUT_OF_MEMORY(e); m_bufSize = 0; } m_bufPos = 0; m_peak = 0.0f; } #ifdef MODPLUG_TRACKER CString Compressor::GetParamName(PlugParamIndex param) { switch(param) { case kCompGain: return _T("Gain"); case kCompAttack: return _T("Attack"); case kCompRelease: return _T("Release"); case kCompThreshold: return _T("Threshold"); case kCompRatio: return _T("Ratio"); case kCompPredelay: return _T("Predelay"); } return CString(); } CString Compressor::GetParamLabel(PlugParamIndex param) { switch(param) { case kCompGain: case kCompThreshold: return _T("dB"); case kCompAttack: case kCompRelease: case kCompPredelay: return _T("ms"); } return CString(); } CString Compressor::GetParamDisplay(PlugParamIndex param) { float value = m_param[param]; switch(param) { case kCompGain: value = GainInDecibel(); break; case kCompAttack: value = AttackTime(); break; case kCompRelease: value = ReleaseTime(); break; case kCompThreshold: value = ThresholdInDecibel(); break; case kCompRatio: value = CompressorRatio(); break; case kCompPredelay: value = PreDelay(); break; } CString s; s.Format(_T("%.2f"), value); return s; } #endif // MODPLUG_TRACKER void Compressor::RecalculateCompressorParams() { const float sampleRate = m_SndFile.GetSampleRate() / 1000.0f; m_gain = std::pow(10.0f, GainInDecibel() / 20.0f); m_attack = std::pow(10.0f, -1.0f / (AttackTime() * sampleRate)); m_release = std::pow(10.0f, -1.0f / (ReleaseTime() * sampleRate)); const float _2e31 = float(1u << 31); const float _2e26 = float(1u << 26); m_threshold = std::min((_2e31 - 1.0f), (std::log(std::pow(10.0f, ThresholdInDecibel() / 20.0f) * _2e31) * _2e26) / static_cast(M_LN2) + _2e26) * (1.0f / _2e31); m_ratio = 1.0f - (1.0f / CompressorRatio()); m_predelay = static_cast((PreDelay() * sampleRate) + 2.0f); } } // namespace DMO #else MPT_MSVC_WORKAROUND_LNK4221(Compressor) #endif // !NO_PLUGINS OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/plugins/dmo/ParamEq.h0000644000372100037210000000541613232424315022041 00000000000000/* * ParamEq.h * --------- * Purpose: Implementation of the DMO Parametric Equalizer DSP (for non-Windows platforms) * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #ifndef NO_PLUGINS #include "../PlugInterface.h" OPENMPT_NAMESPACE_BEGIN namespace DMO { class ParamEq : public IMixPlugin { protected: enum Parameters { kEqCenter = 0, kEqBandwidth, kEqGain, kEqNumParameters }; float m_param[kEqNumParameters]; // Equalizer coefficients float b0DIVa0, b1DIVa0, b2DIVa0, a1DIVa0, a2DIVa0; // Equalizer memory float x1[2], x2[2]; float y1[2], y2[2]; float m_maxFreqParam; public: static IMixPlugin* Create(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct); ParamEq(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct); void Release() override { delete this; } int32 GetUID() const override { return 0x120CED89; } int32 GetVersion() const override { return 0; } void Idle() override { } uint32 GetLatency() const override { return 0; } void Process(float *pOutL, float *pOutR, uint32 numFrames) override; float RenderSilence(uint32) override { return 0.0f; } int32 GetNumPrograms() const override { return 0; } int32 GetCurrentProgram() override { return 0; } void SetCurrentProgram(int32) override { } PlugParamIndex GetNumParameters() const override { return kEqNumParameters; } PlugParamValue GetParameter(PlugParamIndex index) override; void SetParameter(PlugParamIndex index, PlugParamValue value) override; void Resume() override; void Suspend() override { m_isResumed = false; } void PositionChanged() override; bool IsInstrument() const override { return false; } bool CanRecieveMidiEvents() override { return false; } bool ShouldProcessSilence() override { return true; } #ifdef MODPLUG_TRACKER CString GetDefaultEffectName() override { return _T("ParamEq"); } CString GetParamName(PlugParamIndex param) override; CString GetParamLabel(PlugParamIndex) override; CString GetParamDisplay(PlugParamIndex param) override; CString GetCurrentProgramName() override { return CString(); } void SetCurrentProgramName(const CString &) override { } CString GetProgramName(int32) override { return CString(); } bool HasEditor() const override { return false; } #endif int GetNumInputChannels() const override { return 2; } int GetNumOutputChannels() const override { return 2; } protected: float BandwidthInSemitones() const { return 1.0f + m_param[kEqBandwidth] * 35.0f; } float FreqInHertz() const { return 80.0f + m_param[kEqCenter] * 15920.0f; } float GainInDecibel() const { return (m_param[kEqGain] - 0.5f) * 30.0f; } void RecalculateEqParams(); }; } // namespace DMO OPENMPT_NAMESPACE_END #endif // !NO_PLUGINS libopenmpt-0.3.6+release.autotools/soundlib/plugins/dmo/WavesReverb.h0000644000372100037210000000567113161656666022772 00000000000000/* * WavesReverb.h * ------------- * Purpose: Implementation of the DMO WavesReverb DSP (for non-Windows platforms) * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #ifndef NO_PLUGINS #include "../PlugInterface.h" OPENMPT_NAMESPACE_BEGIN namespace DMO { class WavesReverb : public IMixPlugin { protected: enum Parameters { kRvbInGain = 0, kRvbReverbMix, kRvbReverbTime, kRvbHighFreqRTRatio, kDistNumParameters }; float m_param[kDistNumParameters]; // Parameters and coefficients float m_dryFactor; float m_wetFactor; float m_coeffs[10]; uint32 m_delay[6]; // State struct ReverbState { uint32 combPos, allpassPos; float comb[4096][4]; float allpass1[1024][2]; float allpass2[1024][2]; } m_state; public: static IMixPlugin* Create(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct); WavesReverb(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct); void Release() override { delete this; } int32 GetUID() const override { return 0x87FC0268; } int32 GetVersion() const override { return 0; } void Idle() override { } uint32 GetLatency() const override { return 0; } void Process(float *pOutL, float *pOutR, uint32 numFrames) override; float RenderSilence(uint32) override { return 0.0f; } int32 GetNumPrograms() const override { return 0; } int32 GetCurrentProgram() override { return 0; } void SetCurrentProgram(int32) override { } PlugParamIndex GetNumParameters() const override { return kDistNumParameters; } PlugParamValue GetParameter(PlugParamIndex index) override; void SetParameter(PlugParamIndex index, PlugParamValue value) override; void Resume() override; void Suspend() override { m_isResumed = false; } void PositionChanged() override; bool IsInstrument() const override { return false; } bool CanRecieveMidiEvents() override { return false; } bool ShouldProcessSilence() override { return true; } #ifdef MODPLUG_TRACKER CString GetDefaultEffectName() override { return _T("WavesReverb"); } CString GetParamName(PlugParamIndex param) override; CString GetParamLabel(PlugParamIndex) override; CString GetParamDisplay(PlugParamIndex param) override; CString GetCurrentProgramName() override { return CString(); } void SetCurrentProgramName(const CString &) override { } CString GetProgramName(int32) override { return CString(); } bool HasEditor() const override { return false; } #endif int GetNumInputChannels() const override { return 2; } int GetNumOutputChannels() const override { return 2; } protected: static float GainInDecibel(float param) { return -96.0f + param * 96.0f; } float ReverbTime() const { return 0.001f + m_param[kRvbReverbTime] * 2999.999f; } float HighFreqRTRatio() const { return 0.001f + m_param[kRvbHighFreqRTRatio] * 0.998f; } void RecalculateWavesReverbParams(); }; } // namespace DMO OPENMPT_NAMESPACE_END #endif // !NO_PLUGINS libopenmpt-0.3.6+release.autotools/soundlib/plugins/dmo/Distortion.cpp0000644000372100037210000001405413161656666023223 00000000000000/* * Distortion.cpp * -------------- * Purpose: Implementation of the DMO Distortion DSP (for non-Windows platforms) * Notes : The original plugin's integer and floating point code paths only * behave identically when feeding floating point numbers in range * [-32768, +32768] rather than the usual [-1, +1] into the plugin. * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #ifndef NO_PLUGINS #include "../../Sndfile.h" #include "Distortion.h" #endif // !NO_PLUGINS OPENMPT_NAMESPACE_BEGIN #ifndef NO_PLUGINS namespace DMO { // Computes (log2(x) + 1) * 2 ^ (shiftL - shiftR) (x = -2^31...2^31) float logGain(float x, int32 shiftL, int32 shiftR) { uint32 intSample = static_cast(static_cast(x)); const uint32 sign = intSample & 0x80000000; if(sign) intSample = (~intSample) + 1; // Multiply until overflow (or edge shift factor is reached) while(shiftL > 0 && intSample < 0x80000000) { intSample += intSample; shiftL--; } // Unsign clipped sample if(intSample >= 0x80000000) { intSample &= 0x7FFFFFFF; shiftL++; } intSample = (shiftL << (31 - shiftR)) | (intSample >> shiftR); if(sign) intSample = ~intSample | sign; return static_cast(static_cast(intSample)); } IMixPlugin* Distortion::Create(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct) { return new (std::nothrow) Distortion(factory, sndFile, mixStruct); } Distortion::Distortion(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct) : IMixPlugin(factory, sndFile, mixStruct) { m_param[kDistGain] = 0.7f; m_param[kDistEdge] = 0.15f; m_param[kDistPreLowpassCutoff] = 1.0f; m_param[kDistPostEQCenterFrequency] = 0.291f; m_param[kDistPostEQBandwidth] = 0.291f; m_mixBuffer.Initialize(2, 2); InsertIntoFactoryList(); } void Distortion::Process(float *pOutL, float *pOutR, uint32 numFrames) { if(!m_mixBuffer.Ok()) return; const float *in[2] = { m_mixBuffer.GetInputBuffer(0), m_mixBuffer.GetInputBuffer(1) }; float *out[2] = { m_mixBuffer.GetOutputBuffer(0), m_mixBuffer.GetOutputBuffer(1) }; for(uint32 i = numFrames; i != 0; i--) { for(uint8 channel = 0; channel < 2; channel++) { float x = *(in[channel])++; // Pre EQ float z = x * m_preEQa0 + m_preEQz1[channel] * m_preEQb1; m_preEQz1[channel] = z; z *= 1073741824.0f; // 32768^2 // The actual distortion z = logGain(z, m_edge, m_shift); // Post EQ / Gain z = (z * m_postEQa0) - m_postEQz1[channel] * m_postEQb1 - m_postEQz2[channel] * m_postEQb0; m_postEQz1[channel] = z * m_postEQb0 + m_postEQz2[channel]; m_postEQz2[channel] = z; z *= (1.0f / 1073741824.0f); // 32768^2 *(out[channel])++ = z; } } ProcessMixOps(pOutL, pOutR, m_mixBuffer.GetOutputBuffer(0), m_mixBuffer.GetOutputBuffer(1), numFrames); } PlugParamValue Distortion::GetParameter(PlugParamIndex index) { if(index < kDistNumParameters) { return m_param[index]; } return 0; } void Distortion::SetParameter(PlugParamIndex index, PlugParamValue value) { if(index < kDistNumParameters) { Limit(value, 0.0f, 1.0f); m_param[index] = value; RecalculateDistortionParams(); } } void Distortion::Resume() { m_isResumed = true; RecalculateDistortionParams(); PositionChanged(); } void Distortion::PositionChanged() { // Reset filter state m_preEQz1[0] = m_preEQz1[1] = 0; m_postEQz1[0] = m_postEQz2[0] = 0; m_postEQz1[1] = m_postEQz2[1] = 0; } #ifdef MODPLUG_TRACKER CString Distortion::GetParamName(PlugParamIndex param) { switch(param) { case kDistGain: return _T("Gain"); case kDistEdge: return _T("Edge"); case kDistPreLowpassCutoff: return _T("PreLowpassCutoff"); case kDistPostEQCenterFrequency: return _T("PostEQCenterFrequency"); case kDistPostEQBandwidth: return _T("PostEQBandwidth"); } return CString(); } CString Distortion::GetParamLabel(PlugParamIndex param) { switch(param) { case kDistGain: return _T("dB"); case kDistPreLowpassCutoff: case kDistPostEQCenterFrequency: return _T("Hz"); } return CString(); } CString Distortion::GetParamDisplay(PlugParamIndex param) { float value = m_param[param]; switch(param) { case kDistGain: value = GainInDecibel(); break; case kDistEdge: value *= 100.0f; break; case kDistPreLowpassCutoff: case kDistPostEQCenterFrequency: case kDistPostEQBandwidth: value = FreqInHertz(value); break; } CString s; s.Format(_T("%.2f"), value); return s; } #endif // MODPLUG_TRACKER void Distortion::RecalculateDistortionParams() { // Pre-EQ m_preEQb1 = std::sqrt((2.0f * std::cos(2.0f * float(M_PI) * std::min(FreqInHertz(m_param[kDistPreLowpassCutoff]) / m_SndFile.GetSampleRate(), 0.5f)) + 3.0f) / 5.0f); m_preEQa0 = std::sqrt(1.0f - m_preEQb1 * m_preEQb1); // Distortion float edge = 2.0f + m_param[kDistEdge] * 29.0f; m_edge = static_cast(edge); // 2...31 shifted bits // Work out the magical shift factor (= floor(log2(edge)) + 1 == index of highest bit + 1) uint8 shift; if(m_edge <= 3) shift = 2; else if(m_edge <= 7) shift = 3; else if(m_edge <= 15) shift = 4; else shift = 5; m_shift = shift; static const float LogNorm[32] = { 1.00f, 1.00f, 1.50f, 1.00f, 1.75f, 1.40f, 1.17f, 1.00f, 1.88f, 1.76f, 1.50f, 1.36f, 1.25f, 1.15f, 1.07f, 1.00f, 1.94f, 1.82f, 1.72f, 1.63f, 1.55f, 1.48f, 1.41f, 1.35f, 1.29f, 1.24f, 1.19f, 1.15f, 1.11f, 1.07f, 1.03f, 1.00f, }; // Post-EQ const float gain = std::pow(10.0f, GainInDecibel() / 20.0f); const float postFreq = 2.0f * float(M_PI) * std::min(FreqInHertz(m_param[kDistPostEQCenterFrequency]) / m_SndFile.GetSampleRate(), 0.5f); const float postBw = 2.0f * float(M_PI) * std::min(FreqInHertz(m_param[kDistPostEQBandwidth]) / m_SndFile.GetSampleRate(), 0.5f); const float t = std::tan(5.0e-1f * postBw); m_postEQb1 = ((1.0f - t) / (1.0f + t)); m_postEQb0 = -std::cos(postFreq); m_postEQa0 = gain * std::sqrt(1.0f - m_postEQb0 * m_postEQb0) * std::sqrt(1.0f - m_postEQb1 * m_postEQb1) * LogNorm[m_edge]; } } // namespace DMO #else MPT_MSVC_WORKAROUND_LNK4221(Distortion) #endif // !NO_PLUGINS OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/plugins/dmo/Gargle.cpp0000644000372100037210000000766613161656666022301 00000000000000/* * Gargle.cpp * ---------- * Purpose: Implementation of the DMO Gargle DSP (for non-Windows platforms) * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #ifndef NO_PLUGINS #include "../../Sndfile.h" #include "Gargle.h" #endif // !NO_PLUGINS OPENMPT_NAMESPACE_BEGIN #ifndef NO_PLUGINS namespace DMO { IMixPlugin* Gargle::Create(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct) { return new (std::nothrow) Gargle(factory, sndFile, mixStruct); } Gargle::Gargle(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct) : IMixPlugin(factory, sndFile, mixStruct) { m_param[kGargleRate] = 0.02f; m_param[kGargleWaveShape] = 0.0f; m_mixBuffer.Initialize(2, 2); InsertIntoFactoryList(); } void Gargle::Process(float *pOutL, float *pOutR, uint32 numFrames) { if(!m_mixBuffer.Ok()) return; const float *inL = m_mixBuffer.GetInputBuffer(0), *inR = m_mixBuffer.GetInputBuffer(1); float *outL = m_mixBuffer.GetOutputBuffer(0), *outR = m_mixBuffer.GetOutputBuffer(1); const bool triangle = m_param[kGargleWaveShape] < 1.0f; for(uint32 frame = numFrames; frame != 0;) { if(m_counter < m_periodHalf) { // First half of gargle period const uint32 remain = std::min(frame, m_periodHalf - m_counter); if(triangle) { const uint32 stop = m_counter + remain; const float factor = 1.0f / m_periodHalf; for(uint32 i = m_counter; i < stop; i++) { *outL++ = *inL++ * i * factor; *outR++ = *inR++ * i * factor; } } else { for(uint32 i = 0; i < remain; i++) { *outL++ = *inL++; *outR++ = *inR++; } } frame -= remain; m_counter += remain; } else { // Second half of gargle period const uint32 remain = std::min(frame, m_period - m_counter); if(triangle) { const uint32 stop = m_period - m_counter - remain; const float factor = 1.0f / m_periodHalf; for(uint32 i = m_period - m_counter; i > stop; i--) { *outL++ = *inL++ * i * factor; *outR++ = *inR++ * i * factor; } } else { for(uint32 i = 0; i < remain; i++) { *outL++ = 0; *outR++ = 0; } inL += remain; inR += remain; } frame -= remain; m_counter += remain; if(m_counter >= m_period) m_counter = 0; } } ProcessMixOps(pOutL, pOutR, m_mixBuffer.GetOutputBuffer(0), m_mixBuffer.GetOutputBuffer(1), numFrames); } PlugParamValue Gargle::GetParameter(PlugParamIndex index) { if(index < kEqNumParameters) { return m_param[index]; } return 0; } void Gargle::SetParameter(PlugParamIndex index, PlugParamValue value) { if(index < kEqNumParameters) { Limit(value, 0.0f, 1.0f); if(index == kGargleWaveShape) value = Util::Round(value); m_param[index] = value; RecalculateGargleParams(); } } void Gargle::Resume() { RecalculateGargleParams(); m_counter = 0; m_isResumed = true; } #ifdef MODPLUG_TRACKER CString Gargle::GetParamName(PlugParamIndex param) { switch(param) { case kGargleRate: return _T("Rate"); case kGargleWaveShape: return _T("WaveShape"); } return CString(); } CString Gargle::GetParamLabel(PlugParamIndex param) { switch(param) { case kGargleRate: return _T("Hz"); } return CString(); } CString Gargle::GetParamDisplay(PlugParamIndex param) { CString s; switch(param) { case kGargleRate: s.Format(_T("%d"), RateInHertz()); break; case kGargleWaveShape: return (m_param[param] < 0.5) ? _T("Triangle") : _T("Square"); } return s; } #endif // MODPLUG_TRACKER uint32 Gargle::RateInHertz() const { return Util::Round(m_param[kGargleRate] * 999.0f) + 1; } void Gargle::RecalculateGargleParams() { m_period = m_SndFile.GetSampleRate() / RateInHertz(); if(m_period < 2) m_period = 2; m_periodHalf = m_period / 2; LimitMax(m_counter, m_period); } } // namespace DMO #else MPT_MSVC_WORKAROUND_LNK4221(Gargle) #endif // !NO_PLUGINS OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/plugins/dmo/I3DL2Reverb.h0000644000372100037210000001160113161656666022450 00000000000000/* * I3DL2Reverb.h * ------------- * Purpose: Implementation of the DMO I3DL2Reverb DSP (for non-Windows platforms) * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #ifndef NO_PLUGINS #include "../PlugInterface.h" OPENMPT_NAMESPACE_BEGIN namespace DMO { class I3DL2Reverb : public IMixPlugin { protected: enum Parameters { kI3DL2ReverbRoom = 0, kI3DL2ReverbRoomHF, kI3DL2ReverbRoomRolloffFactor, // Doesn't actually do anything :) kI3DL2ReverbDecayTime, kI3DL2ReverbDecayHFRatio, kI3DL2ReverbReflections, kI3DL2ReverbReflectionsDelay, kI3DL2ReverbReverb, kI3DL2ReverbReverbDelay, kI3DL2ReverbDiffusion, kI3DL2ReverbDensity, kI3DL2ReverbHFReference, kI3DL2ReverbQuality, kI3DL2ReverbNumParameters }; enum QualityFlags { kMoreDelayLines = 0x01, kFullSampleRate = 0x02, }; class DelayLine : private std::vector { int32 m_length; int32 m_position; int32 m_delayPosition; public: void Init(int32 ms, int32 padding, uint32 sampleRate, int32 delayTap = 0); void SetDelayTap(int32 delayTap); void Advance(); void Set(float value); float Get(int32 offset) const; float Get() const; }; float m_param[kI3DL2ReverbNumParameters]; // Calculated parameters uint32 m_quality; float m_effectiveSampleRate; float m_diffusion; float m_roomFilter; float m_ERLevel; float m_ReverbLevelL; float m_ReverbLevelR; int32 m_delayTaps[15]; // 6*L + 6*R + LR + Early L + Early R int32 m_earlyTaps[2][6]; float m_delayCoeffs[13][2]; // State DelayLine m_delayLines[19]; float m_filterHist[19]; // Remaining frame for downsampled reverb float m_prevL; float m_prevR; bool m_remain; bool m_ok, m_recalcParams; public: static IMixPlugin* Create(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct); I3DL2Reverb(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct); void Release() override { delete this; } int32 GetUID() const override { return 0xEF985E71; } int32 GetVersion() const override { return 0; } void Idle() override { } uint32 GetLatency() const override { return 0; } void Process(float *pOutL, float *pOutR, uint32 numFrames) override; float RenderSilence(uint32) override { return 0.0f; } int32 GetNumPrograms() const override { return 0; } int32 GetCurrentProgram() override { return 0; } void SetCurrentProgram(int32) override { } PlugParamIndex GetNumParameters() const override { return kI3DL2ReverbNumParameters; } PlugParamValue GetParameter(PlugParamIndex index) override; void SetParameter(PlugParamIndex index, PlugParamValue value) override; void Resume() override; void Suspend() override { m_isResumed = false; } void PositionChanged() override; bool IsInstrument() const override { return false; } bool CanRecieveMidiEvents() override { return false; } bool ShouldProcessSilence() override { return true; } #ifdef MODPLUG_TRACKER CString GetDefaultEffectName() override { return _T("I3DL2Reverb"); } CString GetParamName(PlugParamIndex param) override; CString GetParamLabel(PlugParamIndex) override; CString GetParamDisplay(PlugParamIndex param) override; CString GetCurrentProgramName() override { return CString(); } void SetCurrentProgramName(const CString &) override { } CString GetProgramName(int32) override { return CString(); } bool HasEditor() const override { return false; } #endif void BeginSetProgram(int32) override { } void EndSetProgram() override { } int GetNumInputChannels() const override { return 2; } int GetNumOutputChannels() const override { return 2; } protected: float Room() const { return -10000.0f + m_param[kI3DL2ReverbRoom] * 10000.0f; } float RoomHF() const { return -10000.0f + m_param[kI3DL2ReverbRoomHF] * 10000.0f; } float RoomRolloffFactor() const { return m_param[kI3DL2ReverbRoomRolloffFactor] * 10.0f; } float DecayTime() const { return 0.1f + m_param[kI3DL2ReverbDecayTime] * 19.9f; } float DecayHFRatio() const { return 0.1f + m_param[kI3DL2ReverbDecayHFRatio] * 1.9f; } float Reflections() const { return -10000.0f + m_param[kI3DL2ReverbReflections] * 11000.0f; }; float ReflectionsDelay() const { return m_param[kI3DL2ReverbReflectionsDelay] * 0.3f; } float Reverb() const { return -10000.0f + m_param[kI3DL2ReverbReverb] * 12000.0f; }; float ReverbDelay() const { return m_param[kI3DL2ReverbReverbDelay] * 0.1f; } float Diffusion() const { return m_param[kI3DL2ReverbDiffusion] * 100.0f; } float Density() const { return m_param[kI3DL2ReverbDensity] * 100.0f; } float HFReference() const { return 20.0f + m_param[kI3DL2ReverbHFReference] * 19980.0f; } uint32 Quality() const { return Util::Round(m_param[kI3DL2ReverbQuality] * 3.0f); } void RecalculateI3DL2ReverbParams(); void SetDelayTaps(); void SetDecayCoeffs(); float CalcDecayCoeffs(int32 index); }; } // namespace DMO OPENMPT_NAMESPACE_END #endif // !NO_PLUGINS libopenmpt-0.3.6+release.autotools/soundlib/plugins/dmo/Flanger.cpp0000644000372100037210000000570013161656666022441 00000000000000/* * Flanger.cpp * ----------- * Purpose: Implementation of the DMO Flanger DSP (for non-Windows platforms) * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #ifndef NO_PLUGINS #include "../../Sndfile.h" #include "Flanger.h" #endif // !NO_PLUGINS OPENMPT_NAMESPACE_BEGIN #ifndef NO_PLUGINS namespace DMO { IMixPlugin* Flanger::Create(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct) { return new (std::nothrow) Flanger(factory, sndFile, mixStruct); } Flanger::Flanger(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct) : Chorus(factory, sndFile, mixStruct) { m_param[kFlangerWetDryMix] = 0.5f; m_param[kFlangerWaveShape] = 1.0f; m_param[kFlangerFrequency] = 0.025f; m_param[kFlangerDepth] = 1.0f; m_param[kFlangerPhase] = 0.5f; m_param[kFlangerFeedback] = (-50.0f + 99.0f) / 198.0f; m_param[kFlangerDelay] = 0.5f; // Already done in Chorus constructor //m_mixBuffer.Initialize(2, 2); //InsertIntoFactoryList(); } void Flanger::SetParameter(PlugParamIndex index, PlugParamValue value) { if(index < kFlangerNumParameters) { Limit(value, 0.0f, 1.0f); if(index == kFlangerWaveShape && value < 1.0f) value = 0.0f; else if(index == kFlangerPhase) value = Util::Round(value * 4.0f) / 4.0f; m_param[index] = value; RecalculateChorusParams(); } } #ifdef MODPLUG_TRACKER CString Flanger::GetParamName(PlugParamIndex param) { switch(param) { case kFlangerWetDryMix: return _T("WetDryMix"); case kFlangerWaveShape: return _T("WaveShape"); case kFlangerFrequency: return _T("Frequency"); case kFlangerDepth: return _T("Depth"); case kFlangerPhase: return _T("Phase"); case kFlangerFeedback: return _T("Feedback"); case kFlangerDelay: return _T("Delay"); } return CString(); } CString Flanger::GetParamLabel(PlugParamIndex param) { switch(param) { case kFlangerWetDryMix: case kFlangerDepth: case kFlangerFeedback: return _T("%"); case kFlangerFrequency: return _T("Hz"); case kFlangerPhase: return _T("°"); case kFlangerDelay: return _T("ms"); } return CString(); } CString Flanger::GetParamDisplay(PlugParamIndex param) { CString s; float value = m_param[param]; switch(param) { case kFlangerWetDryMix: case kFlangerDepth: value *= 100.0f; break; case kFlangerFrequency: value = FrequencyInHertz(); break; case kFlangerWaveShape: return (value < 1) ? _T("Triangle") : _T("Sine"); break; case kFlangerPhase: switch(Phase()) { case 0: return _T("-180"); case 1: return _T("-90"); case 2: return _T("0"); case 3: return _T("90"); case 4: return _T("180"); } break; case kFlangerFeedback: value = Feedback(); break; case kFlangerDelay: value = Delay(); } s.Format(_T("%.2f"), value); return s; } #endif // MODPLUG_TRACKER } // namespace DMO #else MPT_MSVC_WORKAROUND_LNK4221(Flanger) #endif // !NO_PLUGINS OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/plugins/dmo/Chorus.cpp0000644000372100037210000001511013161656666022322 00000000000000/* * Chorus.cpp * ---------- * Purpose: Implementation of the DMO Chorus DSP (for non-Windows platforms) * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #ifndef NO_PLUGINS #include "../../Sndfile.h" #include "Chorus.h" #endif // !NO_PLUGINS OPENMPT_NAMESPACE_BEGIN #ifndef NO_PLUGINS namespace DMO { IMixPlugin* Chorus::Create(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct) { return new (std::nothrow) Chorus(factory, sndFile, mixStruct); } Chorus::Chorus(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct) : IMixPlugin(factory, sndFile, mixStruct) { m_param[kChorusWetDryMix] = 0.5f; m_param[kChorusDepth] = 0.1f; m_param[kChorusFrequency] = 0.11f; m_param[kChorusWaveShape] = 1.0f; m_param[kChorusPhase] = 0.75f; m_param[kChorusFeedback] = (25.0f + 99.0f) / 198.0f; m_param[kChorusDelay] = 0.8f; m_mixBuffer.Initialize(2, 2); InsertIntoFactoryList(); } // Integer part of buffer position int32 Chorus::GetBufferIntOffset(int32 fpOffset) const { if(fpOffset < 0) fpOffset += m_bufSize * 4096; MPT_ASSERT(fpOffset >= 0); return (fpOffset / 4096) % m_bufSize; } void Chorus::Process(float *pOutL, float *pOutR, uint32 numFrames) { if(!m_bufSize || !m_mixBuffer.Ok()) return; const float *in[2] = { m_mixBuffer.GetInputBuffer(0), m_mixBuffer.GetInputBuffer(1) }; float *out[2] = { m_mixBuffer.GetOutputBuffer(0), m_mixBuffer.GetOutputBuffer(1) }; const bool isTriangle = IsTriangle(); const float feedback = Feedback() / 100.0f; const float wetDryMix = WetDryMix(); const uint32 phase = Phase(); for(uint32 i = numFrames; i != 0; i--) { const float leftIn = *(in[0])++; const float rightIn = *(in[1])++; int32 readOffset = GetBufferIntOffset(m_bufPos + m_delayOffset); int32 writeOffset = GetBufferIntOffset(m_bufPos); m_buffer[writeOffset] = (m_buffer[readOffset] * feedback) + (rightIn + leftIn) * 0.5f; float waveMin; float waveMax; if(isTriangle) { m_waveShapeMin += m_waveShapeVal; m_waveShapeMax += m_waveShapeVal; if(m_waveShapeMin > 1) m_waveShapeMin -= 2; if(m_waveShapeMax > 1) m_waveShapeMax -= 2; waveMin = mpt::abs(m_waveShapeMin) * 2 - 1; waveMax = mpt::abs(m_waveShapeMax) * 2 - 1; } else { m_waveShapeMin = m_waveShapeMax * m_waveShapeVal + m_waveShapeMin; m_waveShapeMax = m_waveShapeMax - m_waveShapeMin * m_waveShapeVal; waveMin = m_waveShapeMin; waveMax = m_waveShapeMax; } float left1 = m_buffer[GetBufferIntOffset(m_bufPos + m_delayL1)]; float left2 = m_buffer[GetBufferIntOffset(m_bufPos + m_delayL2)]; float fracPos = (m_delayL1 & 0xFFF) * (1.0f / 4096.0f); float leftOut = (left2 - left1) * fracPos + left1; *(out[0])++ = leftIn + (leftOut - leftIn) * wetDryMix; float right1 = m_buffer[GetBufferIntOffset(m_bufPos + m_delayR1)]; float right2 = m_buffer[GetBufferIntOffset(m_bufPos + m_delayR2)]; fracPos = (m_delayR1 & 0xFFF) * (1.0f / 4096.0f); float rightOut = (right2 - right1) * fracPos + right1; *(out[1])++ = rightIn + (rightOut - rightIn) * wetDryMix; // Increment delay positions m_delayL1 = m_delayOffset + (phase < 4 ? 1 : -1) * static_cast(waveMin * m_depthDelay); m_delayL2 = m_delayL1 + 4096; m_delayR1 = m_delayOffset + (phase < 2 ? -1 : 1) * static_cast(((phase % 2u) ? waveMax : waveMin) * m_depthDelay); m_delayR2 = m_delayR1 + 4096; if(m_bufPos <= 0) m_bufPos += m_bufSize * 4096; m_bufPos -= 4096; } ProcessMixOps(pOutL, pOutR, m_mixBuffer.GetOutputBuffer(0), m_mixBuffer.GetOutputBuffer(1), numFrames); } PlugParamValue Chorus::GetParameter(PlugParamIndex index) { if(index < kChorusNumParameters) { return m_param[index]; } return 0; } void Chorus::SetParameter(PlugParamIndex index, PlugParamValue value) { if(index < kChorusNumParameters) { Limit(value, 0.0f, 1.0f); if(index == kChorusWaveShape && value < 1.0f) value = 0.0f; else if(index == kChorusPhase) value = Util::Round(value * 4.0f) / 4.0f; m_param[index] = value; RecalculateChorusParams(); } } void Chorus::Resume() { PositionChanged(); RecalculateChorusParams(); m_isResumed = true; m_waveShapeMin = 0.0f; m_waveShapeMax = IsTriangle() ? 0.5f : 1.0f; m_delayL1 = m_delayL2 = m_delayR1 = m_delayR2 = m_delayOffset; m_bufPos = 0; } void Chorus::PositionChanged() { m_bufSize = Util::muldiv(m_SndFile.GetSampleRate(), 3840, 1000); try { m_buffer.assign(m_bufSize, 0.0f); } MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e) { MPT_EXCEPTION_DELETE_OUT_OF_MEMORY(e); m_bufSize = 0; } } #ifdef MODPLUG_TRACKER CString Chorus::GetParamName(PlugParamIndex param) { switch(param) { case kChorusWetDryMix: return _T("WetDryMix"); case kChorusDepth: return _T("Depth"); case kChorusFrequency: return _T("Frequency"); case kChorusWaveShape: return _T("WaveShape"); case kChorusPhase: return _T("Phase"); case kChorusFeedback: return _T("Feedback"); case kChorusDelay: return _T("Delay"); } return CString(); } CString Chorus::GetParamLabel(PlugParamIndex param) { switch(param) { case kChorusWetDryMix: case kChorusDepth: case kChorusFeedback: return _T("%"); case kChorusFrequency: return _T("Hz"); case kChorusPhase: return _T("°"); case kChorusDelay: return _T("ms"); } return CString(); } CString Chorus::GetParamDisplay(PlugParamIndex param) { CString s; float value = m_param[param]; switch(param) { case kChorusWetDryMix: case kChorusDepth: value *= 100.0f; break; case kChorusFrequency: value = FrequencyInHertz(); break; case kChorusWaveShape: return (value < 0.5f) ? _T("Triangle") : _T("Sine"); break; case kChorusPhase: switch(Phase()) { case 0: return _T("-180"); case 1: return _T("-90"); case 2: return _T("0"); case 3: return _T("90"); case 4: return _T("180"); } break; case kChorusFeedback: value = Feedback(); break; case kChorusDelay: value = Delay(); } s.Format(_T("%.2f"), value); return s; } #endif // MODPLUG_TRACKER void Chorus::RecalculateChorusParams() { const float sampleRate = static_cast(m_SndFile.GetSampleRate()); float delaySamples = Delay() * sampleRate / 1000.0f; m_depthDelay = Depth() * delaySamples * 2048.0f; m_delayOffset = Util::Round(4096.0f * (delaySamples + 2.0f)); m_frequency = FrequencyInHertz(); const float frequencySamples = m_frequency / sampleRate; if(IsTriangle()) m_waveShapeVal = frequencySamples * 2.0f; else m_waveShapeVal = std::sin(frequencySamples * float(M_PI)) * 2.0f; } } // namespace DMO #else MPT_MSVC_WORKAROUND_LNK4221(Chorus) #endif // !NO_PLUGINS OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/plugins/dmo/I3DL2Reverb.cpp0000644000372100037210000004464613161656666023022 00000000000000/* * I3DL2Reverb.cpp * --------------- * Purpose: Implementation of the DMO I3DL2Reverb DSP (for non-Windows platforms) * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #ifndef NO_PLUGINS #include "../../Sndfile.h" #include "I3DL2Reverb.h" #endif // !NO_PLUGINS OPENMPT_NAMESPACE_BEGIN #ifndef NO_PLUGINS namespace DMO { void I3DL2Reverb::DelayLine::Init(int32 ms, int32 padding, uint32 sampleRate, int32 delayTap) { m_length = Util::muldiv(sampleRate, ms, 1000) + padding; m_position = 0; SetDelayTap(delayTap); assign(m_length, 0.0f); } void I3DL2Reverb::DelayLine::SetDelayTap(int32 delayTap) { if(m_length > 0) m_delayPosition = (delayTap + m_position + m_length) % m_length; } void I3DL2Reverb::DelayLine::Advance() { if(--m_position < 0) m_position += m_length; if(--m_delayPosition < 0) m_delayPosition += m_length; } MPT_FORCEINLINE void I3DL2Reverb::DelayLine::Set(float value) { at(m_position) = value; } float I3DL2Reverb::DelayLine::Get(int32 offset) const { offset = (offset + m_position) % m_length; if(offset < 0) offset += m_length; return at(offset); } MPT_FORCEINLINE float I3DL2Reverb::DelayLine::Get() const { return at(m_delayPosition); } IMixPlugin* I3DL2Reverb::Create(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct) { return new (std::nothrow) I3DL2Reverb(factory, sndFile, mixStruct); } I3DL2Reverb::I3DL2Reverb(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct) : IMixPlugin(factory, sndFile, mixStruct) , m_recalcParams(true) { m_param[kI3DL2ReverbRoom] = 0.9f; m_param[kI3DL2ReverbRoomHF] = 0.99f; m_param[kI3DL2ReverbRoomRolloffFactor] = 0.0f; m_param[kI3DL2ReverbDecayTime] = 0.07f; m_param[kI3DL2ReverbDecayHFRatio] = 0.3842105f; m_param[kI3DL2ReverbReflections] = 0.672545433f; m_param[kI3DL2ReverbReflectionsDelay] = 0.233333333f; m_param[kI3DL2ReverbReverb] = 0.85f; m_param[kI3DL2ReverbReverbDelay] = 0.11f; m_param[kI3DL2ReverbDiffusion] = 1.0f; m_param[kI3DL2ReverbDensity] = 1.0f; m_param[kI3DL2ReverbHFReference] = (5000.0f - 20.0f) / 19980.0f; m_param[kI3DL2ReverbQuality] = 2.0f / 3.0f; m_mixBuffer.Initialize(2, 2); InsertIntoFactoryList(); } void I3DL2Reverb::Process(float *pOutL, float *pOutR, uint32 numFrames) { if(m_recalcParams) { auto sampleRate = m_effectiveSampleRate; RecalculateI3DL2ReverbParams(); // Resize and clear delay lines if quality has changed if(sampleRate != m_effectiveSampleRate) PositionChanged(); } if(!m_ok || !m_mixBuffer.Ok()) return; const float *in[2] = { m_mixBuffer.GetInputBuffer(0), m_mixBuffer.GetInputBuffer(1) }; float *out[2] = { m_mixBuffer.GetOutputBuffer(0), m_mixBuffer.GetOutputBuffer(1) }; uint32 frames = numFrames; if(!(m_quality & kFullSampleRate) && m_remain && frames > 0) { // Remaining frame from previous render call frames--; *(out[0]++) = m_prevL; *(out[1]++) = m_prevR; in[0]++; in[1]++; m_remain = false; } while(frames > 0) { // Apply room filter and insert into early reflection delay lines const float inL = *(in[0]++); const float inRoomL = (m_filterHist[12] - inL) * m_roomFilter + inL; m_filterHist[12] = inRoomL; m_delayLines[15].Set(inRoomL); const float inR = *(in[1]++); const float inRoomR = (m_filterHist[13] - inR) * m_roomFilter + inR; m_filterHist[13] = inRoomR; m_delayLines[16].Set(inRoomR); // Early reflections (left) float earlyL = m_delayLines[15].Get(m_earlyTaps[0][1]) * 0.68f - m_delayLines[15].Get(m_earlyTaps[0][2]) * 0.5f - m_delayLines[15].Get(m_earlyTaps[0][3]) * 0.62f - m_delayLines[15].Get(m_earlyTaps[0][4]) * 0.5f - m_delayLines[15].Get(m_earlyTaps[0][5]) * 0.62f; if(m_quality & kMoreDelayLines) { float earlyL2 = earlyL; earlyL = m_delayLines[13].Get() + earlyL * 0.618034f; m_delayLines[13].Set(earlyL2 - earlyL * 0.618034f); } const float earlyRefOutL = earlyL * m_ERLevel; m_filterHist[15] = m_delayLines[15].Get(m_earlyTaps[0][0]) + m_filterHist[15]; m_filterHist[16] = m_delayLines[16].Get(m_earlyTaps[1][0]) + m_filterHist[16]; // Lots of slightly different copy-pasta ahead float reverbL1, reverbL2, reverbL3, reverbR1, reverbR2, reverbR3; reverbL1 = -m_filterHist[15] * 0.707f; reverbL2 = m_filterHist[16] * 0.707f + reverbL1; reverbR2 = reverbL1 - m_filterHist[16] * 0.707f; m_filterHist[5] = (m_filterHist[5] - m_delayLines[5].Get()) * m_delayCoeffs[5][1] + m_delayLines[5].Get(); reverbL1 = m_filterHist[5] * m_delayCoeffs[5][0] + reverbL2 * m_diffusion; m_delayLines[5].Set(reverbL2 - reverbL1 * m_diffusion); reverbL2 = reverbL1; reverbL3 = -0.15f * reverbL1; m_filterHist[4] = (m_filterHist[4] - m_delayLines[4].Get()) * m_delayCoeffs[4][1] + m_delayLines[4].Get(); reverbL1 = m_filterHist[4] * m_delayCoeffs[4][0] + reverbL2 * m_diffusion; m_delayLines[4].Set(reverbL2 - reverbL1 * m_diffusion); reverbL2 = reverbL1; reverbL3 -= reverbL1 * 0.2f; if(m_quality & kMoreDelayLines) { m_filterHist[3] = (m_filterHist[3] - m_delayLines[3].Get()) * m_delayCoeffs[3][1] + m_delayLines[3].Get(); reverbL1 = m_filterHist[3] * m_delayCoeffs[3][0] + reverbL2 * m_diffusion; m_delayLines[3].Set(reverbL2 - reverbL1 * m_diffusion); reverbL2 = reverbL1; reverbL3 += 0.35f * reverbL1; m_filterHist[2] = (m_filterHist[2] - m_delayLines[2].Get()) * m_delayCoeffs[2][1] + m_delayLines[2].Get(); reverbL1 = m_filterHist[2] * m_delayCoeffs[2][0] + reverbL2 * m_diffusion; m_delayLines[2].Set(reverbL2 - reverbL1 * m_diffusion); reverbL2 = reverbL1; reverbL3 -= reverbL1 * 0.38f; } m_delayLines[17].Set(reverbL2); reverbL1 = m_delayLines[17].Get() * m_delayCoeffs[12][0]; m_filterHist[17] = (m_filterHist[17] - reverbL1) * m_delayCoeffs[12][1] + reverbL1; m_filterHist[1] = (m_filterHist[1] - m_delayLines[1].Get()) * m_delayCoeffs[1][1] + m_delayLines[1].Get(); reverbL1 = m_filterHist[17] * m_diffusion + m_filterHist[1] * m_delayCoeffs[1][0]; m_delayLines[1].Set(m_filterHist[17] - reverbL1 * m_diffusion); reverbL2 = reverbL1; float reverbL4 = reverbL1 * 0.38f; m_filterHist[0] = (m_filterHist[0] - m_delayLines[0].Get()) * m_delayCoeffs[0][1] + m_delayLines[0].Get(); reverbL1 = m_filterHist[0] * m_delayCoeffs[0][0] + reverbL2 * m_diffusion; m_delayLines[0].Set(reverbL2 - reverbL1 * m_diffusion); reverbL3 -= reverbL1 * 0.38f; m_filterHist[15] = reverbL1; // Early reflections (right) float earlyR = m_delayLines[16].Get(m_earlyTaps[1][1]) * 0.707f - m_delayLines[16].Get(m_earlyTaps[1][2]) * 0.6f - m_delayLines[16].Get(m_earlyTaps[1][3]) * 0.5f - m_delayLines[16].Get(m_earlyTaps[1][4]) * 0.6f - m_delayLines[16].Get(m_earlyTaps[1][5]) * 0.5f; if(m_quality & kMoreDelayLines) { float earlyR2 = earlyR; earlyR = m_delayLines[14].Get() + earlyR * 0.618034f; m_delayLines[14].Set(earlyR2 - earlyR * 0.618034f); } const float earlyRefOutR = earlyR * m_ERLevel; m_filterHist[11] = (m_filterHist[11] - m_delayLines[11].Get()) * m_delayCoeffs[11][1] + m_delayLines[11].Get(); reverbR1 = m_filterHist[11] * m_delayCoeffs[11][0] + reverbR2 * m_diffusion; m_delayLines[11].Set(reverbR2 - reverbR1 * m_diffusion); reverbR2 = reverbR1; m_filterHist[10] = (m_filterHist[10] - m_delayLines[10].Get()) * m_delayCoeffs[10][1] + m_delayLines[10].Get(); reverbR1 = m_filterHist[10] * m_delayCoeffs[10][0] + reverbR2 * m_diffusion; m_delayLines[10].Set(reverbR2 - reverbR1 * m_diffusion); reverbR3 = reverbL4 - reverbR2 * 0.15f - reverbR1 * 0.2f; reverbR2 = reverbR1; if(m_quality & kMoreDelayLines) { m_filterHist[9] = (m_filterHist[9] - m_delayLines[9].Get()) * m_delayCoeffs[9][1] + m_delayLines[9].Get(); reverbR1 = m_filterHist[9] * m_delayCoeffs[9][0] + reverbR2 * m_diffusion; m_delayLines[9].Set(reverbR2 - reverbR1 * m_diffusion); reverbR2 = reverbR1; reverbR3 += reverbR1 * 0.35f; m_filterHist[8] = (m_filterHist[8] - m_delayLines[8].Get()) * m_delayCoeffs[8][1] + m_delayLines[8].Get(); reverbR1 = m_filterHist[8] * m_delayCoeffs[8][0] + reverbR2 * m_diffusion; m_delayLines[8].Set(reverbR2 - reverbR1 * m_diffusion); reverbR2 = reverbR1; reverbR3 -= reverbR1 * 0.38f; } m_delayLines[18].Set(reverbR2); reverbR1 = m_delayLines[18].Get() * m_delayCoeffs[12][0]; m_filterHist[18] = (m_filterHist[18] - reverbR1) * m_delayCoeffs[12][1] + reverbR1; m_filterHist[7] = (m_filterHist[7] - m_delayLines[7].Get()) * m_delayCoeffs[7][1] + m_delayLines[7].Get(); reverbR1 = m_filterHist[18] * m_diffusion + m_filterHist[7] * m_delayCoeffs[7][0]; m_delayLines[7].Set(m_filterHist[18] - reverbR1 * m_diffusion); reverbR2 = reverbR1; float lateRevOutL = (reverbL3 + reverbR1 * 0.38f) * m_ReverbLevelL; m_filterHist[6] = (m_filterHist[6] - m_delayLines[6].Get()) * m_delayCoeffs[6][1] + m_delayLines[6].Get(); reverbR1 = m_filterHist[6] * m_delayCoeffs[6][0] + reverbR2 * m_diffusion; m_delayLines[6].Set(reverbR2 - reverbR1 * m_diffusion); m_filterHist[16] = reverbR1; float lateRevOutR = (reverbR3 - reverbR1 * 0.38f) * m_ReverbLevelR; float outL = earlyRefOutL + lateRevOutL; float outR = earlyRefOutR + lateRevOutR; for(std::size_t d = 0; d < mpt::size(m_delayLines); d++) m_delayLines[d].Advance(); if(!(m_quality & kFullSampleRate)) { *(out[0]++) = (outL + m_prevL) * 0.5f; *(out[1]++) = (outR + m_prevR) * 0.5f; m_prevL = outL; m_prevR = outR; in[0]++; in[1]++; if(frames-- == 1) { m_remain = true; break; } } *(out[0]++) = outL; *(out[1]++) = outR; frames--; } ProcessMixOps(pOutL, pOutR, m_mixBuffer.GetOutputBuffer(0), m_mixBuffer.GetOutputBuffer(1), numFrames); } PlugParamValue I3DL2Reverb::GetParameter(PlugParamIndex index) { if(index < kI3DL2ReverbNumParameters) { return m_param[index]; } return 0; } void I3DL2Reverb::SetParameter(PlugParamIndex index, PlugParamValue value) { if(index < kI3DL2ReverbNumParameters) { Limit(value, 0.0f, 1.0f); if(index == kI3DL2ReverbQuality) value = Util::Round(value * 3.0f) / 3.0f; m_param[index] = value; m_recalcParams = true; } } void I3DL2Reverb::Resume() { RecalculateI3DL2ReverbParams(); PositionChanged(); m_isResumed = true; } void I3DL2Reverb::PositionChanged() { MemsetZero(m_filterHist); m_prevL = 0; m_prevR = 0; m_remain = false; try { uint32 sampleRate = static_cast(m_effectiveSampleRate); m_delayLines[0].Init(67, 5, sampleRate, m_delayTaps[0]); m_delayLines[1].Init(62, 5, sampleRate, m_delayTaps[1]); m_delayLines[2].Init(53, 5, sampleRate, m_delayTaps[2]); m_delayLines[3].Init(43, 5, sampleRate, m_delayTaps[3]); m_delayLines[4].Init(32, 5, sampleRate, m_delayTaps[4]); m_delayLines[5].Init(22, 5, sampleRate, m_delayTaps[5]); m_delayLines[6].Init(75, 5, sampleRate, m_delayTaps[6]); m_delayLines[7].Init(69, 5, sampleRate, m_delayTaps[7]); m_delayLines[8].Init(60, 5, sampleRate, m_delayTaps[8]); m_delayLines[9].Init(48, 5, sampleRate, m_delayTaps[9]); m_delayLines[10].Init(36, 5, sampleRate, m_delayTaps[10]); m_delayLines[11].Init(25, 5, sampleRate, m_delayTaps[11]); m_delayLines[12].Init(0, 0, 0); // Dummy for array index consistency with both tap and coefficient arrays m_delayLines[13].Init(3, 0, sampleRate, m_delayTaps[13]); m_delayLines[14].Init(3, 0, sampleRate, m_delayTaps[14]); m_delayLines[15].Init(407, 1, sampleRate); m_delayLines[16].Init(400, 1, sampleRate); m_delayLines[17].Init(10, 0, sampleRate, -1); m_delayLines[18].Init(10, 0, sampleRate, -1); m_ok = true; } MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e) { m_ok = false; MPT_EXCEPTION_DELETE_OUT_OF_MEMORY(e); } } #ifdef MODPLUG_TRACKER CString I3DL2Reverb::GetParamName(PlugParamIndex param) { switch(param) { case kI3DL2ReverbRoom: return _T("Room"); case kI3DL2ReverbRoomHF: return _T("RoomHF"); case kI3DL2ReverbRoomRolloffFactor: return _T("RoomRolloffFactor"); case kI3DL2ReverbDecayTime: return _T("DecayTime"); case kI3DL2ReverbDecayHFRatio: return _T("DecayHFRatio"); case kI3DL2ReverbReflections: return _T("Reflections"); case kI3DL2ReverbReflectionsDelay: return _T("ReflectionsDelay"); case kI3DL2ReverbReverb: return _T("Reverb"); case kI3DL2ReverbReverbDelay: return _T("ReverbDelay"); case kI3DL2ReverbDiffusion: return _T("Diffusion"); case kI3DL2ReverbDensity: return _T("Density"); case kI3DL2ReverbHFReference: return _T("HFRefrence"); case kI3DL2ReverbQuality: return _T("Quality"); } return CString(); } CString I3DL2Reverb::GetParamLabel(PlugParamIndex param) { switch(param) { case kI3DL2ReverbRoom: case kI3DL2ReverbRoomHF: case kI3DL2ReverbReflections: case kI3DL2ReverbReverb: return _T("dB"); case kI3DL2ReverbDecayTime: case kI3DL2ReverbReflectionsDelay: case kI3DL2ReverbReverbDelay: return _T("s"); case kI3DL2ReverbDiffusion: case kI3DL2ReverbDensity: return _T("%"); case kI3DL2ReverbHFReference: return _T("Hz"); } return CString(); } CString I3DL2Reverb::GetParamDisplay(PlugParamIndex param) { static const TCHAR *modes[] = { _T("LQ"), _T("LQ+"), _T("HQ"), _T("HQ+") }; float value = m_param[param]; switch(param) { case kI3DL2ReverbRoom: value = Room() * 0.01f; break; case kI3DL2ReverbRoomHF: value = RoomHF() * 0.01f; break; case kI3DL2ReverbRoomRolloffFactor: value = RoomRolloffFactor(); break; case kI3DL2ReverbDecayTime: value = DecayTime(); break; case kI3DL2ReverbDecayHFRatio: value = DecayHFRatio(); break; case kI3DL2ReverbReflections: value = Reflections() * 0.01f; break; case kI3DL2ReverbReflectionsDelay: value = ReflectionsDelay(); break; case kI3DL2ReverbReverb: value = Reverb() * 0.01f; break; case kI3DL2ReverbReverbDelay: value = ReverbDelay(); break; case kI3DL2ReverbDiffusion: value = Diffusion(); break; case kI3DL2ReverbDensity: value = Density(); break; case kI3DL2ReverbHFReference: value = HFReference(); break; case kI3DL2ReverbQuality: return modes[Quality() % 4u]; } CString s; s.Format(_T("%.2f"), value); return s; } #endif // MODPLUG_TRACKER void I3DL2Reverb::RecalculateI3DL2ReverbParams() { m_quality = Quality(); m_effectiveSampleRate = static_cast(m_SndFile.GetSampleRate() / ((m_quality & kFullSampleRate) ? 1u : 2u)); // Diffusion m_diffusion = Diffusion() * (0.618034f / 100.0f); // Early Reflection Level m_ERLevel = std::min(std::pow(10.0f, (Room() + Reflections()) / (100.0f * 20.0f)), 1.0f) * 0.761f; // Room Filter float roomHF = std::pow(10.0f, RoomHF() / 100.0f / 10.0f); if(roomHF == 1.0) { m_roomFilter = 0.0f; } else { float freq = std::cos(HFReference() * static_cast(2.0 * M_PI) / m_effectiveSampleRate); float roomFilter = (freq * (roomHF + roomHF) - 2.0f + std::sqrt(freq * (roomHF * roomHF * freq * 4.0f) + roomHF * 8.0f - roomHF * roomHF * 4.0f - roomHF * freq * 8.0f)) / (roomHF + roomHF - 2.0f); m_roomFilter = Clamp(roomFilter, 0.0f, 1.0f); } SetDelayTaps(); SetDecayCoeffs(); m_recalcParams = false; } void I3DL2Reverb::SetDelayTaps() { // Early reflections static const float delays[] = { 1.0000f, 1.0000f, 0.0000f, 0.1078f, 0.1768f, 0.2727f, 0.3953f, 0.5386f, 0.6899f, 0.8306f, 0.9400f, 0.9800f, }; const float sampleRate = m_effectiveSampleRate; const float reflectionsDelay = ReflectionsDelay(); const float reverbDelay = std::max(ReverbDelay(), 5.0f / 1000.0f); m_earlyTaps[0][0] = static_cast((reverbDelay + reflectionsDelay + 7.0f / 1000.0f) * sampleRate); for(uint32 i = 1; i < 12; i++) { m_earlyTaps[i % 2u][i / 2u] = static_cast((reverbDelay * delays[i] + reflectionsDelay) * sampleRate); } // Late reflections float density = std::min((Density() / 100.0f + 0.1f) * 0.9091f, 1.0f); float delayL = density * 67.0f / 1000.0f * sampleRate; float delayR = density * 75.0f / 1000.0f * sampleRate; for(int i = 0, power = 0; i < 6; i++) { power += i; float factor = std::pow(0.93f, power); m_delayTaps[i + 0] = static_cast(delayL * factor); m_delayTaps[i + 6] = static_cast(delayR * factor); } m_delayTaps[12] = static_cast(10.0f / 1000.0f * sampleRate); // Early reflections (extra delay lines) m_delayTaps[13] = static_cast(3.25f / 1000.0f * sampleRate); m_delayTaps[14] = static_cast(3.53f / 1000.0f * sampleRate); for(std::size_t d = 0; d < mpt::size(m_delayTaps); d++) m_delayLines[d].SetDelayTap(m_delayTaps[d]); } void I3DL2Reverb::SetDecayCoeffs() { float levelLtmp = 1.0f, levelRtmp = 1.0f; float levelL = 0.0f, levelR = 0.0f; levelLtmp *= CalcDecayCoeffs(5); levelRtmp *= CalcDecayCoeffs(11); levelL += levelLtmp * 0.0225f; levelR += levelRtmp * 0.0225f; levelLtmp *= CalcDecayCoeffs(4); levelRtmp *= CalcDecayCoeffs(10); levelL += levelLtmp * 0.04f; levelR += levelRtmp * 0.04f; if(m_quality & kMoreDelayLines) { levelLtmp *= CalcDecayCoeffs(3); levelRtmp *= CalcDecayCoeffs(9); levelL += levelLtmp * 0.1225f; levelR += levelRtmp * 0.1225f; levelLtmp *= CalcDecayCoeffs(2); levelRtmp *= CalcDecayCoeffs(8); levelL += levelLtmp * 0.1444f; levelR += levelRtmp * 0.1444f; } CalcDecayCoeffs(12); levelLtmp *= m_delayCoeffs[12][0] * m_delayCoeffs[12][0]; levelRtmp *= m_delayCoeffs[12][0] * m_delayCoeffs[12][0]; levelLtmp *= CalcDecayCoeffs(1); levelRtmp *= CalcDecayCoeffs(7); levelL += levelRtmp * 0.1444f; levelR += levelLtmp * 0.1444f; levelLtmp *= CalcDecayCoeffs(0); levelRtmp *= CalcDecayCoeffs(6); levelL += levelLtmp * 0.1444f; levelR += levelRtmp * 0.1444f; // Final Reverb Level float level = std::min(std::pow(10.0f, (Room() + Reverb()) / (100.0f * 20.0f)), 1.0f); float monoInv = 1.0f - ((levelLtmp + levelRtmp) * 0.5f); m_ReverbLevelL = level * std::sqrt(monoInv / levelL); m_ReverbLevelR = level * std::sqrt(monoInv / levelR); } float I3DL2Reverb::CalcDecayCoeffs(int32 index) { float hfRef = static_cast(2.0 * M_PI) / m_effectiveSampleRate * HFReference(); float decayHFRatio = DecayHFRatio(); if(decayHFRatio > 1.0f) hfRef = static_cast(M_PI); float c1 = std::pow(10.0f, ((m_delayTaps[index] / m_effectiveSampleRate) * -60.0f / DecayTime()) / 20.0f); float c2 = 0.0f; float c21 = (std::pow(c1, 2.0f - 2.0f / decayHFRatio) - 1.0f) / (1.0f - std::cos(hfRef)); if(c21 != 0) { float c22 = -2.0f * c21 - 2.0f; float c23 = std::sqrt(c22 * c22 - c21 * c21 * 4.0f); c2 = (c23 - c22) / (c21 + c21); if(mpt::abs(c2) > 1.0) c2 = (-c22 - c23) / (c21 + c21); } m_delayCoeffs[index][0] = c1; m_delayCoeffs[index][1] = c2; c1 *= c1; float diff2 = m_diffusion * m_diffusion; return diff2 + c1 / (1.0f - diff2 * c1) * (1.0f - diff2) * (1.0f - diff2); } } // namespace DMO #else MPT_MSVC_WORKAROUND_LNK4221(I3DL2Reverb) #endif // !NO_PLUGINS OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/plugins/dmo/Flanger.h0000644000372100037210000000360113161656666022104 00000000000000/* * Flanger.h * --------- * Purpose: Implementation of the DMO Flanger DSP (for non-Windows platforms) * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #ifndef NO_PLUGINS #include "Chorus.h" OPENMPT_NAMESPACE_BEGIN namespace DMO { class Flanger : public Chorus { protected: enum Parameters { kFlangerWetDryMix = 0, kFlangerWaveShape, kFlangerFrequency, kFlangerDepth, kFlangerPhase, kFlangerFeedback, kFlangerDelay, kFlangerNumParameters }; public: static IMixPlugin* Create(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct); Flanger(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct); void Release() override { delete this; } int32 GetUID() const override { return 0xEFCA3D92; } PlugParamIndex GetNumParameters() const override { return kFlangerNumParameters; } void SetParameter(PlugParamIndex index, PlugParamValue value) override; #ifdef MODPLUG_TRACKER CString GetDefaultEffectName() override { return _T("Flanger"); } CString GetParamName(PlugParamIndex param) override; CString GetParamLabel(PlugParamIndex) override; CString GetParamDisplay(PlugParamIndex param) override; #endif protected: float WetDryMix() const override { return m_param[kFlangerWetDryMix]; } bool IsTriangle() const override { return m_param[kFlangerWaveShape] < 1; } float Depth() const override { return m_param[kFlangerDepth]; } float Feedback() const override { return -99.0f + m_param[kFlangerFeedback] * 198.0f; } float Delay() const override { return m_param[kFlangerDelay] * 4.0f; } float FrequencyInHertz() const override { return m_param[kFlangerFrequency] * 10.0f; } int Phase() const override { return Util::Round(m_param[kFlangerPhase] * 4.0f); } }; } // namespace DMO OPENMPT_NAMESPACE_END #endif // !NO_PLUGINS libopenmpt-0.3.6+release.autotools/soundlib/plugins/dmo/DMOPlugin.cpp0000644000372100037210000004130713161656666022664 00000000000000/* * DMOPlugin.h * ----------- * Purpose: DirectX Media Object plugin handling / processing. * Notes : Some default plugins only have the same output characteristics in the floating point code path (compared to integer PCM) * if we feed them input in the range [-32768, +32768] rather than the more usual [-1, +1]. * Hence, OpenMPT uses this range for both the floating-point and integer path. * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #ifndef NO_DMO #include "../../Sndfile.h" #include "../../../common/mptUUID.h" #include "DMOPlugin.h" #include "../PluginManager.h" #include #include #include #endif // !NO_DMO OPENMPT_NAMESPACE_BEGIN #ifndef NO_DMO #define DMO_LOG IMixPlugin* DMOPlugin::Create(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct) { CLSID clsid; if (Util::VerifyStringToCLSID(factory.dllPath.ToWide(), clsid)) { IMediaObject *pMO = nullptr; IMediaObjectInPlace *pMOIP = nullptr; if ((CoCreateInstance(clsid, nullptr, CLSCTX_INPROC_SERVER, IID_IMediaObject, (VOID **)&pMO) == S_OK) && (pMO)) { if (pMO->QueryInterface(IID_IMediaObjectInPlace, (void **)&pMOIP) != S_OK) pMOIP = nullptr; } else pMO = nullptr; if ((pMO) && (pMOIP)) { DWORD dwInputs = 0, dwOutputs = 0; pMO->GetStreamCount(&dwInputs, &dwOutputs); if (dwInputs == 1 && dwOutputs == 1) { DMOPlugin *p = new (std::nothrow) DMOPlugin(factory, sndFile, mixStruct, pMO, pMOIP, clsid.Data1); return p; } #ifdef DMO_LOG Log(factory.libraryName.ToUnicode() + MPT_USTRING(": Unable to use this DMO")); #endif } #ifdef DMO_LOG else Log(factory.libraryName.ToUnicode() + MPT_USTRING(": Failed to get IMediaObject & IMediaObjectInPlace interfaces")); #endif if (pMO) pMO->Release(); if (pMOIP) pMOIP->Release(); } return nullptr; } DMOPlugin::DMOPlugin(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct, IMediaObject *pMO, IMediaObjectInPlace *pMOIP, uint32 uid) : IMixPlugin(factory, sndFile, mixStruct) , m_pMediaObject(pMO) , m_pMediaProcess(pMOIP) , m_pParamInfo(nullptr) , m_pMediaParams(nullptr) , m_nSamplesPerSec(sndFile.GetSampleRate()) , m_uid(uid) { if(FAILED(m_pMediaObject->QueryInterface(IID_IMediaParamInfo, (void **)&m_pParamInfo))) m_pParamInfo = nullptr; if (FAILED(m_pMediaObject->QueryInterface(IID_IMediaParams, (void **)&m_pMediaParams))) m_pMediaParams = nullptr; m_alignedBuffer.f32 = (float *)((((intptr_t)m_interleavedBuffer.f32) + 15) & ~15); m_mixBuffer.Initialize(2, 2); InsertIntoFactoryList(); } DMOPlugin::~DMOPlugin() { if(m_pMediaParams) { m_pMediaParams->Release(); m_pMediaParams = nullptr; } if(m_pParamInfo) { m_pParamInfo->Release(); m_pParamInfo = nullptr; } if(m_pMediaProcess) { m_pMediaProcess->Release(); m_pMediaProcess = nullptr; } if(m_pMediaObject) { m_pMediaObject->Release(); m_pMediaObject = nullptr; } } uint32 DMOPlugin::GetLatency() const { REFERENCE_TIME time; // Unit 100-nanoseconds if(m_pMediaProcess->GetLatency(&time) == S_OK) { return static_cast(time * m_nSamplesPerSec / (10 * 1000 * 1000)); } return 0; } static const float _f2si = 32768.0f; static const float _si2f = 1.0f / 32768.0f; static void InterleaveStereo(const float * MPT_RESTRICT inputL, const float * MPT_RESTRICT inputR, float * MPT_RESTRICT output, uint32 numFrames) { #if (defined(ENABLE_SSE) || defined(ENABLE_SSE2)) if(GetProcSupport() & PROCSUPPORT_SSE) { // We may read beyond the wanted length... this works because we know that we will always work on our buffers of size MIXBUFFERSIZE STATIC_ASSERT((MIXBUFFERSIZE & 7) == 0); __m128 factor = _mm_set_ps1(_f2si); numFrames = (numFrames + 3) / 4; do { __m128 fl = _mm_loadu_ps(inputL); // Load four float values, LLLL __m128 fr = _mm_loadu_ps(inputR); // Load four float values, RRRR fl = _mm_mul_ps(fl, factor); // Scale them fr = _mm_mul_ps(fr, factor); // Scale them inputL += 4; inputR += 4; __m128 f1 = _mm_unpacklo_ps(fl, fr); // LL__+RR__ => LRLR __m128 f2 = _mm_unpackhi_ps(fl, fr); // __LL+__RR => LRLR _mm_store_ps(output, f1); // Store four int values, LRLR _mm_store_ps(output + 4, f2); // Store four int values, LRLR output += 8; } while(--numFrames); return; } #endif while(numFrames--) { *(output++) = *(inputL++) * _f2si; *(output++) = *(inputR++) * _f2si; } } static void DeinterleaveStereo(const float * MPT_RESTRICT input, float * MPT_RESTRICT outputL, float * MPT_RESTRICT outputR, uint32 numFrames) { #if (defined(ENABLE_SSE) || defined(ENABLE_SSE2)) if(GetProcSupport() & PROCSUPPORT_SSE) { // We may read beyond the wanted length... this works because we know that we will always work on our buffers of size MIXBUFFERSIZE STATIC_ASSERT((MIXBUFFERSIZE & 7) == 0); __m128 factor = _mm_set_ps1(_si2f); numFrames = (numFrames + 3) / 4; do { __m128 f1 = _mm_load_ps(input); // Load four float values, LRLR __m128 f2 = _mm_load_ps(input + 4); // Load four float values, LRLR f1 = _mm_mul_ps(f1, factor); // Scale them f2 = _mm_mul_ps(f2, factor); // Scale them input += 8; __m128 fl = _mm_shuffle_ps(f1, f2, _MM_SHUFFLE(2, 0, 2, 0)); // LRLR+LRLR => LLLL __m128 fr = _mm_shuffle_ps(f1, f2, _MM_SHUFFLE(3, 1, 3, 1)); // LRLR+LRLR => RRRR _mm_storeu_ps(outputL, fl); // Store four float values, LLLL _mm_storeu_ps(outputR, fr); // Store four float values, RRRR outputL += 4; outputR += 4; } while(--numFrames); return; } #endif while(numFrames--) { *(outputL++) = *(input++) * _si2f; *(outputR++) = *(input++) * _si2f; } } // Interleave two float streams into one int16 stereo stream. static void InterleaveFloatToInt16(const float * MPT_RESTRICT inputL, const float * MPT_RESTRICT inputR, int16 * MPT_RESTRICT output, uint32 numFrames) { #ifdef ENABLE_SSE // This uses __m64, so it's not available on the MSVC 64-bit compiler. // But if the user runs a 64-bit operating system, they will go the floating-point path anyway. if(GetProcSupport() & PROCSUPPORT_SSE) { // We may read beyond the wanted length... this works because we know that we will always work on our buffers of size MIXBUFFERSIZE STATIC_ASSERT((MIXBUFFERSIZE & 7) == 0); __m64 *out = reinterpret_cast<__m64 *>(output); __m128 factor = _mm_set_ps1(_f2si); numFrames = (numFrames + 3) / 4; do { __m128 fl = _mm_loadu_ps(inputL); // Load four float values, L1L2L3L4 __m128 fr = _mm_loadu_ps(inputR); // Load four float values, R1R2R3R4 fl = _mm_mul_ps(fl, factor); // Scale them fr = _mm_mul_ps(fr, factor); // Scale them inputL += 4; inputR += 4; // First two stereo pairs __m128 f12 = _mm_shuffle_ps(fl, fr, _MM_SHUFFLE(1, 0, 1, 0)); // L1 L2 R1 R2 f12 = _mm_shuffle_ps(f12 , f12, _MM_SHUFFLE(3, 1, 2, 0)); // L1 R1 L2 R2 __m64 i1 = _mm_cvtps_pi32(f12); // Convert to two ints, L1R1 f12 = _mm_shuffle_ps(f12 , f12, _MM_SHUFFLE(1, 0, 3, 2)); // L2 R2 L1 R1 __m64 i2 = _mm_cvtps_pi32(f12); // Convert to two ints, L2R2 __m64 sat12 = _mm_packs_pi32(i1, i2); // Pack and saturate them to 16-bit *(out++) = sat12; // Store L1R1L2R2 // Second two stereo pairs __m128 f34 = _mm_shuffle_ps(fl, fr, _MM_SHUFFLE(3, 1, 3, 1)); // L3 L4 R3 R4 f34 = _mm_shuffle_ps(f34 , f34, _MM_SHUFFLE(3, 1, 2, 0)); // L3 R3 L4 R4 __m64 i3 = _mm_cvtps_pi32(f34); // Convert to two ints, L3R3 f34 = _mm_shuffle_ps(f34 , f34, _MM_SHUFFLE(1, 0, 3, 2)); // L4 R4 L3 R3 __m64 i4 = _mm_cvtps_pi32(f34); // Convert to two ints, L4R4 __m64 sat34 = _mm_packs_pi32(i3, i4); // Pack and saturate them to 16-bit *(out++) = sat34; // Store L3R3L4R4 } while(--numFrames); _mm_empty(); return; } #endif while(numFrames--) { *(output++) = static_cast(Clamp(*(inputL++) * _f2si, static_cast(int16_min), static_cast(int16_max))); *(output++) = static_cast(Clamp(*(inputR++) * _f2si, static_cast(int16_min), static_cast(int16_max))); } } // Deinterleave an int16 stereo stream into two float streams. static void DeinterleaveInt16ToFloat(const int16 * MPT_RESTRICT input, float * MPT_RESTRICT outputL, float * MPT_RESTRICT outputR, uint32 numFrames) { #ifdef ENABLE_SSE // This uses __m64, so it's not available on the MSVC 64-bit compiler. // But if the user runs a 64-bit operating system, they will go the floating-point path anyway. if(GetProcSupport() & PROCSUPPORT_SSE) { // We may read beyond the wanted length... this works because we know that we will always work on our buffers of size MIXBUFFERSIZE STATIC_ASSERT((MIXBUFFERSIZE & 7) == 0); const __m128i *in = reinterpret_cast(input); __m128 factor = _mm_set_ps1(_si2f); numFrames = (numFrames + 3) / 4; do { __m128i in16 = _mm_load_si128(in); // Load eight int16 values, LRLRLRLR in++; __m128i lo = _mm_unpacklo_epi16(_mm_setzero_si128(), in16); // 0L0R0L0R (1) __m128i hi = _mm_unpackhi_epi16(_mm_setzero_si128(), in16); // 0L0R0L0R (2) lo = _mm_srai_epi32(lo, 16); // LsRsLsRs, s = sign (1) hi = _mm_srai_epi32(hi, 16); // LsRsLsRs, s = sign (2) __m64 lo1, lo2, hi1, hi2; _mm_storel_pi(&lo1, _mm_castsi128_ps(lo)); // L1R1 _mm_storeh_pi(&lo2, _mm_castsi128_ps(lo)); // L2R2 _mm_storel_pi(&hi1, _mm_castsi128_ps(hi)); // L3R3 _mm_storeh_pi(&hi2, _mm_castsi128_ps(hi)); // L4R4 __m128 f1 = _mm_cvt_pi2ps(_mm_setzero_ps(), lo1); // Convert to two floats, L1R1 __m128 f2 = _mm_cvt_pi2ps(_mm_setzero_ps(), lo2); // Convert to two floats, L2R2 f1 = _mm_shuffle_ps(f1, f1, _MM_SHUFFLE(1, 0, 1, 0)); // Move to upper f2 = _mm_shuffle_ps(f2, f2, _MM_SHUFFLE(1, 0, 1, 0)); // Move to upper f1 = _mm_cvt_pi2ps(f1, hi1); // Convert to two floats, L3R3 | L1R1 f2 = _mm_cvt_pi2ps(f2, hi2); // Convert to two floats, L4R4 | L2R2 __m128 fl = _mm_shuffle_ps(f1, f2, _MM_SHUFFLE(0, 2, 0, 2)); // => L1L3L2L4 __m128 fr = _mm_shuffle_ps(f1, f2, _MM_SHUFFLE(1, 3, 1, 3)); // => R1R3R2R4 fl = _mm_shuffle_ps(fl, fl, _MM_SHUFFLE(3, 1, 2, 0)); // => L1L2L3L4 fr = _mm_shuffle_ps(fr, fr, _MM_SHUFFLE(3, 1, 2, 0)); // => R1R2R3R4 fl = _mm_mul_ps(fl, factor); // Scale them fr = _mm_mul_ps(fr, factor); // Scale them _mm_storeu_ps(outputL, fl); // Store four float values, LLLL _mm_storeu_ps(outputR, fr); // Store four float values, RRRR outputL += 4; outputR += 4; } while(--numFrames); _mm_empty(); return; } #endif while(numFrames--) { *outputL++ += _si2f * static_cast(*input++); *outputR++ += _si2f * static_cast(*input++); } } void DMOPlugin::Process(float *pOutL, float *pOutR, uint32 numFrames) { if(!numFrames || !m_mixBuffer.Ok()) return; m_mixBuffer.ClearOutputBuffers(numFrames); REFERENCE_TIME startTime = Util::muldiv(m_SndFile.GetTotalSampleCount(), 10000000, m_nSamplesPerSec); if(m_useFloat) { InterleaveStereo(m_mixBuffer.GetInputBuffer(0), m_mixBuffer.GetInputBuffer(1), m_alignedBuffer.f32, numFrames); m_pMediaProcess->Process(numFrames * 2 * sizeof(float), reinterpret_cast(m_alignedBuffer.f32), startTime, DMO_INPLACE_NORMAL); DeinterleaveStereo(m_alignedBuffer.f32, m_mixBuffer.GetOutputBuffer(0), m_mixBuffer.GetOutputBuffer(1), numFrames); } else { InterleaveFloatToInt16(m_mixBuffer.GetInputBuffer(0), m_mixBuffer.GetInputBuffer(1), m_alignedBuffer.i16, numFrames); m_pMediaProcess->Process(numFrames * 2 * sizeof(int16), reinterpret_cast(m_alignedBuffer.i16), startTime, DMO_INPLACE_NORMAL); DeinterleaveInt16ToFloat(m_alignedBuffer.i16, m_mixBuffer.GetOutputBuffer(0), m_mixBuffer.GetOutputBuffer(1), numFrames); } ProcessMixOps(pOutL, pOutR, m_mixBuffer.GetOutputBuffer(0), m_mixBuffer.GetOutputBuffer(1), numFrames); } PlugParamIndex DMOPlugin::GetNumParameters() const { DWORD dwParamCount = 0; m_pParamInfo->GetParamCount(&dwParamCount); return dwParamCount; } PlugParamValue DMOPlugin::GetParameter(PlugParamIndex index) { if(index < GetNumParameters() && m_pParamInfo != nullptr && m_pMediaParams != nullptr) { MP_PARAMINFO mpi; MP_DATA md; MemsetZero(mpi); md = 0; if (m_pParamInfo->GetParamInfo(index, &mpi) == S_OK && m_pMediaParams->GetParam(index, &md) == S_OK) { float fValue, fMin, fMax, fDefault; fValue = md; fMin = mpi.mpdMinValue; fMax = mpi.mpdMaxValue; fDefault = mpi.mpdNeutralValue; if (mpi.mpType == MPT_BOOL) { fMin = 0; fMax = 1; } fValue -= fMin; if (fMax > fMin) fValue /= (fMax - fMin); return fValue; } } return 0; } void DMOPlugin::SetParameter(PlugParamIndex index, PlugParamValue value) { if(index < GetNumParameters() && m_pParamInfo != nullptr && m_pMediaParams != nullptr) { MP_PARAMINFO mpi; MemsetZero(mpi); if (m_pParamInfo->GetParamInfo(index, &mpi) == S_OK) { float fMin = mpi.mpdMinValue; float fMax = mpi.mpdMaxValue; if (mpi.mpType == MPT_BOOL) { fMin = 0; fMax = 1; value = (value > 0.5f) ? 1.0f : 0.0f; } if (fMax > fMin) value *= (fMax - fMin); value += fMin; Limit(value, fMin, fMax); if (mpi.mpType != MPT_FLOAT) value = Util::Round(value); m_pMediaParams->SetParam(index, value); } } } void DMOPlugin::Resume() { m_nSamplesPerSec = m_SndFile.GetSampleRate(); m_isResumed = true; DMO_MEDIA_TYPE mt; WAVEFORMATEX wfx; mt.majortype = MEDIATYPE_Audio; mt.subtype = MEDIASUBTYPE_PCM; mt.bFixedSizeSamples = TRUE; mt.bTemporalCompression = FALSE; mt.formattype = FORMAT_WaveFormatEx; mt.pUnk = nullptr; mt.pbFormat = (LPBYTE)&wfx; mt.cbFormat = sizeof(WAVEFORMATEX); mt.lSampleSize = 2 * sizeof(float); wfx.wFormatTag = 3; // WAVE_FORMAT_IEEE_FLOAT; wfx.nChannels = 2; wfx.nSamplesPerSec = m_nSamplesPerSec; wfx.wBitsPerSample = sizeof(float) * 8; wfx.nBlockAlign = wfx.nChannels * (wfx.wBitsPerSample / 8); wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; wfx.cbSize = 0; // First try 32-bit float (DirectX 9+) m_useFloat = true; if(FAILED(m_pMediaObject->SetInputType(0, &mt, 0)) || FAILED(m_pMediaObject->SetOutputType(0, &mt, 0))) { m_useFloat = false; // Try again with 16-bit PCM mt.lSampleSize = 2 * sizeof(int16); wfx.wFormatTag = WAVE_FORMAT_PCM; wfx.wBitsPerSample = sizeof(int16) * 8; wfx.nBlockAlign = wfx.nChannels * (wfx.wBitsPerSample / 8); wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; if(FAILED(m_pMediaObject->SetInputType(0, &mt, 0)) || FAILED(m_pMediaObject->SetOutputType(0, &mt, 0))) { #ifdef DMO_LOG Log(MPT_USTRING("DMO: Failed to set I/O media type")); #endif } } } void DMOPlugin::PositionChanged() { m_pMediaObject->Discontinuity(0); m_pMediaObject->Flush(); } void DMOPlugin::Suspend() { m_isResumed = false; m_pMediaObject->Flush(); m_pMediaObject->SetInputType(0, nullptr, DMO_SET_TYPEF_CLEAR); m_pMediaObject->SetOutputType(0, nullptr, DMO_SET_TYPEF_CLEAR); } #ifdef MODPLUG_TRACKER CString DMOPlugin::GetParamName(PlugParamIndex param) { if(param < GetNumParameters() && m_pParamInfo != nullptr) { MP_PARAMINFO mpi; mpi.mpType = MPT_INT; mpi.szUnitText[0] = 0; mpi.szLabel[0] = 0; if(m_pParamInfo->GetParamInfo(param, &mpi) == S_OK) { return mpi.szLabel; } } return CString(); } CString DMOPlugin::GetParamLabel(PlugParamIndex param) { if(param < GetNumParameters() && m_pParamInfo != nullptr) { MP_PARAMINFO mpi; mpi.mpType = MPT_INT; mpi.szUnitText[0] = 0; mpi.szLabel[0] = 0; if(m_pParamInfo->GetParamInfo(param, &mpi) == S_OK) { return mpi.szUnitText; } } return CString(); } CString DMOPlugin::GetParamDisplay(PlugParamIndex param) { if(param < GetNumParameters() && m_pParamInfo != nullptr && m_pMediaParams != nullptr) { MP_PARAMINFO mpi; mpi.mpType = MPT_INT; mpi.szUnitText[0] = 0; mpi.szLabel[0] = 0; if (m_pParamInfo->GetParamInfo(param, &mpi) == S_OK) { MP_DATA md; if(m_pMediaParams->GetParam(param, &md) == S_OK) { switch(mpi.mpType) { case MPT_FLOAT: { CString s; s.Format(_T("%.2f"), md); return s; } break; case MPT_BOOL: return ((int)md) ? _T("Yes") : _T("No"); break; case MPT_ENUM: { WCHAR *text = nullptr; m_pParamInfo->GetParamText(param, &text); const int nValue = Util::Round(md * (mpi.mpdMaxValue - mpi.mpdMinValue)); // Always skip first two strings (param name, unit name) for(int i = 0; i < nValue + 2; i++) { text += wcslen(text) + 1; } return CString(text); } break; case MPT_INT: default: { CString s; s.Format(_T("%d"), Util::Round(md)); return s; } break; } } } } return CString(); } #endif // MODPLUG_TRACKER #else // NO_DMO MPT_MSVC_WORKAROUND_LNK4221(DMOPlugin) #endif // !NO_DMO OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/plugins/dmo/Distortion.h0000644000372100037210000000544513161656666022674 00000000000000/* * Distortion.h * ------------ * Purpose: Implementation of the DMO Distortion DSP (for non-Windows platforms) * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #ifndef NO_PLUGINS #include "../PlugInterface.h" OPENMPT_NAMESPACE_BEGIN namespace DMO { class Distortion : public IMixPlugin { protected: enum Parameters { kDistGain = 0, kDistEdge, kDistPreLowpassCutoff, kDistPostEQCenterFrequency, kDistPostEQBandwidth, kDistNumParameters }; float m_param[kDistNumParameters]; // Pre-EQ coefficients float m_preEQz1[2], m_preEQb1, m_preEQa0; // Post-EQ coefficients float m_postEQz1[2], m_postEQz2[2], m_postEQa0, m_postEQb0, m_postEQb1; uint8 m_edge, m_shift; public: static IMixPlugin* Create(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct); Distortion(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct); void Release() override { delete this; } int32 GetUID() const override { return 0xEF114C90; } int32 GetVersion() const override { return 0; } void Idle() override { } uint32 GetLatency() const override { return 0; } void Process(float *pOutL, float *pOutR, uint32 numFrames) override; float RenderSilence(uint32) override { return 0.0f; } int32 GetNumPrograms() const override { return 0; } int32 GetCurrentProgram() override { return 0; } void SetCurrentProgram(int32) override { } PlugParamIndex GetNumParameters() const override { return kDistNumParameters; } PlugParamValue GetParameter(PlugParamIndex index) override; void SetParameter(PlugParamIndex index, PlugParamValue value) override; void Resume() override; void Suspend() override { m_isResumed = false; } void PositionChanged() override; bool IsInstrument() const override { return false; } bool CanRecieveMidiEvents() override { return false; } bool ShouldProcessSilence() override { return true; } #ifdef MODPLUG_TRACKER CString GetDefaultEffectName() override { return _T("Distortion"); } CString GetParamName(PlugParamIndex param) override; CString GetParamLabel(PlugParamIndex) override; CString GetParamDisplay(PlugParamIndex param) override; CString GetCurrentProgramName() override { return CString(); } void SetCurrentProgramName(const CString &) override { } CString GetProgramName(int32) override { return CString(); } bool HasEditor() const override { return false; } #endif int GetNumInputChannels() const override { return 2; } int GetNumOutputChannels() const override { return 2; } protected: static float FreqInHertz(float param) { return 100.0f + param * 7900.0f; } float GainInDecibel() const { return -60.0f + m_param[kDistGain] * 60.0f; } void RecalculateDistortionParams(); }; } // namespace DMO OPENMPT_NAMESPACE_END #endif // !NO_PLUGINS libopenmpt-0.3.6+release.autotools/soundlib/plugins/dmo/Gargle.h0000644000372100037210000000471713161656666021740 00000000000000/* * Gargle.h * -------- * Purpose: Implementation of the DMO Gargle DSP (for non-Windows platforms) * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #ifndef NO_PLUGINS #include "../PlugInterface.h" OPENMPT_NAMESPACE_BEGIN namespace DMO { class Gargle : public IMixPlugin { protected: enum Parameters { kGargleRate = 0, kGargleWaveShape, kEqNumParameters }; float m_param[kEqNumParameters]; uint32 m_period, m_periodHalf, m_counter; // In frames public: static IMixPlugin* Create(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct); Gargle(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct); void Release() override { delete this; } int32 GetUID() const override { return 0xDAFD8210; } int32 GetVersion() const override { return 0; } void Idle() override { } uint32 GetLatency() const override { return 0; } void Process(float *pOutL, float *pOutR, uint32 numFrames) override; float RenderSilence(uint32) override { return 0.0f; } int32 GetNumPrograms() const override { return 0; } int32 GetCurrentProgram() override { return 0; } void SetCurrentProgram(int32) override { } PlugParamIndex GetNumParameters() const override { return kEqNumParameters; } PlugParamValue GetParameter(PlugParamIndex index) override; void SetParameter(PlugParamIndex index, PlugParamValue value) override; void Resume() override; void Suspend() override { m_isResumed = false; } void PositionChanged() override { m_counter = 0; } bool IsInstrument() const override { return false; } bool CanRecieveMidiEvents() override { return false; } bool ShouldProcessSilence() override { return true; } #ifdef MODPLUG_TRACKER CString GetDefaultEffectName() override { return _T("Gargle"); } CString GetParamName(PlugParamIndex param) override; CString GetParamLabel(PlugParamIndex) override; CString GetParamDisplay(PlugParamIndex param) override; CString GetCurrentProgramName() override { return CString(); } void SetCurrentProgramName(const CString &) override { } CString GetProgramName(int32) override { return CString(); } bool HasEditor() const override { return false; } #endif int GetNumInputChannels() const override { return 2; } int GetNumOutputChannels() const override { return 2; } protected: uint32 RateInHertz() const; void RecalculateGargleParams(); }; } // namespace DMO OPENMPT_NAMESPACE_END #endif // !NO_PLUGINS libopenmpt-0.3.6+release.autotools/soundlib/plugins/PlugInterface.cpp0000644000372100037210000006500013177330265023022 00000000000000/* * PlugInterface.cpp * ----------------- * Purpose: Default plugin interface implementation * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "../Sndfile.h" #include "PlugInterface.h" #include "PluginManager.h" #include "../../common/FileReader.h" #ifdef MODPLUG_TRACKER #include "../../mptrack/Moddoc.h" #include "../../mptrack/Mainfrm.h" #include "../../mptrack/InputHandler.h" #include "../../mptrack/AbstractVstEditor.h" #include "../../mptrack/DefaultVstEditor.h" // LoadProgram/SaveProgram #include "../../mptrack/FileDialog.h" #include "../../mptrack/VstPresets.h" #include "../../common/mptFileIO.h" #include "../mod_specifications.h" #endif // MODPLUG_TRACKER #include #ifndef NO_PLUGINS OPENMPT_NAMESPACE_BEGIN #ifdef MODPLUG_TRACKER CModDoc *IMixPlugin::GetModDoc() { return m_SndFile.GetpModDoc(); } const CModDoc *IMixPlugin::GetModDoc() const { return m_SndFile.GetpModDoc(); } #endif // MODPLUG_TRACKER IMixPlugin::IMixPlugin(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct) : m_pNext(nullptr) , m_pPrev(nullptr) , m_Factory(factory) , m_SndFile(sndFile) , m_pMixStruct(mixStruct) #ifdef MODPLUG_TRACKER , m_pEditor(nullptr) #endif // MODPLUG_TRACKER , m_fGain(1.0f) , m_nSlot(0) , m_isSongPlaying(false) , m_isResumed(false) , m_recordAutomation(false) , m_passKeypressesToPlug(false) , m_recordMIDIOut(false) { m_MixState.pMixBuffer = (mixsample_t *)((((intptr_t)m_MixBuffer) + 7) & ~7); m_MixState.dwFlags = 0; m_MixState.nVolDecayL = 0; m_MixState.nVolDecayR = 0; while(m_pMixStruct != &(m_SndFile.m_MixPlugins[m_nSlot]) && m_nSlot < MAX_MIXPLUGINS - 1) { m_nSlot++; } } IMixPlugin::~IMixPlugin() { #ifdef MODPLUG_TRACKER CloseEditor(); CriticalSection cs; #endif // MODPLUG_TRACKER // First thing to do, if we don't want to hang in a loop if (m_Factory.pPluginsList == this) m_Factory.pPluginsList = m_pNext; if (m_pMixStruct) { m_pMixStruct->pMixPlugin = nullptr; m_pMixStruct = nullptr; } if (m_pNext) m_pNext->m_pPrev = m_pPrev; if (m_pPrev) m_pPrev->m_pNext = m_pNext; m_pPrev = nullptr; m_pNext = nullptr; } void IMixPlugin::InsertIntoFactoryList() { m_pMixStruct->pMixPlugin = this; m_pNext = m_Factory.pPluginsList; if(m_Factory.pPluginsList) { m_Factory.pPluginsList->m_pPrev = this; } m_Factory.pPluginsList = this; } #ifdef MODPLUG_TRACKER void IMixPlugin::SetSlot(PLUGINDEX slot) { m_nSlot = slot; m_pMixStruct = &m_SndFile.m_MixPlugins[slot]; } CString IMixPlugin::GetFormattedParamName(PlugParamIndex param) { CString paramName = GetParamName(param); CString name; if(paramName.IsEmpty()) { name.Format(_T("%02u: Parameter %02u"), param, param); } else { name.Format(_T("%02u: %s"), param, paramName.GetString()); } return name; } // Get a parameter's current value, represented by the plugin. CString IMixPlugin::GetFormattedParamValue(PlugParamIndex param) { CString paramDisplay = GetParamDisplay(param); CString paramUnits = GetParamLabel(param); paramDisplay.Trim(); paramUnits.Trim(); paramDisplay += _T(" ") + paramUnits; return paramDisplay; } CString IMixPlugin::GetFormattedProgramName(int32 index) { CString rawname = GetProgramName(index); // Let's start counting at 1 for the program name (as most MIDI hardware / software does) index++; CString formattedName; if(rawname[0] >= 0 && rawname[0] < _T(' ')) formattedName.Format(_T("%02u - Program %u"), index, index); else formattedName.Format(_T("%02u - %s"), index, rawname.GetString()); return formattedName; } void IMixPlugin::SetEditorPos(int32 x, int32 y) { m_pMixStruct->editorX = x; m_pMixStruct->editorY = y; } void IMixPlugin::GetEditorPos(int32 &x, int32 &y) const { x = m_pMixStruct->editorX; y = m_pMixStruct->editorY; } #endif // MODPLUG_TRACKER bool IMixPlugin::IsBypassed() const { return m_pMixStruct != nullptr && m_pMixStruct->IsBypassed(); } void IMixPlugin::RecalculateGain() { float gain = 0.1f * static_cast(m_pMixStruct ? m_pMixStruct->GetGain() : 10); if(gain < 0.1f) gain = 1.0f; if(IsInstrument()) { gain /= m_SndFile.GetPlayConfig().getVSTiAttenuation(); gain = static_cast(gain * (m_SndFile.m_nVSTiVolume / m_SndFile.GetPlayConfig().getNormalVSTiVol())); } m_fGain = gain; } void IMixPlugin::SetDryRatio(uint32 param) { param = std::min(param, uint32(127)); m_pMixStruct->fDryRatio = 1.0f - (param / 127.0f); } void IMixPlugin::Bypass(bool bypass) { m_pMixStruct->Info.SetBypass(bypass); #ifdef MODPLUG_TRACKER if(m_SndFile.GetpModDoc()) m_SndFile.GetpModDoc()->UpdateAllViews(nullptr, PluginHint(m_nSlot + 1).Info(), nullptr); #endif // MODPLUG_TRACKER } double IMixPlugin::GetOutputLatency() const { if(GetSoundFile().IsRenderingToDisc()) return 0; else return GetSoundFile().m_TimingInfo.OutputLatency; } void IMixPlugin::ProcessMixOps(float * MPT_RESTRICT pOutL, float * MPT_RESTRICT pOutR, float * MPT_RESTRICT leftPlugOutput, float * MPT_RESTRICT rightPlugOutput, uint32 numFrames) const { /* float *leftPlugOutput; float *rightPlugOutput; if(m_Effect.numOutputs == 1) { // If there was just the one plugin output we copy it into our 2 outputs leftPlugOutput = rightPlugOutput = mixBuffer.GetOutputBuffer(0); } else if(m_Effect.numOutputs > 1) { // Otherwise we actually only cater for two outputs max (outputs > 2 have been mixed together already). leftPlugOutput = mixBuffer.GetOutputBuffer(0); rightPlugOutput = mixBuffer.GetOutputBuffer(1); } else { return; }*/ // -> mixop == 0 : normal processing // -> mixop == 1 : MIX += DRY - WET * wetRatio // -> mixop == 2 : MIX += WET - DRY * dryRatio // -> mixop == 3 : MIX -= WET - DRY * wetRatio // -> mixop == 4 : MIX -= middle - WET * wetRatio + middle - DRY // -> mixop == 5 : MIX_L += wetRatio * (WET_L - DRY_L) + dryRatio * (DRY_R - WET_R) // MIX_R += dryRatio * (WET_L - DRY_L) + wetRatio * (DRY_R - WET_R) MPT_ASSERT(m_pMixStruct != nullptr); int mixop; if(IsInstrument()) { // Force normal mix mode for instruments mixop = 0; } else { mixop = m_pMixStruct->GetMixMode(); } float wetRatio = 1 - m_pMixStruct->fDryRatio; float dryRatio = IsInstrument() ? 1 : m_pMixStruct->fDryRatio; // Always mix full dry if this is an instrument // Wet / Dry range expansion [0,1] -> [-1,1] if(GetNumInputChannels() > 0 && m_pMixStruct->IsExpandedMix()) { wetRatio = 2.0f * wetRatio - 1.0f; dryRatio = -wetRatio; } wetRatio *= m_fGain; dryRatio *= m_fGain; float * MPT_RESTRICT plugInputL = m_mixBuffer.GetInputBuffer(0); float * MPT_RESTRICT plugInputR = m_mixBuffer.GetInputBuffer(1); // Mix operation switch(mixop) { // Default mix case 0: for(uint32 i = 0; i < numFrames; i++) { //rewbs.wetratio - added the factors. [20040123] pOutL[i] += leftPlugOutput[i] * wetRatio + plugInputL[i] * dryRatio; pOutR[i] += rightPlugOutput[i] * wetRatio + plugInputR[i] * dryRatio; } break; // Wet subtract case 1: for(uint32 i = 0; i < numFrames; i++) { pOutL[i] += plugInputL[i] - leftPlugOutput[i] * wetRatio; pOutR[i] += plugInputR[i] - rightPlugOutput[i] * wetRatio; } break; // Dry subtract case 2: for(uint32 i = 0; i < numFrames; i++) { pOutL[i] += leftPlugOutput[i] - plugInputL[i] * dryRatio; pOutR[i] += rightPlugOutput[i] - plugInputR[i] * dryRatio; } break; // Mix subtract case 3: for(uint32 i = 0; i < numFrames; i++) { pOutL[i] -= leftPlugOutput[i] - plugInputL[i] * wetRatio; pOutR[i] -= rightPlugOutput[i] - plugInputR[i] * wetRatio; } break; // Middle subtract case 4: for(uint32 i = 0; i < numFrames; i++) { float middle = (pOutL[i] + plugInputL[i] + pOutR[i] + plugInputR[i]) / 2.0f; pOutL[i] -= middle - leftPlugOutput[i] * wetRatio + middle - plugInputL[i]; pOutR[i] -= middle - rightPlugOutput[i] * wetRatio + middle - plugInputR[i]; } break; // Left / Right balance case 5: if(m_pMixStruct->IsExpandedMix()) { wetRatio /= 2.0f; dryRatio /= 2.0f; } for(uint32 i = 0; i < numFrames; i++) { pOutL[i] += wetRatio * (leftPlugOutput[i] - plugInputL[i]) + dryRatio * (plugInputR[i] - rightPlugOutput[i]); pOutR[i] += dryRatio * (leftPlugOutput[i] - plugInputL[i]) + wetRatio * (plugInputR[i] - rightPlugOutput[i]); } break; } // If dry mix is ticked, we add the unprocessed buffer, // except if this is an instrument since then it has already been done: if(m_pMixStruct->IsWetMix() && !IsInstrument()) { for(uint32 i = 0; i < numFrames; i++) { pOutL[i] += plugInputL[i]; pOutR[i] += plugInputR[i]; } } } // Render some silence and return maximum level returned by the plugin. float IMixPlugin::RenderSilence(uint32 numFrames) { // The JUCE framework doesn't like processing while being suspended. const bool wasSuspended = !IsResumed(); if(wasSuspended) { Resume(); } float out[2][MIXBUFFERSIZE]; // scratch buffers float maxVal = 0.0f; m_mixBuffer.ClearInputBuffers(MIXBUFFERSIZE); while(numFrames > 0) { uint32 renderSamples = numFrames; LimitMax(renderSamples, mpt::saturate_cast(MPT_ARRAY_COUNT(out[0]))); MemsetZero(out); Process(out[0], out[1], renderSamples); for(size_t i = 0; i < renderSamples; i++) { maxVal = std::max(maxVal, std::fabs(out[0][i])); maxVal = std::max(maxVal, std::fabs(out[1][i])); } numFrames -= renderSamples; } if(wasSuspended) { Suspend(); } return maxVal; } // Get list of plugins to which output is sent. A nullptr indicates master output. size_t IMixPlugin::GetOutputPlugList(std::vector &list) { // At the moment we know there will only be 1 output. // Returning nullptr means plugin outputs directly to master. list.clear(); IMixPlugin *outputPlug = nullptr; if(!m_pMixStruct->IsOutputToMaster()) { PLUGINDEX nOutput = m_pMixStruct->GetOutputPlugin(); if(nOutput > m_nSlot && nOutput != PLUGINDEX_INVALID) { outputPlug = m_SndFile.m_MixPlugins[nOutput].pMixPlugin; } } list.push_back(outputPlug); return 1; } // Get a list of plugins that send data to this plugin. size_t IMixPlugin::GetInputPlugList(std::vector &list) { std::vector candidatePlugOutputs; list.clear(); for(PLUGINDEX plug = 0; plug < MAX_MIXPLUGINS; plug++) { IMixPlugin *candidatePlug = m_SndFile.m_MixPlugins[plug].pMixPlugin; if(candidatePlug) { candidatePlug->GetOutputPlugList(candidatePlugOutputs); for(auto &outPlug : candidatePlugOutputs) { if(outPlug == this) { list.push_back(candidatePlug); break; } } } } return list.size(); } // Get a list of instruments that send data to this plugin. size_t IMixPlugin::GetInputInstrumentList(std::vector &list) { list.clear(); const PLUGINDEX nThisMixPlug = m_nSlot + 1; //m_nSlot is position in mixplug array. for(INSTRUMENTINDEX ins = 0; ins <= m_SndFile.GetNumInstruments(); ins++) { if(m_SndFile.Instruments[ins] != nullptr && m_SndFile.Instruments[ins]->nMixPlug == nThisMixPlug) { list.push_back(ins); } } return list.size(); } size_t IMixPlugin::GetInputChannelList(std::vector &list) { list.clear(); PLUGINDEX nThisMixPlug = m_nSlot + 1; //m_nSlot is position in mixplug array. const CHANNELINDEX chnCount = m_SndFile.GetNumChannels(); for(CHANNELINDEX nChn=0; nChndefaultProgram = -1; // Default implementation: Save all parameter values PlugParamIndex numParams = std::min(GetNumParameters(), (std::numeric_limits::max() - sizeof(uint32)) / sizeof(IEEE754binary32LE)); uint32 nLen = numParams * sizeof(IEEE754binary32LE); if (!nLen) return; nLen += sizeof(uint32); try { m_pMixStruct->pluginData.resize(nLen); auto memFile = std::make_pair(mpt::as_span(m_pMixStruct->pluginData), mpt::IO::Offset(0)); mpt::IO::WriteIntLE(memFile, 0); // Plugin data type for(PlugParamIndex i = 0; i < numParams; i++) { mpt::IO::Write(memFile, IEEE754binary32LE(GetParameter(i))); } } MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e) { m_pMixStruct->pluginData.clear(); MPT_EXCEPTION_DELETE_OUT_OF_MEMORY(e); } } void IMixPlugin::RestoreAllParameters(int32 /*program*/) { if(m_pMixStruct != nullptr && m_pMixStruct->pluginData.size() >= sizeof(uint32)) { FileReader memFile(mpt::as_span(m_pMixStruct->pluginData)); uint32 type = memFile.ReadUint32LE(); if(type == 0) { const uint32 numParams = GetNumParameters(); if((m_pMixStruct->pluginData.size() - sizeof(uint32)) >= (numParams * sizeof(IEEE754binary32LE))) { BeginSetProgram(-1); for(uint32 i = 0; i < numParams; i++) { SetParameter(i, memFile.ReadFloatLE()); } EndSetProgram(); } } } } #ifdef MODPLUG_TRACKER void IMixPlugin::ToggleEditor() { // We only really need this mutex for bridged plugins, as we may be processing window messages (in the same thread) while the editor opens. // The user could press the toggle button while the editor is loading and thus close the editor while still being initialized. // Note that this does not protect against closing the module while the editor is still loading. static bool initializing = false; if(initializing) return; initializing = true; if (m_pEditor) { CloseEditor(); } else { m_pEditor = OpenEditor(); if (m_pEditor) m_pEditor->OpenEditor(CMainFrame::GetMainFrame()); } initializing = false; } // Provide default plugin editor CAbstractVstEditor *IMixPlugin::OpenEditor() { try { return new CDefaultVstEditor(*this); } MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e) { MPT_EXCEPTION_DELETE_OUT_OF_MEMORY(e); return nullptr; } } void IMixPlugin::CloseEditor() { if(m_pEditor) { if (m_pEditor->m_hWnd) m_pEditor->DoClose(); delete m_pEditor; m_pEditor = nullptr; } } // Automate a parameter from the plugin GUI (both custom and default plugin GUI) void IMixPlugin::AutomateParameter(PlugParamIndex param) { CModDoc *modDoc = GetModDoc(); if(modDoc == nullptr) { return; } // TODO: Check if any params are actually automatable, and if there are but this one isn't, chicken out if(m_recordAutomation) { // Record parameter change modDoc->RecordParamChange(GetSlot(), param); } modDoc->PostMessageToAllViews(WM_MOD_PLUGPARAMAUTOMATE, m_nSlot, param); // TODO: This should rather be posted to the GUI thread! CAbstractVstEditor *pVstEditor = GetEditor(); if(pVstEditor && pVstEditor->m_hWnd) { // Mark track modified if GUI is open and format supports plugins SetModified(); if (CMainFrame::GetInputHandler()->ShiftPressed() && TrackerSettings::Instance().midiMappingInPluginEditor) { // Shift pressed -> Open MIDI mapping dialog CMainFrame::GetInputHandler()->SetModifierMask(ModNone); // Make sure that the dialog will open only once. CMainFrame::GetMainFrame()->PostMessage(WM_MOD_MIDIMAPPING, m_nSlot, param); } // Learn macro int macroToLearn = pVstEditor->GetLearnMacro(); if (macroToLearn > -1) { modDoc->LearnMacro(macroToLearn, param); pVstEditor->SetLearnMacro(-1); } } } void IMixPlugin::SetModified() { CModDoc *modDoc = GetModDoc(); if(modDoc != nullptr && m_SndFile.GetModSpecifications().supportsPlugins) { modDoc->SetModified(); } } bool IMixPlugin::SaveProgram() { mpt::PathString defaultDir = TrackerSettings::Instance().PathPluginPresets.GetWorkingDir(); bool useDefaultDir = !defaultDir.empty(); if(!useDefaultDir && m_Factory.dllPath.IsFile()) { defaultDir = m_Factory.dllPath.GetPath(); } CString progName = GetCurrentProgramName(); SanitizeFilename(progName); FileDialog dlg = SaveFileDialog() .DefaultExtension("fxb") .DefaultFilename(progName) .ExtensionFilter("VST Plugin Programs (*.fxp)|*.fxp|" "VST Plugin Banks (*.fxb)|*.fxb||") .WorkingDirectory(defaultDir); if(!dlg.Show(m_pEditor)) return false; if(useDefaultDir) { TrackerSettings::Instance().PathPluginPresets.SetWorkingDir(dlg.GetWorkingDirectory()); } bool bank = (dlg.GetExtension() == MPT_PATHSTRING("fxb")); mpt::fstream f(dlg.GetFirstFile(), std::ios::out | std::ios::trunc | std::ios::binary); if(f.good() && VSTPresets::SaveFile(f, *this, bank)) { return true; } else { Reporting::Error("Error saving preset.", m_pEditor); return false; } } bool IMixPlugin::LoadProgram(mpt::PathString fileName) { mpt::PathString defaultDir = TrackerSettings::Instance().PathPluginPresets.GetWorkingDir(); bool useDefaultDir = !defaultDir.empty(); if(!useDefaultDir && m_Factory.dllPath.IsFile()) { defaultDir = m_Factory.dllPath.GetPath(); } if(fileName.empty()) { FileDialog dlg = OpenFileDialog() .DefaultExtension("fxp") .ExtensionFilter("VST Plugin Programs and Banks (*.fxp,*.fxb)|*.fxp;*.fxb|" "VST Plugin Programs (*.fxp)|*.fxp|" "VST Plugin Banks (*.fxb)|*.fxb|" "All Files|*.*||") .WorkingDirectory(defaultDir); if(!dlg.Show(m_pEditor)) return false; if(useDefaultDir) { TrackerSettings::Instance().PathPluginPresets.SetWorkingDir(dlg.GetWorkingDirectory()); } fileName = dlg.GetFirstFile(); } const char *errorStr = nullptr; InputFile f(fileName); if(f.IsValid()) { FileReader file = GetFileReader(f); errorStr = VSTPresets::GetErrorMessage(VSTPresets::LoadFile(file, *this)); } else { errorStr = "Can't open file."; } if(errorStr == nullptr) { if(GetModDoc() != nullptr && GetSoundFile().GetModSpecifications().supportsPlugins) { GetModDoc()->SetModified(); } return true; } else { Reporting::Error(errorStr, m_pEditor); return false; } } #endif // MODPLUG_TRACKER //////////////////////////////////////////////////////////////////// // IMidiPlugin: Default implementation of plugins with MIDI input // //////////////////////////////////////////////////////////////////// IMidiPlugin::IMidiPlugin(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct) : IMixPlugin(factory, sndFile, mixStruct) { MemsetZero(m_MidiCh); for(int ch = 0; ch < 16; ch++) { m_MidiCh[ch].midiPitchBendPos = EncodePitchBendParam(MIDIEvents::pitchBendCentre); // centre pitch bend on all channels m_MidiCh[ch].ResetProgram(); } } void IMidiPlugin::ApplyPitchWheelDepth(int32 &value, int8 pwd) { if(pwd != 0) { value = (value * ((MIDIEvents::pitchBendMax - MIDIEvents::pitchBendCentre + 1) / 64)) / pwd; } else { value = 0; } } void IMidiPlugin::MidiCC(uint8 nMidiCh, MIDIEvents::MidiCC nController, uint8 nParam, CHANNELINDEX /*trackChannel*/) { //Error checking LimitMax(nController, MIDIEvents::MIDICC_end); LimitMax(nParam, uint8(127)); if(m_SndFile.m_playBehaviour[kMIDICCBugEmulation]) MidiSend(MIDIEvents::Event(MIDIEvents::evControllerChange, nMidiCh, nParam, static_cast(nController))); // param and controller are swapped (old broken implementation) else MidiSend(MIDIEvents::CC(nController, nMidiCh, nParam)); } // Bend MIDI pitch for given MIDI channel using fine tracker param (one unit = 1/64th of a note step) void IMidiPlugin::MidiPitchBend(uint8 nMidiCh, int32 increment, int8 pwd) { if(m_SndFile.m_playBehaviour[kOldMIDIPitchBends]) { // OpenMPT Legacy: Old pitch slides never were really accurate, but setting the PWD to 13 in plugins would give the closest results. increment = (increment * 0x800 * 13) / (0xFF * pwd); increment = EncodePitchBendParam(increment); } else { increment = EncodePitchBendParam(increment); ApplyPitchWheelDepth(increment, pwd); } int32 newPitchBendPos = (increment + m_MidiCh[nMidiCh].midiPitchBendPos) & vstPitchBendMask; Limit(newPitchBendPos, EncodePitchBendParam(MIDIEvents::pitchBendMin), EncodePitchBendParam(MIDIEvents::pitchBendMax)); MidiPitchBend(nMidiCh, newPitchBendPos); } // Set MIDI pitch for given MIDI channel using fixed point pitch bend value (converted back to 0-16383 MIDI range) void IMidiPlugin::MidiPitchBend(uint8 nMidiCh, int32 newPitchBendPos) { MPT_ASSERT(EncodePitchBendParam(MIDIEvents::pitchBendMin) <= newPitchBendPos && newPitchBendPos <= EncodePitchBendParam(MIDIEvents::pitchBendMax)); m_MidiCh[nMidiCh].midiPitchBendPos = newPitchBendPos; MidiSend(MIDIEvents::PitchBend(nMidiCh, DecodePitchBendParam(newPitchBendPos))); } // Apply vibrato effect through pitch wheel commands on a given MIDI channel. void IMidiPlugin::MidiVibrato(uint8 nMidiCh, int32 depth, int8 pwd) { depth = EncodePitchBendParam(depth); if(depth != 0 || (m_MidiCh[nMidiCh].midiPitchBendPos & vstVibratoFlag)) { ApplyPitchWheelDepth(depth, pwd); // Temporarily add vibrato offset to current pitch int32 newPitchBendPos = (depth + m_MidiCh[nMidiCh].midiPitchBendPos) & vstPitchBendMask; Limit(newPitchBendPos, EncodePitchBendParam(MIDIEvents::pitchBendMin), EncodePitchBendParam(MIDIEvents::pitchBendMax)); MidiSend(MIDIEvents::PitchBend(nMidiCh, DecodePitchBendParam(newPitchBendPos))); } // Update vibrato status if(depth != 0) { m_MidiCh[nMidiCh].midiPitchBendPos |= vstVibratoFlag; } else { m_MidiCh[nMidiCh].midiPitchBendPos &= ~vstVibratoFlag; } } void IMidiPlugin::MidiCommand(uint8 nMidiCh, uint8 nMidiProg, uint16 wMidiBank, uint16 note, uint16 vol, CHANNELINDEX trackChannel) { PlugInstrChannel &channel = m_MidiCh[nMidiCh]; bool bankChanged = (channel.currentBank != --wMidiBank) && (wMidiBank < 0x4000); bool progChanged = (channel.currentProgram != --nMidiProg) && (nMidiProg < 0x80); //get vol in [0,128[ uint8 volume = static_cast(std::min(vol / 2, 127)); // Bank change if(bankChanged) { uint8 high = static_cast(wMidiBank >> 7); uint8 low = static_cast(wMidiBank & 0x7F); //GetSoundFile()->ProcessMIDIMacro(trackChannel, false, GetSoundFile()->m_MidiCfg.szMidiGlb[MIDIOUT_BANKSEL], 0); MidiSend(MIDIEvents::CC(MIDIEvents::MIDICC_BankSelect_Coarse, nMidiCh, high)); MidiSend(MIDIEvents::CC(MIDIEvents::MIDICC_BankSelect_Fine, nMidiCh, low)); channel.currentBank = wMidiBank; } // Program change // According to the MIDI specs, a bank change alone doesn't have to change the active program - it will only change the bank of subsequent program changes. // Thus we send program changes also if only the bank has changed. if(progChanged || (nMidiProg < 0x80 && bankChanged)) { channel.currentProgram = nMidiProg; //GetSoundFile()->ProcessMIDIMacro(trackChannel, false, GetSoundFile()->m_MidiCfg.szMidiGlb[MIDIOUT_PROGRAM], 0); MidiSend(MIDIEvents::ProgramChange(nMidiCh, nMidiProg)); } // Specific Note Off if(note > NOTE_MAX_SPECIAL) { uint8 i = static_cast(note - NOTE_MAX_SPECIAL - NOTE_MIN); if(channel.noteOnMap[i][trackChannel]) { channel.noteOnMap[i][trackChannel]--; MidiSend(MIDIEvents::NoteOff(nMidiCh, i, 0)); } } // "Hard core" All Sounds Off on this midi and tracker channel // This one doesn't check the note mask - just one note off per note. // Also less likely to cause a VST event buffer overflow. else if(note == NOTE_NOTECUT) // ^^ { MidiSend(MIDIEvents::CC(MIDIEvents::MIDICC_AllNotesOff, nMidiCh, 0)); MidiSend(MIDIEvents::CC(MIDIEvents::MIDICC_AllSoundOff, nMidiCh, 0)); // Turn off all notes for(uint8 i = 0; i < CountOf(channel.noteOnMap); i++) { channel.noteOnMap[i][trackChannel] = 0; MidiSend(MIDIEvents::NoteOff(nMidiCh, i, volume)); } } // All "active" notes off on this midi and tracker channel // using note mask. else if(note == NOTE_KEYOFF || note == NOTE_FADE) // ==, ~~ { for(uint8 i = 0; i < CountOf(channel.noteOnMap); i++) { // Some VSTis need a note off for each instance of a note on, e.g. fabfilter. while(channel.noteOnMap[i][trackChannel]) { MidiSend(MIDIEvents::NoteOff(nMidiCh, i, volume)); channel.noteOnMap[i][trackChannel]--; } } } // Note On else if(ModCommand::IsNote(static_cast(note))) { note -= NOTE_MIN; // Reset pitch bend on each new note, tracker style. // This is done if the pitch wheel has been moved or there was a vibrato on the previous row (in which case the "vstVibratoFlag" bit of the pitch bend memory is set) if(m_MidiCh[nMidiCh].midiPitchBendPos != EncodePitchBendParam(MIDIEvents::pitchBendCentre)) { MidiPitchBend(nMidiCh, EncodePitchBendParam(MIDIEvents::pitchBendCentre)); } // count instances of active notes. // This is to send a note off for each instance of a note, for plugs like Fabfilter. // Problem: if a note dies out naturally and we never send a note off, this counter // will block at max until note off. Is this a problem? // Safe to assume we won't need more than 16 note offs max on a given note? if(channel.noteOnMap[note][trackChannel] < 17) channel.noteOnMap[note][trackChannel]++; MidiSend(MIDIEvents::NoteOn(nMidiCh, static_cast(note), volume)); } } bool IMidiPlugin::IsNotePlaying(uint32 note, uint32 midiChn, uint32 trackerChn) { note -= NOTE_MIN; return (m_MidiCh[midiChn].noteOnMap[note][trackerChn] != 0); } void IMidiPlugin::ReceiveMidi(uint32 midiCode) { ResetSilence(); // I think we should only route events to plugins that are explicitely specified as output plugins of the current plugin. // This should probably use GetOutputPlugList here if we ever get to support multiple output plugins. PLUGINDEX receiver; if(m_pMixStruct != nullptr && (receiver = m_pMixStruct->GetOutputPlugin()) != PLUGINDEX_INVALID) { IMixPlugin *plugin = m_SndFile.m_MixPlugins[receiver].pMixPlugin; // Add all events to the plugin's queue. plugin->MidiSend(midiCode); } #ifdef MODPLUG_TRACKER if(m_recordMIDIOut) { // Spam MIDI data to all views ::PostMessage(CMainFrame::GetMainFrame()->GetMidiRecordWnd(), WM_MOD_MIDIMSG, midiCode, reinterpret_cast(this)); } #endif // MODPLUG_TRACKER } void IMidiPlugin::ReceiveSysex(const void *message, uint32 length) { ResetSilence(); // I think we should only route events to plugins that are explicitely specified as output plugins of the current plugin. // This should probably use GetOutputPlugList here if we ever get to support multiple output plugins. PLUGINDEX receiver; if(m_pMixStruct != nullptr && (receiver = m_pMixStruct->GetOutputPlugin()) != PLUGINDEX_INVALID) { IMixPlugin *plugin = m_SndFile.m_MixPlugins[receiver].pMixPlugin; // Add all events to the plugin's queue. plugin->MidiSysexSend(message, length); } } // SNDMIXPLUGIN functions void SNDMIXPLUGIN::SetGain(uint8 gain) { Info.gain = gain; if(pMixPlugin != nullptr) pMixPlugin->RecalculateGain(); } void SNDMIXPLUGIN::SetBypass(bool bypass) { if(pMixPlugin != nullptr) pMixPlugin->Bypass(bypass); else Info.SetBypass(bypass); } void SNDMIXPLUGIN::Destroy() { if(pMixPlugin) { pMixPlugin->Release(); pMixPlugin = nullptr; } pluginData.clear(); pluginData.shrink_to_fit(); } OPENMPT_NAMESPACE_END #endif // NO_PLUGINS libopenmpt-0.3.6+release.autotools/soundlib/plugins/PluginManager.cpp0000644000372100037210000004646613161656666023053 00000000000000/* * PluginManager.cpp * ----------------- * Purpose: Implementation of the plugin manager, which keeps a list of known plugins and instantiates them. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #ifndef NO_PLUGINS #include "../../common/version.h" #include "PluginManager.h" #include "PlugInterface.h" #include "../../common/mptUUID.h" // Built-in plugins #include "DigiBoosterEcho.h" #include "LFOPlugin.h" #include "dmo/DMOPlugin.h" #include "dmo/Chorus.h" #include "dmo/Compressor.h" #include "dmo/Distortion.h" #include "dmo/Echo.h" #include "dmo/Flanger.h" #include "dmo/Gargle.h" #include "dmo/I3DL2Reverb.h" #include "dmo/ParamEq.h" #include "dmo/WavesReverb.h" #ifdef MODPLUG_TRACKER #include "../../mptrack/plugins/MidiInOut.h" #endif // MODPLUG_TRACKER #include "../../common/StringFixer.h" #include "../Sndfile.h" #include "../Loaders.h" #ifndef NO_VST #include "../../mptrack/Vstplug.h" #include "../../pluginBridge/BridgeWrapper.h" #endif // NO_VST #ifndef NO_DMO #include #include #include #endif // NO_DMO #ifdef MODPLUG_TRACKER #include "../../mptrack/Mptrack.h" #include "../../mptrack/TrackerSettings.h" #include "../../mptrack/AbstractVstEditor.h" #include "../../soundlib/AudioCriticalSection.h" #include "../common/mptCRC.h" #endif // MODPLUG_TRACKER OPENMPT_NAMESPACE_BEGIN //#define VST_LOG //#define DMO_LOG #ifdef MODPLUG_TRACKER static const MPT_UCHAR_TYPE *const cacheSection = MPT_ULITERAL("PluginCache"); #endif // MODPLUG_TRACKER uint8 VSTPluginLib::GetDllBits(bool fromCache) const { // Built-in plugins are always native. if(dllPath.empty()) return sizeof(void *) * CHAR_BIT; #ifndef NO_VST if(!dllBits || !fromCache) { dllBits = static_cast(BridgeWrapper::GetPluginBinaryType(dllPath)); } #else MPT_UNREFERENCED_PARAMETER(fromCache); #endif // NO_VST return dllBits; } // PluginCache format: // FullDllPath = (hex-encoded) // .Flags = Plugin Flags (see VSTPluginLib::DecodeCacheFlags). // .Vendor = Plugin Vendor String. #ifdef MODPLUG_TRACKER void VSTPluginLib::WriteToCache() const { SettingsContainer &cacheFile = theApp.GetPluginCache(); const std::string crcName = dllPath.ToUTF8(); const uint32 crc = mpt::crc32(crcName); const mpt::ustring IDs = mpt::ufmt::HEX0<8>(SwapBytesLE(pluginId1)) + mpt::ufmt::HEX0<8>(SwapBytesLE(pluginId2)) + mpt::ufmt::HEX0<8>(SwapBytesLE(crc)); mpt::PathString writePath = dllPath; if(theApp.IsPortableMode()) { writePath = theApp.AbsolutePathToRelative(writePath); } cacheFile.Write(cacheSection, writePath.ToUnicode(), IDs); cacheFile.Write(cacheSection, IDs + MPT_USTRING(".Vendor"), vendor); cacheFile.Write(cacheSection, IDs + MPT_USTRING(".Flags"), EncodeCacheFlags()); } #endif // MODPLUG_TRACKER bool CreateMixPluginProc(SNDMIXPLUGIN &mixPlugin, CSoundFile &sndFile) { #ifdef MODPLUG_TRACKER CVstPluginManager *that = theApp.GetPluginManager(); if(that) { return that->CreateMixPlugin(mixPlugin, sndFile); } return false; #else if(!sndFile.m_PluginManager) { sndFile.m_PluginManager = mpt::make_unique(); } return sndFile.m_PluginManager->CreateMixPlugin(mixPlugin, sndFile); #endif // MODPLUG_TRACKER } CVstPluginManager::CVstPluginManager() #ifndef NO_DMO : MustUnInitilizeCOM(false) #endif { #ifndef NO_DMO HRESULT COMinit = CoInitializeEx(NULL, COINIT_MULTITHREADED); if(COMinit == S_OK || COMinit == S_FALSE) { MustUnInitilizeCOM = true; } #endif // Hard-coded "plugins" static constexpr struct { VSTPluginLib::CreateProc createProc; const char *filename, *name; uint32 pluginId1, pluginId2; VSTPluginLib::PluginCategory category; bool isInstrument, isOurs; } BuiltInPlugins[] = { // DirectX Media Objects Emulation { DMO::Chorus::Create, "{EFE6629C-81F7-4281-BD91-C9D604A95AF6}", "Chorus", kDmoMagic, 0xEFE6629C, VSTPluginLib::catDMO, false, false }, { DMO::Compressor::Create, "{EF011F79-4000-406D-87AF-BFFB3FC39D57}", "Compressor", kDmoMagic, 0xEF011F79, VSTPluginLib::catDMO, false, false }, { DMO::Distortion::Create, "{EF114C90-CD1D-484E-96E5-09CFAF912A21}", "Distortion", kDmoMagic, 0xEF114C90, VSTPluginLib::catDMO, false, false }, { DMO::Echo::Create, "{EF3E932C-D40B-4F51-8CCF-3F98F1B29D5D}", "Echo", kDmoMagic, 0xEF3E932C, VSTPluginLib::catDMO, false, false }, { DMO::Flanger::Create, "{EFCA3D92-DFD8-4672-A603-7420894BAD98}", "Flanger", kDmoMagic, 0xEFCA3D92, VSTPluginLib::catDMO, false, false }, { DMO::Gargle::Create, "{DAFD8210-5711-4B91-9FE3-F75B7AE279BF}", "Gargle", kDmoMagic, 0xDAFD8210, VSTPluginLib::catDMO, false, false }, { DMO::I3DL2Reverb::Create, "{EF985E71-D5C7-42D4-BA4D-2D073E2E96F4}", "I3DL2Reverb", kDmoMagic, 0xEF985E71, VSTPluginLib::catDMO, false, false }, { DMO::ParamEq::Create, "{120CED89-3BF4-4173-A132-3CB406CF3231}", "ParamEq", kDmoMagic, 0x120CED89, VSTPluginLib::catDMO, false, false }, { DMO::WavesReverb::Create, "{87FC0268-9A55-4360-95AA-004A1D9DE26C}", "WavesReverb", kDmoMagic, 0x87FC0268, VSTPluginLib::catDMO, false, false }, // DigiBooster Pro Echo DSP { DigiBoosterEcho::Create, "", "DigiBooster Pro Echo", MAGIC4LE('D','B','M','0'), MAGIC4LE('E','c','h','o'), VSTPluginLib::catRoomFx, false, true }, // LFO { LFOPlugin::Create, "", "LFO", MAGIC4LE('O','M','P','T'), MAGIC4LE('L','F','O',' '), VSTPluginLib::catGenerator, false, true }, #ifdef MODPLUG_TRACKER { MidiInOut::Create, "", "MIDI Input Output", PLUGMAGIC('V','s','t','P'), PLUGMAGIC('M','M','I','D'), VSTPluginLib::catSynth, true, true }, #endif // MODPLUG_TRACKER }; pluginList.reserve(mpt::size(BuiltInPlugins)); for(const auto &plugin : BuiltInPlugins) { VSTPluginLib *plug = new (std::nothrow) VSTPluginLib(plugin.createProc, true, mpt::PathString::FromUTF8(plugin.filename), mpt::PathString::FromUTF8(plugin.name)); if(plug != nullptr) { pluginList.push_back(plug); plug->pluginId1 = plugin.pluginId1; plug->pluginId2 = plugin.pluginId2; plug->category = plugin.category; plug->isInstrument = plugin.isInstrument; #ifdef MODPLUG_TRACKER if(plugin.isOurs) plug->vendor = _T("OpenMPT Project"); #endif // MODPLUG_TRACKER } } #ifdef MODPLUG_TRACKER // For security reasons, we do not load untrusted DMO plugins in libopenmpt. EnumerateDirectXDMOs(); #endif } CVstPluginManager::~CVstPluginManager() { for(auto &plug : pluginList) { while(plug->pPluginsList != nullptr) { plug->pPluginsList->Release(); } delete plug; } #ifndef NO_DMO if(MustUnInitilizeCOM) { CoUninitialize(); MustUnInitilizeCOM = false; } #endif } bool CVstPluginManager::IsValidPlugin(const VSTPluginLib *pLib) const { return std::find(pluginList.begin(), pluginList.end(), pLib) != pluginList.end(); } void CVstPluginManager::EnumerateDirectXDMOs() { #ifndef NO_DMO const mpt::UUID knownDMOs[] = { MPT_UUID(745057C7,F353,4F2D,A7EE,58434477730E), // AEC (Acoustic echo cancellation, not usable) MPT_UUID(EFE6629C,81F7,4281,BD91,C9D604A95AF6), // Chorus MPT_UUID(EF011F79,4000,406D,87AF,BFFB3FC39D57), // Compressor MPT_UUID(EF114C90,CD1D,484E,96E5,09CFAF912A21), // Distortion MPT_UUID(EF3E932C,D40B,4F51,8CCF,3F98F1B29D5D), // Echo MPT_UUID(EFCA3D92,DFD8,4672,A603,7420894BAD98), // Flanger MPT_UUID(DAFD8210,5711,4B91,9FE3,F75B7AE279BF), // Gargle MPT_UUID(EF985E71,D5C7,42D4,BA4D,2D073E2E96F4), // I3DL2Reverb MPT_UUID(120CED89,3BF4,4173,A132,3CB406CF3231), // ParamEq MPT_UUID(87FC0268,9A55,4360,95AA,004A1D9DE26C), // WavesReverb MPT_UUID(F447B69E,1884,4A7E,8055,346F74D6EDB3), // Resampler DMO (not usable) }; HKEY hkEnum; WCHAR keyname[128]; LONG cr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("software\\classes\\DirectShow\\MediaObjects\\Categories\\f3602b3f-0592-48df-a4cd-674721e7ebeb"), 0, KEY_READ, &hkEnum); DWORD index = 0; while (cr == ERROR_SUCCESS) { if ((cr = RegEnumKeyW(hkEnum, index, keyname, CountOf(keyname))) == ERROR_SUCCESS) { CLSID clsid; std::wstring formattedKey = std::wstring(L"{") + std::wstring(keyname) + std::wstring(L"}"); if(Util::VerifyStringToCLSID(formattedKey, clsid)) { if(std::find(std::begin(knownDMOs), std::end(knownDMOs), clsid) == std::end(knownDMOs)) { HKEY hksub; formattedKey = std::wstring(L"software\\classes\\DirectShow\\MediaObjects\\") + std::wstring(keyname); if (RegOpenKeyW(HKEY_LOCAL_MACHINE, formattedKey.c_str(), &hksub) == ERROR_SUCCESS) { WCHAR name[64]; DWORD datatype = REG_SZ; DWORD datasize = sizeof(name); if(ERROR_SUCCESS == RegQueryValueExW(hksub, nullptr, 0, &datatype, (LPBYTE)name, &datasize)) { mpt::String::SetNullTerminator(name); VSTPluginLib *plug = new (std::nothrow) VSTPluginLib(DMOPlugin::Create, true, mpt::PathString::FromNative(Util::GUIDToString(clsid)), mpt::PathString::FromNative(name)); if(plug != nullptr) { try { pluginList.push_back(plug); plug->pluginId1 = kDmoMagic; plug->pluginId2 = clsid.Data1; plug->category = VSTPluginLib::catDMO; } MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e) { MPT_EXCEPTION_DELETE_OUT_OF_MEMORY(e); delete plug; } #ifdef DMO_LOG Log(mpt::format(L"Found \"%1\" clsid=%2\n")(plug->libraryName, plug->dllPath)); #endif } } RegCloseKey(hksub); } } } } index++; } if (hkEnum) RegCloseKey(hkEnum); #endif // NO_DMO } // Extract instrument and category information from plugin. #ifndef NO_VST static void GetPluginInformation(AEffect *effect, VSTPluginLib &library) { unsigned long exception = 0; library.category = static_cast(CVstPlugin::DispatchSEH(effect, effGetPlugCategory, 0, 0, nullptr, 0, exception)); library.isInstrument = ((effect->flags & effFlagsIsSynth) || !effect->numInputs); if(library.isInstrument) { library.category = VSTPluginLib::catSynth; } else if(library.category >= VSTPluginLib::numCategories) { library.category = VSTPluginLib::catUnknown; } #ifdef MODPLUG_TRACKER std::vector s(256, 0); CVstPlugin::DispatchSEH(effect, effGetVendorString, 0, 0, s.data(), 0, exception); library.vendor = mpt::ToCString(mpt::CharsetLocale, s.data()); #endif // MODPLUG_TRACKER } #endif // NO_VST #ifdef MODPLUG_TRACKER // Add a plugin to the list of known plugins. VSTPluginLib *CVstPluginManager::AddPlugin(const mpt::PathString &dllPath, const mpt::ustring &tags, bool fromCache, const bool checkFileExistence, std::wstring *const errStr) { const mpt::PathString fileName = dllPath.GetFileName(); // Check if this is already a known plugin. for(const auto &dupePlug : pluginList) { if(!dllPath.CompareNoCase(dllPath, dupePlug->dllPath)) return dupePlug; } if(checkFileExistence && errStr != nullptr && !dllPath.IsFile()) { *errStr += L"\nUnable to find " + dllPath.ToWide(); } // Look if the plugin info is stored in the PluginCache if(fromCache) { SettingsContainer & cacheFile = theApp.GetPluginCache(); // First try finding the full path mpt::ustring IDs = cacheFile.Read(cacheSection, dllPath.ToUnicode(), MPT_USTRING("")); if(IDs.length() < 16) { // If that didn't work out, find relative path mpt::PathString relPath = theApp.AbsolutePathToRelative(dllPath); IDs = cacheFile.Read(cacheSection, relPath.ToUnicode(), MPT_USTRING("")); } if(IDs.length() >= 16) { VSTPluginLib *plug = new (std::nothrow) VSTPluginLib(nullptr, false, dllPath, fileName, tags); if(plug == nullptr) { return nullptr; } pluginList.push_back(plug); // Extract plugin IDs for (int i = 0; i < 16; i++) { int32 n = IDs[i] - '0'; if (n > 9) n = IDs[i] + 10 - 'A'; n &= 0x0f; if (i < 8) { plug->pluginId1 = (plug->pluginId1 << 4) | n; } else { plug->pluginId2 = (plug->pluginId2 << 4) | n; } } const mpt::ustring flagKey = IDs + MPT_USTRING(".Flags"); plug->DecodeCacheFlags(cacheFile.Read(cacheSection, flagKey, 0)); plug->vendor = cacheFile.Read(cacheSection, IDs + MPT_USTRING(".Vendor"), CString()); #ifdef VST_LOG Log("Plugin \"%s\" found in PluginCache\n", plug->libraryName.ToLocale().c_str()); #endif // VST_LOG return plug; } else { #ifdef VST_LOG Log("Plugin \"%s\" mismatch in PluginCache: \"%s\" [%s]=\"%s\"\n", s, dllPath, (LPCTSTR)IDs, (LPCTSTR)strFullPath); #endif // VST_LOG } } // If this key contains a file name on program launch, a plugin previously crashed OpenMPT. theApp.GetSettings().Write(MPT_USTRING("VST Plugins"), MPT_USTRING("FailedPlugin"), dllPath, SettingWriteThrough); bool validPlug = false; VSTPluginLib *plug = new (std::nothrow) VSTPluginLib(nullptr, false, dllPath, fileName, tags); if(plug == nullptr) { return nullptr; } #ifndef NO_VST unsigned long exception = 0; // Always scan plugins in a separate process HINSTANCE hLib = NULL; AEffect *pEffect = CVstPlugin::LoadPlugin(*plug, hLib, true); if(pEffect != nullptr && pEffect->magic == kEffectMagic && pEffect->dispatcher != nullptr) { CVstPlugin::DispatchSEH(pEffect, effOpen, 0, 0, 0, 0, exception); plug->pluginId1 = pEffect->magic; plug->pluginId2 = pEffect->uniqueID; GetPluginInformation(pEffect, *plug); #ifdef VST_LOG int nver = CVstPlugin::DispatchSEH(pEffect, effGetVstVersion, 0,0, nullptr, 0, exception); if (!nver) nver = pEffect->version; Log("%-20s: v%d.0, %d in, %d out, %2d programs, %2d params, flags=0x%04X realQ=%d offQ=%d\n", plug->libraryName.ToLocale().c_str(), nver, pEffect->numInputs, pEffect->numOutputs, pEffect->numPrograms, pEffect->numParams, pEffect->flags, pEffect->realQualities, pEffect->offQualities); #endif // VST_LOG CVstPlugin::DispatchSEH(pEffect, effClose, 0, 0, 0, 0, exception); validPlug = true; } FreeLibrary(hLib); if(exception != 0) { CVstPluginManager::ReportPlugException(mpt::format(L"Exception %1 while trying to load plugin \"%2\"!\n")(mpt::wfmt::HEX<8>(exception), plug->libraryName)); } #endif // NO_VST // Now it should be safe to assume that this plugin loaded properly. :) theApp.GetSettings().Remove(MPT_USTRING("VST Plugins"), MPT_USTRING("FailedPlugin")); // If OK, write the information in PluginCache if(validPlug) { pluginList.push_back(plug); plug->WriteToCache(); } else { delete plug; } return (validPlug ? plug : nullptr); } // Remove a plugin from the list of known plugins and release any remaining instances of it. bool CVstPluginManager::RemovePlugin(VSTPluginLib *pFactory) { for(const_iterator p = begin(); p != end(); p++) { VSTPluginLib *plug = *p; if(plug == pFactory) { // Kill all instances of this plugin CriticalSection cs; while(plug->pPluginsList != nullptr) { plug->pPluginsList->Release(); } pluginList.erase(p); delete plug; return true; } } return false; } #endif // MODPLUG_TRACKER // Create an instance of a plugin. bool CVstPluginManager::CreateMixPlugin(SNDMIXPLUGIN &mixPlugin, CSoundFile &sndFile) { VSTPluginLib *pFound = nullptr; #ifdef MODPLUG_TRACKER mixPlugin.SetAutoSuspend(TrackerSettings::Instance().enableAutoSuspend); #endif // MODPLUG_TRACKER // Find plugin in library int8 match = 0; // "Match quality" of found plugin. Higher value = better match. #if MPT_OS_WINDOWS && !MPT_OS_WINDOWS_WINRT const mpt::PathString libraryName = mpt::PathString::FromUTF8(mixPlugin.GetLibraryName()); #else const std::string libraryName = mpt::ToLowerCaseAscii(mixPlugin.GetLibraryName()); #endif for(const auto &plug : pluginList) { const bool matchID = (plug->pluginId1 == mixPlugin.Info.dwPluginId1) && (plug->pluginId2 == mixPlugin.Info.dwPluginId2); #if MPT_OS_WINDOWS && !MPT_OS_WINDOWS_WINRT const bool matchName = !mpt::PathString::CompareNoCase(plug->libraryName, libraryName); #else const bool matchName = (mpt::ToLowerCaseAscii(plug->libraryName.ToUTF8()) == libraryName); #endif if(matchID && matchName) { pFound = plug; if(plug->IsNative(false)) { break; } // If the plugin isn't native, first check if a native version can be found. match = 3; } else if(matchID && match < 2) { pFound = plug; match = 2; } else if(matchName && match < 1) { pFound = plug; match = 1; } } if(pFound != nullptr && pFound->Create != nullptr) { IMixPlugin *plugin = pFound->Create(*pFound, sndFile, &mixPlugin); return plugin != nullptr; } #ifdef MODPLUG_TRACKER if(!pFound && strcmp(mixPlugin.GetLibraryName(), "")) { // Try finding the plugin DLL in the plugin directory or plugin cache instead. mpt::PathString fullPath = TrackerSettings::Instance().PathPlugins.GetDefaultDir(); if(fullPath.empty()) { fullPath = theApp.GetAppDirPath() + MPT_PATHSTRING("Plugins\\"); } fullPath += mpt::PathString::FromUTF8(mixPlugin.GetLibraryName()) + MPT_PATHSTRING(".dll"); pFound = AddPlugin(fullPath); if(!pFound) { // Try plugin cache (search for library name) SettingsContainer &cacheFile = theApp.GetPluginCache(); mpt::ustring IDs = cacheFile.Read(cacheSection, mpt::ToUnicode(mpt::CharsetUTF8, mixPlugin.GetLibraryName()), MPT_USTRING("")); if(IDs.length() >= 16) { fullPath = cacheFile.Read(cacheSection, IDs, MPT_PATHSTRING("")); if(!fullPath.empty()) { fullPath = theApp.RelativePathToAbsolute(fullPath); if(fullPath.IsFile()) { pFound = AddPlugin(fullPath); } } } } } #ifndef NO_VST if(pFound && mixPlugin.Info.dwPluginId1 == kEffectMagic) { AEffect *pEffect = nullptr; HINSTANCE hLibrary = nullptr; bool validPlugin = false; pEffect = CVstPlugin::LoadPlugin(*pFound, hLibrary, TrackerSettings::Instance().bridgeAllPlugins); if(pEffect != nullptr && pEffect->dispatcher != nullptr && pEffect->magic == kEffectMagic) { validPlugin = true; GetPluginInformation(pEffect, *pFound); // Update cached information pFound->WriteToCache(); CVstPlugin *pVstPlug = new (std::nothrow) CVstPlugin(hLibrary, *pFound, mixPlugin, *pEffect, sndFile); if(pVstPlug == nullptr) { validPlugin = false; } } if(!validPlugin) { FreeLibrary(hLibrary); CVstPluginManager::ReportPlugException(mpt::format(L"Unable to create plugin \"%1\"!\n")(pFound->libraryName)); } return validPlugin; } else { // "plug not found" notification code MOVED to CSoundFile::Create #ifdef VST_LOG Log("Unknown plugin\n"); #endif } #endif // NO_VST #endif // MODPLUG_TRACKER return false; } #ifdef MODPLUG_TRACKER void CVstPluginManager::OnIdle() { for(auto &factory : pluginList) { // Note: bridged plugins won't receive these messages and generate their own idle messages. IMixPlugin *p = factory->pPluginsList; while (p) { //rewbs. VSTCompliance: A specific plug has requested indefinite periodic processing time. p->Idle(); //We need to update all open editors CAbstractVstEditor *editor = p->GetEditor(); if (editor && editor->m_hWnd) { editor->UpdateParamDisplays(); } //end rewbs. VSTCompliance: p = p->GetNextInstance(); } } } void CVstPluginManager::ReportPlugException(const std::string &msg) { Reporting::Notification(msg.c_str()); #ifdef VST_LOG Log("%s", msg.c_str()); #endif } void CVstPluginManager::ReportPlugException(const std::wstring &msg) { Reporting::Notification(msg); #ifdef VST_LOG Log(mpt::ToUnicode(msg)); #endif } #endif // MODPLUG_TRACKER OPENMPT_NAMESPACE_END #endif // NO_PLUGINS libopenmpt-0.3.6+release.autotools/soundlib/plugins/DigiBoosterEcho.h0000644000372100037210000000665713161656666022776 00000000000000/* * DigiBoosterEcho.h * ----------------- * Purpose: Implementation of the DigiBooster Pro Echo DSP * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #ifndef NO_PLUGINS #include "PlugInterface.h" OPENMPT_NAMESPACE_BEGIN class DigiBoosterEcho : public IMixPlugin { public: enum Parameters { kEchoDelay = 0, kEchoFeedback, kEchoMix, kEchoCross, kEchoNumParameters }; // Our settings chunk for file I/O, as it will be written to files struct PluginChunk { char id[4]; uint8 param[kEchoNumParameters]; PluginChunk(uint8 delay = 80, uint8 feedback = 150, uint8 mix = 80, uint8 cross = 255) { memcpy(id, "Echo", 4); param[kEchoDelay] = delay; param[kEchoFeedback] = feedback; param[kEchoMix] = mix; param[kEchoCross] = cross; STATIC_ASSERT(sizeof(PluginChunk) == 8); } }; protected: std::vector m_delayLine; // Echo delay line uint32 m_bufferSize; // Delay line length in frames uint32 m_writePos; // Current write position in the delay line uint32 m_delayTime; // In frames uint32 m_sampleRate; // Echo calculation coefficients float m_PMix, m_NMix; float m_PCrossPBack, m_PCrossNBack; float m_NCrossPBack, m_NCrossNBack; // Settings chunk for file I/O PluginChunk m_chunk; public: static IMixPlugin* Create(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct); DigiBoosterEcho(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct); void Release() override { delete this; } void SaveAllParameters() override; void RestoreAllParameters(int32 program) override; int32 GetUID() const override { int32le id; memcpy(&id, "Echo", 4); return id; } int32 GetVersion() const override { return 0; } void Idle() override { } uint32 GetLatency() const override { return 0; } void Process(float *pOutL, float *pOutR, uint32 numFrames) override; float RenderSilence(uint32) override { return 0.0f; } int32 GetNumPrograms() const override { return 0; } int32 GetCurrentProgram() override { return 0; } void SetCurrentProgram(int32) override { } PlugParamIndex GetNumParameters() const override { return kEchoNumParameters; } PlugParamValue GetParameter(PlugParamIndex index) override; void SetParameter(PlugParamIndex index, PlugParamValue value) override; void Resume() override; void Suspend() override { m_isResumed = false; } void PositionChanged() override; bool IsInstrument() const override { return false; } bool CanRecieveMidiEvents() override { return false; } bool ShouldProcessSilence() override { return true; } #ifdef MODPLUG_TRACKER CString GetDefaultEffectName() override { return _T("Echo"); } CString GetParamName(PlugParamIndex param) override; CString GetParamLabel(PlugParamIndex) override; CString GetParamDisplay(PlugParamIndex param) override; CString GetCurrentProgramName() override { return CString(); } void SetCurrentProgramName(const CString &) override { } CString GetProgramName(int32) override { return CString(); } bool HasEditor() const override { return false; } #endif int GetNumInputChannels() const override { return 2; } int GetNumOutputChannels() const override { return 2; } bool ProgramsAreChunks() const override { return true; } ChunkData GetChunk(bool) override; void SetChunk(const ChunkData &chunk, bool) override; protected: void RecalculateEchoParams(); }; OPENMPT_NAMESPACE_END #endif // NO_PLUGINS libopenmpt-0.3.6+release.autotools/soundlib/plugins/PluginStructs.h0000644000372100037210000001070413077472223022566 00000000000000/* * PluginStructs.h * --------------- * Purpose: Basic plugin structs for CSoundFile. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "../Snd_defs.h" #ifndef NO_PLUGINS #include "../../common/Endianness.h" #endif // NO_PLUGINS OPENMPT_NAMESPACE_BEGIN //////////////////////////////////////////////////////////////////// // Mix Plugins typedef int32 PlugParamIndex; typedef float PlugParamValue; struct SNDMIXPLUGINSTATE; struct SNDMIXPLUGIN; class IMixPlugin; class CSoundFile; #ifndef NO_PLUGINS struct SNDMIXPLUGININFO { // dwInputRouting flags enum RoutingFlags { irApplyToMaster = 0x01, // Apply to master mix irBypass = 0x02, // Bypass effect irWetMix = 0x04, // Wet Mix (dry added) irExpandMix = 0x08, // [0%,100%] -> [-200%,200%] irAutoSuspend = 0x10, // Plugin will automatically suspend on silence }; int32le dwPluginId1; // Plugin type (kEffectMagic, kDmoMagic, kBuzzMagic) int32le dwPluginId2; // Plugin unique ID uint8le routingFlags; // See RoutingFlags uint8le mixMode; uint8le gain; // Divide by 10 to get real gain uint8le reserved; uint32le dwOutputRouting; // 0 = send to master 0x80 + x = send to plugin x uint32le dwReserved[4]; // Reserved for routing info char szName[32]; // User-chosen plugin display name - this is locale ANSI! char szLibraryName[64]; // original DLL name - this is UTF-8! // Should only be called from SNDMIXPLUGIN::SetBypass() and IMixPlugin::Bypass() void SetBypass(bool bypass = true) { if(bypass) routingFlags |= irBypass; else routingFlags &= uint8(~irBypass); } }; MPT_BINARY_STRUCT(SNDMIXPLUGININFO, 128) // this is directly written to files, so the size must be correct! struct SNDMIXPLUGIN { IMixPlugin *pMixPlugin; std::vector pluginData; SNDMIXPLUGININFO Info; float fDryRatio; int32 defaultProgram; int32 editorX, editorY; SNDMIXPLUGIN() : pMixPlugin(nullptr) , fDryRatio(0.0f) , defaultProgram(0) , editorX(0), editorY(0) { MemsetZero(Info); } const char *GetName() const { return Info.szName; } const char *GetLibraryName() const { return Info.szLibraryName; } // Check if a plugin is loaded into this slot (also returns true if the plugin in this slot has not been found) bool IsValidPlugin() const { return (Info.dwPluginId1 | Info.dwPluginId2) != 0; }; // Input routing getters uint8 GetGain() const { return Info.gain; } uint8 GetMixMode() const { return Info.mixMode; } bool IsMasterEffect() const { return (Info.routingFlags & SNDMIXPLUGININFO::irApplyToMaster) != 0; } bool IsWetMix() const { return (Info.routingFlags & SNDMIXPLUGININFO::irWetMix) != 0; } bool IsExpandedMix() const { return (Info.routingFlags & SNDMIXPLUGININFO::irExpandMix) != 0; } bool IsBypassed() const { return (Info.routingFlags & SNDMIXPLUGININFO::irBypass) != 0; } bool IsAutoSuspendable() const { return (Info.routingFlags & SNDMIXPLUGININFO::irAutoSuspend) != 0; } // Input routing setters void SetGain(uint8 gain); void SetMixMode(uint8 mixMode) { Info.mixMode = mixMode; } void SetMasterEffect(bool master = true) { if(master) Info.routingFlags |= SNDMIXPLUGININFO::irApplyToMaster; else Info.routingFlags &= uint8(~SNDMIXPLUGININFO::irApplyToMaster); } void SetWetMix(bool wetMix = true) { if(wetMix) Info.routingFlags |= SNDMIXPLUGININFO::irWetMix; else Info.routingFlags &= uint8(~SNDMIXPLUGININFO::irWetMix); } void SetExpandedMix(bool expanded = true) { if(expanded) Info.routingFlags |= SNDMIXPLUGININFO::irExpandMix; else Info.routingFlags &= uint8(~SNDMIXPLUGININFO::irExpandMix); } void SetBypass(bool bypass = true); void SetAutoSuspend(bool suspend = true) { if(suspend) Info.routingFlags |= SNDMIXPLUGININFO::irAutoSuspend; else Info.routingFlags &= uint8(~SNDMIXPLUGININFO::irAutoSuspend); } // Output routing getters bool IsOutputToMaster() const { return Info.dwOutputRouting == 0; } PLUGINDEX GetOutputPlugin() const { return Info.dwOutputRouting >= 0x80 ? static_cast(Info.dwOutputRouting - 0x80) : PLUGINDEX_INVALID; } // Output routing setters void SetOutputToMaster() { Info.dwOutputRouting = 0; } void SetOutputPlugin(PLUGINDEX plugin) { if(plugin < MAX_MIXPLUGINS) Info.dwOutputRouting = plugin + 0x80; else Info.dwOutputRouting = 0; } void Destroy(); }; bool CreateMixPluginProc(SNDMIXPLUGIN &mixPlugin, CSoundFile &sndFile); #endif // NO_PLUGINS OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/plugins/LFOPlugin.h0000644000372100037210000001053713161656666021554 00000000000000/* * LFOPlugin.h * ----------- * Purpose: Plugin for automating other plugins' parameters * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #ifndef NO_PLUGINS #include "PlugInterface.h" #include "../../common/mptRandom.h" OPENMPT_NAMESPACE_BEGIN class LFOPlugin : public IMixPlugin { friend class LFOPluginEditor; protected: enum Parameters { kAmplitude = 0, kOffset, kFrequency, kTempoSync, kWaveform, kPolarity, kBypassed, kLoopMode, kCurrentPhase, kLFONumParameters }; enum LFOWaveform { kSine = 0, kTriangle, kSaw, kSquare, kSHNoise, kSmoothNoise, kNumWaveforms }; std::vector m_chunkData; // LFO parameters float m_amplitude, m_offset, m_frequency; LFOWaveform m_waveForm; PlugParamIndex m_outputParam; bool m_tempoSync, m_polarity, m_bypassed, m_outputToCC, m_oneshot; // LFO state double m_computedFrequency; double m_phase, m_increment; double m_random, m_nextRandom; double m_tempo; mpt::fast_prng m_PRNG; #ifdef MODPLUG_TRACKER static const int WM_PARAM_UDPATE = WM_USER + 500; #endif public: static IMixPlugin* Create(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct); LFOPlugin(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct); void Release() override { delete this; } int32 GetUID() const override { int32 id; memcpy(&id, "LFO ", 4); return id; } int32 GetVersion() const override { return 0; } void Idle() override { } uint32 GetLatency() const override { return 0; } void Process(float *pOutL, float *pOutR, uint32 numFrames) override; float RenderSilence(uint32) override { return 0.0f; } // MIDI event handling (mostly passing it through to the follow-up plugin) bool MidiSend(uint32 midiCode) override; bool MidiSysexSend(const void *message, uint32 length) override; void MidiCC(uint8 nMidiCh, MIDIEvents::MidiCC nController, uint8 nParam, CHANNELINDEX trackChannel) override; void MidiPitchBend(uint8 nMidiCh, int32 increment, int8 pwd) override; void MidiVibrato(uint8 nMidiCh, int32 depth, int8 pwd) override; void MidiCommand(uint8 nMidiCh, uint8 nMidiProg, uint16 wMidiBank, uint16 note, uint16 vol, CHANNELINDEX trackChannel) override; void HardAllNotesOff() override; bool IsNotePlaying(uint32 note, uint32 midiChn, uint32 trackerChn) override; int32 GetNumPrograms() const override { return 0; } int32 GetCurrentProgram() override { return 0; } void SetCurrentProgram(int32) override { } PlugParamIndex GetNumParameters() const override { return kLFONumParameters; } PlugParamValue GetParameter(PlugParamIndex index) override; void SetParameter(PlugParamIndex index, PlugParamValue value) override; void Resume() override; void Suspend() override { m_isResumed = false; } void PositionChanged() override; bool IsInstrument() const override { return false; } bool CanRecieveMidiEvents() override { return false; } bool ShouldProcessSilence() override { return true; } #ifdef MODPLUG_TRACKER CString GetDefaultEffectName() override { return _T("LFO"); } CString GetParamName(PlugParamIndex param) override; CString GetParamLabel(PlugParamIndex) override; CString GetParamDisplay(PlugParamIndex param) override; CString GetCurrentProgramName() override { return CString(); } void SetCurrentProgramName(const CString &) override { } CString GetProgramName(int32) override { return CString(); } bool HasEditor() const override { return true; } protected: CAbstractVstEditor *OpenEditor() override; #endif public: int GetNumInputChannels() const override { return 2; } int GetNumOutputChannels() const override { return 2; } bool ProgramsAreChunks() const override { return true; } // Save parameters for storing them in a module file void SaveAllParameters() override; // Restore parameters from module file void RestoreAllParameters(int32 program) override; ChunkData GetChunk(bool) override; void SetChunk(const ChunkData &chunk, bool) override; protected: void NextRandom(); void RecalculateFrequency(); void RecalculateIncrement(); IMixPlugin *GetOutputPlugin() const; public: static LFOWaveform ParamToWaveform(float param) { return static_cast(Util::Round(param * 32.0f)); } static float WaveformToParam(LFOWaveform waveform) { return waveform / 32.0f; } }; OPENMPT_NAMESPACE_END #endif // NO_PLUGINS libopenmpt-0.3.6+release.autotools/soundlib/plugins/PlugInterface.h0000644000372100037210000002375713161656666022515 00000000000000/* * PlugInterface.h * --------------- * Purpose: Interface class for plugin handling * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #ifndef NO_PLUGINS #include "../../soundlib/Snd_defs.h" #include "../../soundlib/MIDIEvents.h" #include "../../soundlib/Mixer.h" #include "PluginMixBuffer.h" #include "PluginStructs.h" OPENMPT_NAMESPACE_BEGIN struct VSTPluginLib; struct SNDMIXPLUGIN; class CSoundFile; class CModDoc; class CAbstractVstEditor; struct SNDMIXPLUGINSTATE { // dwFlags flags enum PluginStateFlags { psfMixReady = 0x01, // Set when cleared psfHasInput = 0x02, // Set when plugin has non-silent input psfSilenceBypass = 0x04, // Bypass because of silence detection }; mixsample_t *pMixBuffer; // Stereo effect send buffer uint32 dwFlags; // PluginStateFlags uint32 inputSilenceCount; // How much silence has been processed? (for plugin auto-turnoff) mixsample_t nVolDecayL, nVolDecayR; // End of sample click removal SNDMIXPLUGINSTATE() { memset(this, 0, sizeof(*this)); } void ResetSilence() { dwFlags |= psfHasInput; dwFlags &= ~psfSilenceBypass; inputSilenceCount = 0; } }; class IMixPlugin { friend class CAbstractVstEditor; protected: IMixPlugin *m_pNext, *m_pPrev; VSTPluginLib &m_Factory; CSoundFile &m_SndFile; SNDMIXPLUGIN *m_pMixStruct; #ifdef MODPLUG_TRACKER CAbstractVstEditor *m_pEditor; #endif // MODPLUG_TRACKER public: SNDMIXPLUGINSTATE m_MixState; PluginMixBuffer m_mixBuffer; // Float buffers (input and output) for plugins protected: mixsample_t m_MixBuffer[MIXBUFFERSIZE * 2 + 2]; // Stereo interleaved input (sample mixer renders here) float m_fGain; PLUGINDEX m_nSlot; bool m_isSongPlaying : 1; bool m_isResumed : 1; public: bool m_recordAutomation : 1; bool m_passKeypressesToPlug : 1; bool m_recordMIDIOut : 1; protected: virtual ~IMixPlugin(); // Insert plugin into list of loaded plugins. void InsertIntoFactoryList(); public: // Non-virtual part of the interface IMixPlugin(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct); inline CSoundFile &GetSoundFile() { return m_SndFile; } inline const CSoundFile &GetSoundFile() const { return m_SndFile; } #ifdef MODPLUG_TRACKER CModDoc *GetModDoc(); const CModDoc *GetModDoc() const; void SetSlot(PLUGINDEX slot); inline PLUGINDEX GetSlot() const { return m_nSlot; } #endif // MODPLUG_TRACKER inline VSTPluginLib &GetPluginFactory() const { return m_Factory; } // Returns the next instance of the same plugin inline IMixPlugin *GetNextInstance() const { return m_pNext; } void SetDryRatio(uint32 param); bool IsBypassed() const; void RecalculateGain(); // Query output latency from host (in seconds) double GetOutputLatency() const; // Destroy the plugin virtual void Release() = 0; virtual int32 GetUID() const = 0; virtual int32 GetVersion() const = 0; virtual void Idle() = 0; // Plugin latency in samples virtual uint32 GetLatency() const = 0; virtual int32 GetNumPrograms() const = 0; virtual int32 GetCurrentProgram() = 0; virtual void SetCurrentProgram(int32 nIndex) = 0; virtual PlugParamIndex GetNumParameters() const = 0; virtual void SetParameter(PlugParamIndex paramindex, PlugParamValue paramvalue) = 0; virtual PlugParamValue GetParameter(PlugParamIndex nIndex) = 0; // Save parameters for storing them in a module file virtual void SaveAllParameters(); // Restore parameters from module file virtual void RestoreAllParameters(int32 program); virtual void Process(float *pOutL, float *pOutR, uint32 numFrames) = 0; void ProcessMixOps(float *pOutL, float *pOutR, float *leftPlugOutput, float *rightPlugOutput, uint32 numFrames) const; // Render silence and return the highest resulting output level virtual float RenderSilence(uint32 numSamples); // MIDI event handling virtual bool MidiSend(uint32 /*midiCode*/) { return true; } virtual bool MidiSysexSend(const void * /*message*/, uint32 /*length*/) { return true; } virtual void MidiCC(uint8 /*nMidiCh*/, MIDIEvents::MidiCC /*nController*/, uint8 /*nParam*/, CHANNELINDEX /*trackChannel*/) { } virtual void MidiPitchBend(uint8 /*nMidiCh*/, int32 /*increment*/, int8 /*pwd*/) { } virtual void MidiVibrato(uint8 /*nMidiCh*/, int32 /*depth*/, int8 /*pwd*/) { } virtual void MidiCommand(uint8 /*nMidiCh*/, uint8 /*nMidiProg*/, uint16 /*wMidiBank*/, uint16 /*note*/, uint16 /*vol*/, CHANNELINDEX /*trackChannel*/) { } virtual void HardAllNotesOff() { } virtual bool IsNotePlaying(uint32 /*note*/, uint32 /*midiChn*/, uint32 /*trackerChn*/) { return false; } // Modify parameter by given amount. Only needs to be re-implemented if plugin architecture allows this to be performed atomically. virtual void ModifyParameter(PlugParamIndex nIndex, PlugParamValue diff); virtual void NotifySongPlaying(bool playing) { m_isSongPlaying = playing; } virtual bool IsSongPlaying() const { return m_isSongPlaying; } virtual bool IsResumed() const { return m_isResumed; } virtual void Resume() = 0; virtual void Suspend() = 0; // Tell the plugin that there is a discontinuity between the previous and next render call (e.g. aftert jumping around in the module) virtual void PositionChanged() = 0; virtual void Bypass(bool = true); bool ToggleBypass() { Bypass(!IsBypassed()); return IsBypassed(); } virtual bool IsInstrument() const = 0; virtual bool CanRecieveMidiEvents() = 0; // If false is returned, mixing this plugin can be skipped if its input are currently completely silent. virtual bool ShouldProcessSilence() = 0; virtual void ResetSilence() { m_MixState.ResetSilence(); } size_t GetOutputPlugList(std::vector &list); size_t GetInputPlugList(std::vector &list); size_t GetInputInstrumentList(std::vector &list); size_t GetInputChannelList(std::vector &list); #ifdef MODPLUG_TRACKER bool SaveProgram(); bool LoadProgram(mpt::PathString fileName = mpt::PathString()); virtual CString GetDefaultEffectName() = 0; // Cache a range of names, in case one-by-one retrieval would be slow (e.g. when using plugin bridge) virtual void CacheProgramNames(int32 /*firstProg*/, int32 /*lastProg*/) { } virtual void CacheParameterNames(int32 /*firstParam*/, int32 /*lastParam*/) { } virtual CString GetParamName(PlugParamIndex param) = 0; virtual CString GetParamLabel(PlugParamIndex param) = 0; virtual CString GetParamDisplay(PlugParamIndex param) = 0; CString GetFormattedParamName(PlugParamIndex param); CString GetFormattedParamValue(PlugParamIndex param); virtual CString GetCurrentProgramName() = 0; virtual void SetCurrentProgramName(const CString &name) = 0; virtual CString GetProgramName(int32 program) = 0; CString GetFormattedProgramName(int32 index); virtual bool HasEditor() const = 0; protected: virtual CAbstractVstEditor *OpenEditor(); public: // Get the plugin's editor window CAbstractVstEditor *GetEditor() { return m_pEditor; } const CAbstractVstEditor *GetEditor() const { return m_pEditor; } void ToggleEditor(); void CloseEditor(); void SetEditorPos(int32 x, int32 y); void GetEditorPos(int32 &x, int32 &y) const; // Notify OpenMPT that a plugin parameter has changed and set document as modified void AutomateParameter(PlugParamIndex param); // Plugin state changed, set document as modified. void SetModified(); #endif virtual void BeginSetProgram(int32 /*program*/ = -1) { } virtual void EndSetProgram() { } virtual int GetNumInputChannels() const = 0; virtual int GetNumOutputChannels() const = 0; typedef mpt::const_byte_span ChunkData; virtual bool ProgramsAreChunks() const { return false; } virtual ChunkData GetChunk(bool /*isBank*/) { return ChunkData(); } virtual void SetChunk(const ChunkData &/*chunk*/, bool /*isBank*/) { } }; inline void IMixPlugin::ModifyParameter(PlugParamIndex nIndex, PlugParamValue diff) { float val = GetParameter(nIndex) + diff; Limit(val, PlugParamValue(0), PlugParamValue(1)); SetParameter(nIndex, val); } // IMidiPlugin: Default implementation of plugins with MIDI input class IMidiPlugin : public IMixPlugin { protected: enum { // Pitch wheel constants vstPitchBendShift = 12, // Use lowest 12 bits for fractional part and vibrato flag => 16.11 fixed point precision vstPitchBendMask = (~1), vstVibratoFlag = 1, }; struct PlugInstrChannel { int32 midiPitchBendPos; // Current Pitch Wheel position, in 16.11 fixed point format. Lowest bit is used for indicating that vibrato was applied. Vibrato offset itself is not stored in this value. uint16 currentProgram; uint16 currentBank; uint8 noteOnMap[128][MAX_CHANNELS]; void ResetProgram() { currentProgram = 0; currentBank = 0; } }; PlugInstrChannel m_MidiCh[16]; // MIDI channel state public: IMidiPlugin(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct); virtual void MidiCC(uint8 nMidiCh, MIDIEvents::MidiCC nController, uint8 nParam, CHANNELINDEX trackChannel); virtual void MidiPitchBend(uint8 nMidiCh, int32 increment, int8 pwd); virtual void MidiVibrato(uint8 nMidiCh, int32 depth, int8 pwd); virtual void MidiCommand(uint8 nMidiCh, uint8 nMidiProg, uint16 wMidiBank, uint16 note, uint16 vol, CHANNELINDEX trackChannel); virtual bool IsNotePlaying(uint32 note, uint32 midiChn, uint32 trackerChn); protected: // Plugin wants to send MIDI to OpenMPT virtual void ReceiveMidi(uint32 midiCode); virtual void ReceiveSysex(const void *message, uint32 length); // Converts a 14-bit MIDI pitch bend position to our internal pitch bend position representation static int32 EncodePitchBendParam(int32 position) { return (position << vstPitchBendShift); } // Converts the internal pitch bend position to a 14-bit MIDI pitch bend position static int16 DecodePitchBendParam(int32 position) { return static_cast(position >> vstPitchBendShift); } // Apply Pitch Wheel Depth (PWD) to some MIDI pitch bend value. static inline void ApplyPitchWheelDepth(int32 &value, int8 pwd); void MidiPitchBend(uint8 nMidiCh, int32 pitchBendPos); }; OPENMPT_NAMESPACE_END #endif // NO_PLUGINS libopenmpt-0.3.6+release.autotools/soundlib/plugins/LFOPlugin.cpp0000644000372100037210000002776413161656666022121 00000000000000/* * LFOPlugin.cpp * ------------- * Purpose: Plugin for automating other plugins' parameters * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #ifndef NO_PLUGINS #include "LFOPlugin.h" #include "../Sndfile.h" #include "../../common/FileReader.h" #ifdef MODPLUG_TRACKER #include "../../mptrack/plugins/LFOPluginEditor.h" #endif // MODPLUG_TRACKER OPENMPT_NAMESPACE_BEGIN IMixPlugin* LFOPlugin::Create(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct) { return new (std::nothrow) LFOPlugin(factory, sndFile, mixStruct); } LFOPlugin::LFOPlugin(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct) : IMixPlugin(factory, sndFile, mixStruct) , m_nextRandom(0) , m_tempo(0) , m_PRNG(mpt::make_prng(mpt::global_prng())) { m_amplitude = 0.5f; m_offset = 0.5f; m_frequency = 0.290241f; m_tempoSync = false; m_waveForm = kSine; m_polarity = false; m_bypassed = false; m_outputToCC = false; m_outputParam = int32_max; m_oneshot = false; RecalculateFrequency(); RecalculateIncrement(); m_mixBuffer.Initialize(2, 2); InsertIntoFactoryList(); } // Processing (we do not process audio, just send out parameters) void LFOPlugin::Process(float *pOutL, float *pOutR, uint32 numFrames) { if(!m_bypassed) { ResetSilence(); if(m_tempoSync) { double tempo = m_SndFile.GetCurrentBPM(); if(tempo != m_tempo) { m_tempo = tempo; RecalculateIncrement(); } } if(m_oneshot) { LimitMax(m_phase, 1.0); } else { int intPhase = static_cast(m_phase); if(intPhase > 0 && (m_waveForm == kSHNoise || m_waveForm == kSmoothNoise)) { // Phase wrap-around happened NextRandom(); } m_phase -= intPhase; } double value = 0; switch(m_waveForm) { case kSine: value = std::sin(m_phase * 2.0 * M_PI); break; case kTriangle: value = 1.0 - 4.0 * mpt::abs(m_phase - 0.5); break; case kSaw: value = 2.0 * m_phase - 1.0; break; case kSquare: value = m_phase < 0.5 ? -1.0 : 1.0; break; case kSHNoise: value = m_random; break; case kSmoothNoise: value = m_phase * m_phase * m_phase * (m_phase * (m_phase * 6 - 15) + 10); // Smootherstep value = m_nextRandom * value + m_random * (1.0 - value); break; default: break; } if(m_polarity) value = -value; // Transform value from -1...+1 to 0...1 range and apply offset/amplitude value = value * m_amplitude + m_offset; Limit(value, 0.0, 1.0); IMixPlugin *plugin = GetOutputPlugin(); if(plugin != nullptr) { if(m_outputToCC) { plugin->MidiSend(MIDIEvents::CC(static_cast(m_outputParam & 0x7F), static_cast((m_outputParam >> 8) & 0x0F), Util::Round(value * 127.0f))); } else { plugin->SetParameter(m_outputParam, static_cast(value)); } } m_phase += m_increment * numFrames; } ProcessMixOps(pOutL, pOutR, m_mixBuffer.GetInputBuffer(0), m_mixBuffer.GetInputBuffer(1), numFrames); } PlugParamValue LFOPlugin::GetParameter(PlugParamIndex index) { switch(index) { case kAmplitude: return m_amplitude; case kOffset: return m_offset; case kFrequency: return m_frequency; case kTempoSync: return m_tempoSync ? 1.0f : 0.0f; case kWaveform: return WaveformToParam(m_waveForm); case kPolarity: return m_polarity ? 1.0f : 0.0f; case kBypassed: return m_bypassed ? 1.0f : 0.0f; case kLoopMode: return m_oneshot ? 1.0f : 0.0f; default: return 0; } } void LFOPlugin::SetParameter(PlugParamIndex index, PlugParamValue value) { ResetSilence(); Limit(value, 0.0f, 1.0f); switch(index) { case kAmplitude: m_amplitude = value; break; case kOffset: m_offset = value; break; case kFrequency: m_frequency = value; RecalculateFrequency(); break; case kTempoSync: m_tempoSync = (value >= 0.5f); RecalculateFrequency(); break; case kWaveform: m_waveForm = ParamToWaveform(value); if(m_waveForm >= kNumWaveforms) m_waveForm = static_cast(kNumWaveforms - 1); break; case kPolarity: m_polarity = (value >= 0.5f); break; case kBypassed: m_bypassed = (value >= 0.5f); break; case kLoopMode: m_oneshot = (value >= 0.5f); break; case kCurrentPhase: if(value == 0) { // Enforce next random value for random LFOs NextRandom(); } m_phase = value; return; default: return; } #ifdef MODPLUG_TRACKER if(GetEditor() != nullptr) { GetEditor()->PostMessage(WM_PARAM_UDPATE, GetSlot(), index); } #endif } void LFOPlugin::Resume() { m_isResumed = true; RecalculateIncrement(); NextRandom(); PositionChanged(); } void LFOPlugin::PositionChanged() { // TODO Changing tempo (with tempo sync enabled), parameter automation over time and setting the LFO phase manually is not considered here. m_phase = m_increment * m_SndFile.GetTotalSampleCount(); m_phase -= static_cast(m_phase); } bool LFOPlugin::MidiSend(uint32 midiCode) { if(IMixPlugin *plugin = GetOutputPlugin()) return plugin->MidiSend(midiCode); else return true; } bool LFOPlugin::MidiSysexSend(const void *message, uint32 length) { if(IMixPlugin *plugin = GetOutputPlugin()) return plugin->MidiSysexSend(message, length); else return true; } void LFOPlugin::MidiCC(uint8 nMidiCh, MIDIEvents::MidiCC nController, uint8 nParam, CHANNELINDEX trackChannel) { if(IMixPlugin *plugin = GetOutputPlugin()) { plugin->MidiCC(nMidiCh, nController, nParam, trackChannel); } } void LFOPlugin::MidiPitchBend(uint8 nMidiCh, int32 increment, int8 pwd) { if(IMixPlugin *plugin = GetOutputPlugin()) { plugin->MidiPitchBend(nMidiCh, increment, pwd); } } void LFOPlugin::MidiVibrato(uint8 nMidiCh, int32 depth, int8 pwd) { if(IMixPlugin *plugin = GetOutputPlugin()) { plugin->MidiVibrato(nMidiCh, depth, pwd); } } void LFOPlugin::MidiCommand(uint8 nMidiCh, uint8 nMidiProg, uint16 wMidiBank, uint16 note, uint16 vol, CHANNELINDEX trackChannel) { if(ModCommand::IsNote(static_cast(note)) && vol > 0) { SetParameter(kCurrentPhase, 0); } if(IMixPlugin *plugin = GetOutputPlugin()) { plugin->MidiCommand(nMidiCh, nMidiProg, wMidiBank, note, vol, trackChannel); } } void LFOPlugin::HardAllNotesOff() { if(IMixPlugin *plugin = GetOutputPlugin()) { plugin->HardAllNotesOff(); } } bool LFOPlugin::IsNotePlaying(uint32 note, uint32 midiChn, uint32 trackerChn) { if(IMixPlugin *plugin = GetOutputPlugin()) return plugin->IsNotePlaying(note, midiChn, trackerChn); else return false; } void LFOPlugin::SaveAllParameters() { auto chunk = GetChunk(false); if(chunk.empty()) return; m_pMixStruct->defaultProgram = -1; m_pMixStruct->pluginData.assign(chunk.cbegin(), chunk.cend()); } void LFOPlugin::RestoreAllParameters(int32 /*program*/) { SetChunk(mpt::as_span(m_pMixStruct->pluginData), false); } struct PluginData { char magic[4]; uint32le version; uint32le amplitude; // float uint32le offset; // float uint32le frequency; // float uint32le waveForm; uint32le outputParam; uint8le tempoSync; uint8le polarity; uint8le bypassed; uint8le outputToCC; uint8le loopMode; }; MPT_BINARY_STRUCT(PluginData, 33) IMixPlugin::ChunkData LFOPlugin::GetChunk(bool) { PluginData chunk; memcpy(chunk.magic, "LFO ", 4); chunk.version = 0; chunk.amplitude = IEEE754binary32LE(m_amplitude).GetInt32(); chunk.offset = IEEE754binary32LE(m_offset).GetInt32(); chunk.frequency = IEEE754binary32LE(m_frequency).GetInt32(); chunk.waveForm = m_waveForm; chunk.outputParam = m_outputParam; chunk.tempoSync = m_tempoSync ? 1 : 0; chunk.polarity = m_polarity ? 1 : 0; chunk.bypassed = m_bypassed ? 1 : 0; chunk.outputToCC = m_outputToCC ? 1 : 0; chunk.loopMode = m_oneshot ? 1 : 0; m_chunkData.resize(sizeof(chunk)); memcpy(m_chunkData.data(), &chunk, sizeof(chunk)); return mpt::as_span(m_chunkData); } void LFOPlugin::SetChunk(const ChunkData &chunk, bool) { FileReader file(chunk); PluginData data; if(file.ReadStructPartial(data, file.BytesLeft()) && !memcmp(data.magic, "LFO ", 4) && data.version == 0) { m_amplitude = Clamp(IEEE754binary32LE().SetInt32(data.amplitude), 0.0f, 1.0f); m_offset = Clamp(IEEE754binary32LE().SetInt32(data.offset), 0.0f, 1.0f); m_frequency = Clamp(IEEE754binary32LE().SetInt32(data.frequency), 0.0f, 1.0f); if(data.waveForm < kNumWaveforms) m_waveForm = static_cast(data.waveForm.get()); m_outputParam = data.outputParam; m_tempoSync = data.tempoSync != 0; m_polarity = data.polarity != 0; m_bypassed = data.bypassed != 0; m_outputToCC = data.outputToCC != 0; m_oneshot = data.loopMode != 0; } } #ifdef MODPLUG_TRACKER CString LFOPlugin::GetParamName(PlugParamIndex param) { switch(param) { case kAmplitude: return _T("Amplitude"); case kOffset: return _T("Offset"); case kFrequency: return _T("Frequency"); case kTempoSync: return _T("Tempo Sync"); case kWaveform: return _T("Waveform"); case kPolarity: return _T("Polarity"); case kBypassed: return _T("Bypassed"); case kLoopMode: return _T("Loop Mode"); case kCurrentPhase: return _T("Set LFO Phase"); } return CString(); } CString LFOPlugin::GetParamLabel(PlugParamIndex param) { if(param == kFrequency) { if(m_tempoSync && m_computedFrequency > 0.0 && m_computedFrequency < 1.0) return _T("Beats Per Cycle"); else if(m_tempoSync) return _T("Cycles Per Beat"); else return _T("Hz"); } return CString(); } CString LFOPlugin::GetParamDisplay(PlugParamIndex param) { CString s; if(param == kPolarity) { return m_polarity ? _T("Inverted") : _T("Normal"); } else if(param == kTempoSync) { return m_tempoSync ? _T("Yes") : _T("No"); } else if(param == kBypassed) { return m_bypassed ? _T("Yes") : _T("No"); } else if(param == kWaveform) { static const TCHAR *waveforms[] = { _T("Sine"), _T("Triangle"), _T("Saw"), _T("Square"), _T("Noise"), _T("Smoothed Noise") }; if(m_waveForm < MPT_ARRAY_COUNT(waveforms)) return waveforms[m_waveForm]; } else if(param == kLoopMode) { return m_oneshot ? _T("One-Shot") : _T("Looped"); } else if(param == kCurrentPhase) { return _T("Write-Only"); } else if(param < kLFONumParameters) { auto val = GetParameter(param); if(param == kOffset) val = 2.0f * val - 1.0f; if(param == kFrequency) { val = static_cast(m_computedFrequency); if(m_tempoSync && val > 0.0f && val < 1.0f) val = static_cast(1.0 / m_computedFrequency); } s.Format(_T("%.3f"), val); } return s; } CAbstractVstEditor *LFOPlugin::OpenEditor() { try { return new LFOPluginEditor(*this); } MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e) { MPT_EXCEPTION_DELETE_OUT_OF_MEMORY(e); return nullptr; } } #endif // MODPLUG_TRACKER void LFOPlugin::NextRandom() { m_random = m_nextRandom; m_nextRandom = mpt::random(m_PRNG) / static_cast(int32_min); } void LFOPlugin::RecalculateFrequency() { m_computedFrequency = 0.25 * std::pow(2.0, m_frequency * 8.0) - 0.25; if(m_tempoSync) { if(m_computedFrequency > 0.00045) { double freqLog = std::log(m_computedFrequency) / M_LN2; double freqFrac = freqLog - std::floor(freqLog); freqLog -= freqFrac; // Lock to powers of two and 1.5 times or 1.333333... times the powers of two if(freqFrac < 0.20751874963942190927313052802609) freqFrac = 0.0; else if(freqFrac < 0.5) freqFrac = 0.41503749927884381854626105605218; else if(freqFrac < 0.79248125036057809072686947197391) freqFrac = 0.58496250072115618145373894394782; else freqFrac = 1.0; m_computedFrequency = std::pow(2.0, freqLog + freqFrac) * 0.5; } else { m_computedFrequency = 0; } } RecalculateIncrement(); } void LFOPlugin::RecalculateIncrement() { m_increment = m_computedFrequency / m_SndFile.GetSampleRate(); if(m_tempoSync) { m_increment *= m_tempo / 60.0; } } IMixPlugin *LFOPlugin::GetOutputPlugin() const { PLUGINDEX outPlug = m_pMixStruct->GetOutputPlugin(); if(outPlug > m_nSlot && outPlug < MAX_MIXPLUGINS) return m_SndFile.m_MixPlugins[outPlug].pMixPlugin; else return nullptr; } OPENMPT_NAMESPACE_END #else MPT_MSVC_WORKAROUND_LNK4221(LFOPlugin) #endif // !NO_PLUGINS libopenmpt-0.3.6+release.autotools/soundlib/plugins/PluginManager.h0000644000372100037210000001201613161656666022500 00000000000000/* * PluginManager.h * --------------- * Purpose: Plugin management * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include OPENMPT_NAMESPACE_BEGIN #define PLUGMAGIC(a, b, c, d) \ ((((int32)a) << 24) | (((int32)b) << 16) | (((int32)c) << 8) | (((int32)d) << 0)) //#define kBuzzMagic PLUGMAGIC('B', 'u', 'z', 'z') #define kDmoMagic PLUGMAGIC('D', 'X', 'M', 'O') class CSoundFile; class IMixPlugin; struct SNDMIXPLUGIN; struct VSTPluginLib { public: enum PluginCategory { // Same plugin categories as defined in VST SDK catUnknown = 0, catEffect, // Simple Effect catSynth, // VST Instrument (Synths, samplers,...) catAnalysis, // Scope, Tuner, ... catMastering, // Dynamics, ... catSpacializer, // Panners, ... catRoomFx, // Delays and Reverbs catSurroundFx, // Dedicated surround processor catRestoration, // Denoiser, ... catOfflineProcess, // Offline Process catShell, // Plug-in is container of other plug-ins catGenerator, // Tone Generator, ... // Custom categories catDMO, // DirectX media object plugin numCategories, }; public: typedef IMixPlugin* (*CreateProc)(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct); IMixPlugin *pPluginsList; // Pointer to first plugin instance (this instance carries pointers to other instances) CreateProc Create; // Factory to call for this plugin mpt::PathString libraryName; // Display name mpt::PathString dllPath; // Full path name #ifdef MODPLUG_TRACKER mpt::ustring tags; // User tags CString vendor; #endif // MODPLUG_TRACKER int32 pluginId1; // Plugin type (kEffectMagic, kDmoMagic, ...) int32 pluginId2; // Plugin unique ID PluginCategory category; const bool isBuiltIn : 1; bool isInstrument : 1; bool useBridge : 1, shareBridgeInstance : 1; protected: mutable uint8 dllBits; public: VSTPluginLib(CreateProc factoryProc, bool isBuiltIn, const mpt::PathString &dllPath, const mpt::PathString &libraryName #ifdef MODPLUG_TRACKER , const mpt::ustring &tags = mpt::ustring(), const CString &vendor = CString() #endif // MODPLUG_TRACKER ) : pPluginsList(nullptr) , Create(factoryProc) , libraryName(libraryName), dllPath(dllPath) #ifdef MODPLUG_TRACKER , tags(tags) , vendor(vendor) #endif // MODPLUG_TRACKER , pluginId1(0), pluginId2(0) , category(catUnknown) , isBuiltIn(isBuiltIn), isInstrument(false) , useBridge(false), shareBridgeInstance(true) , dllBits(0) { } // Check whether a plugin can be hosted inside OpenMPT or requires bridging uint8 GetDllBits(bool fromCache = true) const; bool IsNative(bool fromCache = true) const { return GetDllBits(fromCache) == sizeof(void *) * CHAR_BIT; } // Check if a plugin is native, and if it is currently unknown, assume that it is native. Use this function only for performance reasons // (e.g. if tons of unscanned plugins would slow down generation of the plugin selection dialog) bool IsNativeFromCache() const { return dllBits == sizeof(void *) * CHAR_BIT || dllBits == 0; } void WriteToCache() const; uint32 EncodeCacheFlags() const { // Format: 00000000.00000000.DDDDDDSB.CCCCCCCI return (isInstrument ? 1 : 0) | (category << 1) | (useBridge ? 0x100 : 0) | (shareBridgeInstance ? 0x200 : 0) | ((dllBits / 8) << 10); } void DecodeCacheFlags(uint32 flags) { category = static_cast((flags & 0xFF) >> 1); if(category >= numCategories) { category = catUnknown; } if(flags & 1) { isInstrument = true; category = catSynth; } useBridge = (flags & 0x100) != 0; shareBridgeInstance = (flags & 0x200) != 0; dllBits = ((flags >> 10) & 0x3F) * 8; } }; class CVstPluginManager { #ifndef NO_PLUGINS protected: #ifndef NO_DMO bool MustUnInitilizeCOM; #endif std::vector pluginList; public: CVstPluginManager(); ~CVstPluginManager(); typedef std::vector::iterator iterator; typedef std::vector::const_iterator const_iterator; iterator begin() { return pluginList.begin(); } const_iterator begin() const { return pluginList.begin(); } iterator end() { return pluginList.end(); } const_iterator end() const { return pluginList.end(); } void reserve(size_t num) { pluginList.reserve(num); } bool IsValidPlugin(const VSTPluginLib *pLib) const; VSTPluginLib *AddPlugin(const mpt::PathString &dllPath, const mpt::ustring &tags = mpt::ustring(), bool fromCache = true, const bool checkFileExistence = false, std::wstring* const errStr = nullptr); bool RemovePlugin(VSTPluginLib *); bool CreateMixPlugin(SNDMIXPLUGIN &, CSoundFile &); void OnIdle(); static void ReportPlugException(const std::wstring &msg); static void ReportPlugException(const std::string &msg); protected: void EnumerateDirectXDMOs(); #else // NO_PLUGINS public: const VSTPluginLib **begin() const { return nullptr; } const VSTPluginLib **end() const { return nullptr; } void reserve(size_t) { } void OnIdle() {} #endif // NO_PLUGINS }; OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/plugins/DigiBoosterEcho.cpp0000644000372100037210000001271413161656666023320 00000000000000/* * DigiBoosterEcho.cpp * ------------------- * Purpose: Implementation of the DigiBooster Pro Echo DSP * Notes : (currently none) * Authors: OpenMPT Devs, based on original code by Grzegorz Kraszewski (BSD 2-clause) * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #ifndef NO_PLUGINS #include "../Sndfile.h" #include "DigiBoosterEcho.h" OPENMPT_NAMESPACE_BEGIN IMixPlugin* DigiBoosterEcho::Create(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct) { return new (std::nothrow) DigiBoosterEcho(factory, sndFile, mixStruct); } DigiBoosterEcho::DigiBoosterEcho(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct) : IMixPlugin(factory, sndFile, mixStruct) , m_bufferSize(0) , m_writePos(0) , m_sampleRate(sndFile.GetSampleRate()) { m_mixBuffer.Initialize(2, 2); InsertIntoFactoryList(); } void DigiBoosterEcho::Process(float *pOutL, float *pOutR, uint32 numFrames) { if(!m_bufferSize) return; const float *srcL = m_mixBuffer.GetInputBuffer(0), *srcR = m_mixBuffer.GetInputBuffer(1); float *outL = m_mixBuffer.GetOutputBuffer(0), *outR = m_mixBuffer.GetOutputBuffer(1); for(uint32 i = numFrames; i != 0; i--) { int readPos = m_writePos - m_delayTime; if(readPos < 0) readPos += m_bufferSize; float l = *srcL++, r = *srcR++; float lDelay = m_delayLine[readPos * 2], rDelay = m_delayLine[readPos * 2 + 1]; // Calculate the delay float al = l * m_NCrossNBack; al += r * m_PCrossNBack; al += lDelay * m_NCrossPBack; al += rDelay * m_PCrossPBack; float ar = r * m_NCrossNBack; ar += l * m_PCrossNBack; ar += rDelay * m_NCrossPBack; ar += lDelay * m_PCrossPBack; // Prevent denormals if(mpt::abs(al) < 1e-24f) al = 0.0f; if(mpt::abs(ar) < 1e-24f) ar = 0.0f; m_delayLine[m_writePos * 2] = al; m_delayLine[m_writePos * 2 + 1] = ar; m_writePos++; if(m_writePos == m_bufferSize) m_writePos = 0; // Output samples now *outL++ = (l * m_NMix + lDelay * m_PMix); *outR++ = (r * m_NMix + rDelay * m_PMix); } ProcessMixOps(pOutL, pOutR, m_mixBuffer.GetOutputBuffer(0), m_mixBuffer.GetOutputBuffer(1), numFrames); } void DigiBoosterEcho::SaveAllParameters() { m_pMixStruct->defaultProgram = -1; try { m_pMixStruct->pluginData.resize(sizeof(m_chunk)); memcpy(m_pMixStruct->pluginData.data(), &m_chunk, sizeof(m_chunk)); } MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e) { MPT_EXCEPTION_DELETE_OUT_OF_MEMORY(e); m_pMixStruct->pluginData.clear(); } } void DigiBoosterEcho::RestoreAllParameters(int32 program) { if(m_pMixStruct->pluginData.size() == sizeof(m_chunk) && !memcmp(m_pMixStruct->pluginData.data(), "Echo", 4)) { memcpy(&m_chunk, m_pMixStruct->pluginData.data(), sizeof(m_chunk)); } else { IMixPlugin::RestoreAllParameters(program); } RecalculateEchoParams(); } PlugParamValue DigiBoosterEcho::GetParameter(PlugParamIndex index) { if(index < kEchoNumParameters) { return m_chunk.param[index] / 255.0f; } return 0; } void DigiBoosterEcho::SetParameter(PlugParamIndex index, PlugParamValue value) { if(index < kEchoNumParameters) { m_chunk.param[index] = Util::Round(value * 255.0f); RecalculateEchoParams(); } } void DigiBoosterEcho::Resume() { m_isResumed = true; m_sampleRate = m_SndFile.GetSampleRate(); RecalculateEchoParams(); PositionChanged(); } void DigiBoosterEcho::PositionChanged() { m_bufferSize = (m_sampleRate >> 1) + (m_sampleRate >> 6); try { m_delayLine.assign(m_bufferSize * 2, 0); } MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e) { MPT_EXCEPTION_DELETE_OUT_OF_MEMORY(e); m_bufferSize = 0; } m_writePos = 0; } #ifdef MODPLUG_TRACKER CString DigiBoosterEcho::GetParamName(PlugParamIndex param) { switch(param) { case kEchoDelay: return _T("Delay"); case kEchoFeedback: return _T("Feedback"); case kEchoMix: return _T("Wet / Dry Ratio"); case kEchoCross: return _T("Cross Echo"); } return CString(); } CString DigiBoosterEcho::GetParamLabel(PlugParamIndex param) { if(param == kEchoDelay) return _T("ms"); return CString(); } CString DigiBoosterEcho::GetParamDisplay(PlugParamIndex param) { CString s; if(param == kEchoMix) { int wet = (m_chunk.param[kEchoMix] * 100) / 255; s.Format(_T("%d%% / %d%%"), wet, 100 - wet); } else if(param < kEchoNumParameters) { int val = m_chunk.param[param]; if(param == kEchoDelay) val *= 2; s.Format(_T("%d"), val); } return s; } #endif // MODPLUG_TRACKER IMixPlugin::ChunkData DigiBoosterEcho::GetChunk(bool) { auto data = reinterpret_cast(&m_chunk); return ChunkData(data, sizeof(m_chunk)); } void DigiBoosterEcho::SetChunk(const ChunkData &chunk, bool) { auto data = chunk.data(); if(chunk.size() == sizeof(chunk) && !memcmp(data, "Echo", 4)) { memcpy(&m_chunk, data, chunk.size()); RecalculateEchoParams(); } } void DigiBoosterEcho::RecalculateEchoParams() { m_delayTime = (m_chunk.param[kEchoDelay] * m_sampleRate + 250) / 500; m_PMix = (m_chunk.param[kEchoMix]) * (1.0f / 256.0f); m_NMix = (256 - m_chunk.param[kEchoMix]) * (1.0f / 256.0f); m_PCrossPBack = (m_chunk.param[kEchoCross] * m_chunk.param[kEchoFeedback]) * (1.0f / 65536.0f); m_PCrossNBack = (m_chunk.param[kEchoCross] * (256 - m_chunk.param[kEchoFeedback])) * (1.0f / 65536.0f); m_NCrossPBack = ((m_chunk.param[kEchoCross] - 256) * m_chunk.param[kEchoFeedback]) * (1.0f / 65536.0f); m_NCrossNBack = ((m_chunk.param[kEchoCross] - 256) * (m_chunk.param[kEchoFeedback] - 256)) * (1.0f / 65536.0f); } OPENMPT_NAMESPACE_END #endif // NO_PLUGINS libopenmpt-0.3.6+release.autotools/soundlib/plugins/PluginMixBuffer.h0000644000372100037210000000651713161656666023026 00000000000000/* * PluginMixBuffer.h * ----------------- * Purpose: Helper class for managing plugin audio input and output buffers. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once OPENMPT_NAMESPACE_BEGIN // At least this part of the code is ready for double-precision rendering... :> // buffer_t: Sample buffer type (float, double, ...) // bufferSize: Buffer size in samples template class PluginMixBuffer { protected: std::vector mixBuffer; // Actual buffer, contains all input and output buffers std::vector inputs; // Pointers to input buffers std::vector outputs; // Pointers to output buffers buffer_t *alignedBuffer; // Aligned pointer to the buffer // Align buffer to 16 bytes static_assert(sizeof(buffer_t) < 16, "Check buffer alignment code"); static const uintptr_t bufferAlignmentInBytes = (16 - 1); static const uintptr_t additionalBuffer = bufferAlignmentInBytes / sizeof(buffer_t); // Return pointer to an aligned buffer buffer_t *GetBuffer(size_t index) const { MPT_ASSERT(index < inputs.size() + outputs.size()); return &alignedBuffer[bufferSize * index]; } public: // Allocate input and output buffers bool Initialize(uint32 numInputs, uint32 numOutputs) { // Short cut - we do not need to recreate the buffers. if(inputs.size() == numInputs && outputs.size() == numOutputs) { return true; } try { inputs.resize(numInputs); outputs.resize(numOutputs); // Create inputs + outputs buffers with additional alignment. const size_t totalBufferSize = bufferSize * (numInputs + numOutputs) + additionalBuffer; mixBuffer.assign(totalBufferSize, 0); // Align buffer start. alignedBuffer = reinterpret_cast((reinterpret_cast(mixBuffer.data()) + bufferAlignmentInBytes) & ~bufferAlignmentInBytes); } MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e) { MPT_EXCEPTION_DELETE_OUT_OF_MEMORY(e); inputs.clear(); outputs.clear(); mixBuffer.clear(); alignedBuffer = nullptr; return false; } for(uint32 i = 0; i < numInputs; i++) { inputs[i] = GetInputBuffer(i); } for(uint32 i = 0; i < numOutputs; i++) { outputs[i] = GetOutputBuffer(i); } return true; } // Silence all input buffers. void ClearInputBuffers(uint32 numSamples) { MPT_ASSERT(numSamples <= bufferSize); for(size_t i = 0; i < inputs.size(); i++) { memset(inputs[i], 0, numSamples * sizeof(buffer_t)); } } // Silence all output buffers. void ClearOutputBuffers(uint32 numSamples) { MPT_ASSERT(numSamples <= bufferSize); for(size_t i = 0; i < outputs.size(); i++) { memset(outputs[i], 0, numSamples * sizeof(buffer_t)); } } PluginMixBuffer() { Initialize(2, 0); } // Return pointer to a given input or output buffer buffer_t *GetInputBuffer(uint32 index) const { return GetBuffer(index); } buffer_t *GetOutputBuffer(uint32 index) const { return GetBuffer(inputs.size() + index); } // Return pointer array to all input or output buffers buffer_t **GetInputBufferArray() { return inputs.empty() ? nullptr : inputs.data(); } buffer_t **GetOutputBufferArray() { return outputs.empty() ? nullptr : outputs.data(); } bool Ok() const { return alignedBuffer != nullptr; } }; OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/SampleFormatFLAC.cpp0000644000372100037210000005220213161656666021642 00000000000000/* * SampleFormatFLAC.cpp * -------------------- * Purpose: FLAC sample import. * Notes : * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Sndfile.h" #ifdef MODPLUG_TRACKER #include "../mptrack/TrackerSettings.h" #endif //MODPLUG_TRACKER #ifndef MODPLUG_NO_FILESAVE #include "../common/mptFileIO.h" #endif #include "../common/misc_util.h" #include "Tagging.h" #include "Loaders.h" #include "WAVTools.h" #include "ChunkReader.h" #include "modsmp_ctrl.h" #include "../soundbase/SampleFormatConverters.h" #include "../soundbase/SampleFormatCopy.h" #include "../soundlib/ModSampleCopy.h" //#include "../common/mptCRC.h" #include "OggStream.h" #ifdef MPT_WITH_OGG #include #endif // MPT_WITH_OGG #ifdef MPT_WITH_FLAC #include #include #include #endif // MPT_WITH_FLAC OPENMPT_NAMESPACE_BEGIN /////////////////////////////////////////////////////////////////////////////////////////////////// // FLAC Samples #ifdef MPT_WITH_FLAC struct FLACDecoder { FileReader &file; CSoundFile &sndFile; SAMPLEINDEX sample; bool ready; FLACDecoder(FileReader &f, CSoundFile &sf, SAMPLEINDEX smp) : file(f), sndFile(sf), sample(smp), ready(false) { } static FLAC__StreamDecoderReadStatus read_cb(const FLAC__StreamDecoder *, FLAC__byte buffer[], size_t *bytes, void *client_data) { FileReader &file = static_cast(client_data)->file; if(*bytes > 0) { FileReader::off_t readBytes = *bytes; LimitMax(readBytes, file.BytesLeft()); file.ReadRaw(buffer, readBytes); *bytes = readBytes; if(*bytes == 0) return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; else return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; } else { return FLAC__STREAM_DECODER_READ_STATUS_ABORT; } } static FLAC__StreamDecoderSeekStatus seek_cb(const FLAC__StreamDecoder *, FLAC__uint64 absolute_byte_offset, void *client_data) { FileReader &file = static_cast(client_data)->file; if(!file.Seek(static_cast(absolute_byte_offset))) return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR; else return FLAC__STREAM_DECODER_SEEK_STATUS_OK; } static FLAC__StreamDecoderTellStatus tell_cb(const FLAC__StreamDecoder *, FLAC__uint64 *absolute_byte_offset, void *client_data) { FileReader &file = static_cast(client_data)->file; *absolute_byte_offset = file.GetPosition(); return FLAC__STREAM_DECODER_TELL_STATUS_OK; } static FLAC__StreamDecoderLengthStatus length_cb(const FLAC__StreamDecoder *, FLAC__uint64 *stream_length, void *client_data) { FileReader &file = static_cast(client_data)->file; *stream_length = file.GetLength(); return FLAC__STREAM_DECODER_LENGTH_STATUS_OK; } static FLAC__bool eof_cb(const FLAC__StreamDecoder *, void *client_data) { FileReader &file = static_cast(client_data)->file; return file.NoBytesLeft(); } static FLAC__StreamDecoderWriteStatus write_cb(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *const buffer[], void *client_data) { FLACDecoder &client = *static_cast(client_data); ModSample &sample = client.sndFile.GetSample(client.sample); if(frame->header.number.sample_number >= sample.nLength || !client.ready) { // We're reading beyond the sample size already, or we aren't even ready to decode yet! return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; } // Number of samples to be copied in this call const SmpLength copySamples = std::min(static_cast(frame->header.blocksize), static_cast(sample.nLength - frame->header.number.sample_number)); // Number of target channels const uint8 modChannels = sample.GetNumChannels(); // Offset (in samples) into target data const size_t offset = static_cast(frame->header.number.sample_number) * modChannels; // Source size in bytes const size_t srcSize = frame->header.blocksize * 4; // Source bit depth const unsigned int bps = frame->header.bits_per_sample; int8 *sampleData8 = sample.pSample8 + offset; int16 *sampleData16 = sample.pSample16 + offset; MPT_ASSERT((bps <= 8 && sample.GetElementarySampleSize() == 1) || (bps > 8 && sample.GetElementarySampleSize() == 2)); MPT_ASSERT(modChannels <= FLAC__stream_decoder_get_channels(decoder)); MPT_ASSERT(bps == FLAC__stream_decoder_get_bits_per_sample(decoder)); MPT_UNREFERENCED_PARAMETER(decoder); // decoder is unused if ASSERTs are compiled out // Do the sample conversion for(uint8 chn = 0; chn < modChannels; chn++) { if(bps <= 8) { CopySample, SC::DecodeIdentity > >(sampleData8 + chn, copySamples, modChannels, buffer[chn], srcSize, 1); } else if(bps <= 16) { CopySample, SC::DecodeIdentity > >(sampleData16 + chn, copySamples, modChannels, buffer[chn], srcSize, 1); } else if(bps <= 24) { CopySample, SC::DecodeIdentity > >(sampleData16 + chn, copySamples, modChannels, buffer[chn], srcSize, 1); } else if(bps <= 32) { CopySample, SC::DecodeIdentity > >(sampleData16 + chn, copySamples, modChannels, buffer[chn], srcSize, 1); } } return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; } static void metadata_cb(const FLAC__StreamDecoder *, const FLAC__StreamMetadata *metadata, void *client_data) { FLACDecoder &client = *static_cast(client_data); if(client.sample > client.sndFile.GetNumSamples()) { client.sndFile.m_nSamples = client.sample; } ModSample &sample = client.sndFile.GetSample(client.sample); if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO && metadata->data.stream_info.total_samples != 0) { // Init sample information client.sndFile.DestroySampleThreadsafe(client.sample); strcpy(client.sndFile.m_szNames[client.sample], ""); sample.Initialize(); sample.uFlags.set(CHN_16BIT, metadata->data.stream_info.bits_per_sample > 8); sample.uFlags.set(CHN_STEREO, metadata->data.stream_info.channels > 1); sample.nLength = mpt::saturate_cast(metadata->data.stream_info.total_samples); sample.nC5Speed = metadata->data.stream_info.sample_rate; client.ready = (sample.AllocateSample() != 0); } else if(metadata->type == FLAC__METADATA_TYPE_APPLICATION && !memcmp(metadata->data.application.id, "riff", 4) && client.ready) { // Try reading RIFF loop points and other sample information ChunkReader data(mpt::as_span(metadata->data.application.data, metadata->length)); ChunkReader::ChunkList chunks = data.ReadChunks(2); // We're not really going to read a WAV file here because there will be only one RIFF chunk per metadata event, but we can still re-use the code for parsing RIFF metadata... WAVReader riffReader(data); riffReader.FindMetadataChunks(chunks); riffReader.ApplySampleSettings(sample, client.sndFile.m_szNames[client.sample]); } else if(metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT && client.ready) { // Try reading Vorbis Comments for sample title, sample rate and loop points SmpLength loopStart = 0, loopLength = 0; for(FLAC__uint32 i = 0; i < metadata->data.vorbis_comment.num_comments; i++) { const char *tag = mpt::byte_cast(metadata->data.vorbis_comment.comments[i].entry); const FLAC__uint32 length = metadata->data.vorbis_comment.comments[i].length; if(length > 6 && !mpt::CompareNoCaseAscii(tag, "TITLE=", 6)) { mpt::String::Read(client.sndFile.m_szNames[client.sample], tag + 6, length - 6); } else if(length > 11 && !mpt::CompareNoCaseAscii(tag, "SAMPLERATE=", 11)) { uint32 sampleRate = ConvertStrTo(tag + 11); if(sampleRate > 0) sample.nC5Speed = sampleRate; } else if(length > 10 && !mpt::CompareNoCaseAscii(tag, "LOOPSTART=", 10)) { loopStart = ConvertStrTo(tag + 10); } else if(length > 11 && !mpt::CompareNoCaseAscii(tag, "LOOPLENGTH=", 11)) { loopLength = ConvertStrTo(tag + 11); } } if(loopLength > 0) { sample.nLoopStart = loopStart; sample.nLoopEnd = loopStart + loopLength; sample.uFlags.set(CHN_LOOP); sample.SanitizeLoops(); } } } static void error_cb(const FLAC__StreamDecoder *, FLAC__StreamDecoderErrorStatus, void *) { } }; #endif // MPT_WITH_FLAC bool CSoundFile::ReadFLACSample(SAMPLEINDEX sample, FileReader &file) { #ifdef MPT_WITH_FLAC file.Rewind(); bool isOgg = false; #ifdef MPT_WITH_OGG uint32 oggFlacBitstreamSerial = 0; #endif // Check whether we are dealing with native FLAC, OggFlac or no FLAC at all. if(file.ReadMagic("fLaC")) { // ok isOgg = false; #ifdef MPT_WITH_OGG } else if(file.ReadMagic("OggS")) { // use libogg to find the first OggFlac stream header file.Rewind(); bool oggOK = false; bool needMoreData = true; static const long bufsize = 65536; std::size_t readSize = 0; char *buf = nullptr; ogg_sync_state oy; MemsetZero(oy); ogg_page og; MemsetZero(og); std::map oggStreams; ogg_packet op; MemsetZero(op); if(ogg_sync_init(&oy) != 0) { return false; } while(needMoreData) { if(file.NoBytesLeft()) { // stop at EOF oggOK = false; needMoreData = false; break; } buf = ogg_sync_buffer(&oy, bufsize); if(!buf) { oggOK = false; needMoreData = false; break; } readSize = file.ReadRaw(buf, bufsize); if(ogg_sync_wrote(&oy, static_cast(readSize)) != 0) { oggOK = false; needMoreData = false; break; } while(ogg_sync_pageout(&oy, &og) == 1) { if(!ogg_page_bos(&og)) { // we stop scanning when seeing the first noo-begin-of-stream page oggOK = false; needMoreData = false; break; } uint32 serial = ogg_page_serialno(&og); if(!oggStreams[serial]) { // previously unseen stream serial oggStreams[serial] = new ogg_stream_state(); MemsetZero(*(oggStreams[serial])); if(ogg_stream_init(oggStreams[serial], serial) != 0) { delete oggStreams[serial]; oggStreams.erase(serial); oggOK = false; needMoreData = false; break; } } if(ogg_stream_pagein(oggStreams[serial], &og) != 0) { // invalid page oggOK = false; needMoreData = false; break; } if(ogg_stream_packetout(oggStreams[serial], &op) != 1) { // partial or broken packet, continue with more data continue; } if(op.packetno != 0) { // non-begin-of-stream packet. // This should not appear on first page for any known ogg codec, // but deal gracefully with badly mused streams in that regard. continue; } FileReader packet(mpt::as_span(op.packet, op.bytes)); if(packet.ReadIntLE() == 0x7f && packet.ReadMagic("FLAC")) { // looks like OggFlac oggOK = true; oggFlacBitstreamSerial = serial; needMoreData = false; break; } } } while(oggStreams.size() > 0) { uint32 serial = oggStreams.begin()->first; ogg_stream_clear(oggStreams[serial]); delete oggStreams[serial]; oggStreams.erase(serial); } ogg_sync_clear(&oy); if(!oggOK) { return false; } isOgg = true; #else // !MPT_WITH_OGG } else if(file.CanRead(78) && file.ReadMagic("OggS")) { // first OggFlac page is exactly 78 bytes long // only support plain OggFlac here with the FLAC logical bitstream being the first one uint8 oggPageVersion = file.ReadIntLE(); uint8 oggPageHeaderType = file.ReadIntLE(); uint64 oggPageGranulePosition = file.ReadIntLE(); uint32 oggPageBitstreamSerialNumber = file.ReadIntLE(); uint32 oggPageSequenceNumber = file.ReadIntLE(); uint32 oggPageChecksum = file.ReadIntLE(); uint8 oggPageSegments = file.ReadIntLE(); uint8 oggPageSegmentLength = file.ReadIntLE(); if(oggPageVersion != 0) { // unknown Ogg version return false; } if(!(oggPageHeaderType & 0x02) || (oggPageHeaderType& 0x01)) { // not BOS or continuation return false; } if(oggPageGranulePosition != 0) { // not starting position return false; } if(oggPageSequenceNumber != 0) { // not first page return false; } // skip CRC check for now if(oggPageSegments != 1) { // first OggFlac page must contain exactly 1 segment return false; } if(oggPageSegmentLength != 51) { // segment length must be 51 bytes in OggFlac mapping return false; } if(file.ReadIntLE() != 0x7f) { // OggFlac mapping demands 0x7f packet type return false; } if(!file.ReadMagic("FLAC")) { // OggFlac magic return false; } if(file.ReadIntLE() != 0x01) { // OggFlac major version return false; } // by now, we are pretty confident that we are not parsing random junk isOgg = true; #endif // MPT_WITH_OGG } else { return false; } file.Rewind(); FLAC__StreamDecoder *decoder = FLAC__stream_decoder_new(); if(decoder == nullptr) { return false; } #ifdef MPT_WITH_OGG if(isOgg) { // force flac decoding of the logical bitstream that actually is OggFlac if(!FLAC__stream_decoder_set_ogg_serial_number(decoder, oggFlacBitstreamSerial)) { FLAC__stream_decoder_delete(decoder); return false; } } #endif // Give me all the metadata! FLAC__stream_decoder_set_metadata_respond_all(decoder); FLACDecoder client(file, *this, sample); // Init decoder FLAC__StreamDecoderInitStatus initStatus = isOgg ? FLAC__stream_decoder_init_ogg_stream(decoder, FLACDecoder::read_cb, FLACDecoder::seek_cb, FLACDecoder::tell_cb, FLACDecoder::length_cb, FLACDecoder::eof_cb, FLACDecoder::write_cb, FLACDecoder::metadata_cb, FLACDecoder::error_cb, &client) : FLAC__stream_decoder_init_stream(decoder, FLACDecoder::read_cb, FLACDecoder::seek_cb, FLACDecoder::tell_cb, FLACDecoder::length_cb, FLACDecoder::eof_cb, FLACDecoder::write_cb, FLACDecoder::metadata_cb, FLACDecoder::error_cb, &client) ; if(initStatus != FLAC__STREAM_DECODER_INIT_STATUS_OK) { FLAC__stream_decoder_delete(decoder); return false; } // Decode file FLAC__stream_decoder_process_until_end_of_stream(decoder); FLAC__stream_decoder_finish(decoder); FLAC__stream_decoder_delete(decoder); if(client.ready && Samples[sample].pSample != nullptr) { Samples[sample].Convert(MOD_TYPE_IT, GetType()); Samples[sample].PrecomputeLoops(*this, false); return true; } #else MPT_UNREFERENCED_PARAMETER(sample); MPT_UNREFERENCED_PARAMETER(file); #endif // MPT_WITH_FLAC return false; } #ifdef MPT_WITH_FLAC // Helper function for copying OpenMPT's sample data to FLAC's int32 buffer. template inline static void SampleToFLAC32(FLAC__int32 *dst, const T *src, SmpLength numSamples) { for(SmpLength i = 0; i < numSamples; i++) { dst[i] = src[i]; } }; // RAII-style helper struct for FLAC encoder struct FLAC__StreamEncoder_RAII { FLAC__StreamEncoder *encoder; FILE *f; operator FLAC__StreamEncoder *() { return encoder; } FLAC__StreamEncoder_RAII() : encoder(FLAC__stream_encoder_new()), f(nullptr) { } ~FLAC__StreamEncoder_RAII() { FLAC__stream_encoder_delete(encoder); if(f != nullptr) fclose(f); } }; #endif #ifndef MODPLUG_NO_FILESAVE bool CSoundFile::SaveFLACSample(SAMPLEINDEX nSample, const mpt::PathString &filename) const { #ifdef MPT_WITH_FLAC FLAC__StreamEncoder_RAII encoder; if(encoder == nullptr) { return false; } const ModSample &sample = Samples[nSample]; uint32 sampleRate = sample.GetSampleRate(GetType()); // First off, set up all the metadata... FLAC__StreamMetadata *metadata[] = { FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT), FLAC__metadata_object_new(FLAC__METADATA_TYPE_APPLICATION), // MPT sample information FLAC__metadata_object_new(FLAC__METADATA_TYPE_APPLICATION), // Loop points FLAC__metadata_object_new(FLAC__METADATA_TYPE_APPLICATION), // Cue points }; unsigned numBlocks = 2; if(metadata[0]) { // Store sample name FLAC__StreamMetadata_VorbisComment_Entry entry; FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(&entry, "TITLE", m_szNames[nSample]); FLAC__metadata_object_vorbiscomment_append_comment(metadata[0], entry, false); FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(&entry, "ENCODER", MptVersion::GetOpenMPTVersionStr().c_str()); FLAC__metadata_object_vorbiscomment_append_comment(metadata[0], entry, false); if(sampleRate > FLAC__MAX_SAMPLE_RATE) { // FLAC only supports a sample rate of up to 655350 Hz. // Store the real sample rate in a custom Vorbis comment. FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(&entry, "SAMPLERATE", mpt::fmt::val(sampleRate).c_str()); FLAC__metadata_object_vorbiscomment_append_comment(metadata[0], entry, false); } } if(metadata[1]) { // Write MPT sample information memcpy(metadata[1]->data.application.id, "riff", 4); struct { RIFFChunk header; WAVExtraChunk mptInfo; } chunk; chunk.header.id = RIFFChunk::idxtra; chunk.header.length = sizeof(WAVExtraChunk); chunk.mptInfo.ConvertToWAV(sample, GetType()); const uint32 length = sizeof(RIFFChunk) + sizeof(WAVExtraChunk); FLAC__metadata_object_application_set_data(metadata[1], reinterpret_cast(&chunk), length, true); } if(metadata[numBlocks] && (sample.uFlags[CHN_LOOP | CHN_SUSTAINLOOP] || ModCommand::IsNote(sample.rootNote))) { // Store loop points / root note information memcpy(metadata[numBlocks]->data.application.id, "riff", 4); struct { RIFFChunk header; WAVSampleInfoChunk info; WAVSampleLoop loops[2]; } chunk; chunk.header.id = RIFFChunk::idsmpl; chunk.header.length = sizeof(WAVSampleInfoChunk); chunk.info.ConvertToWAV(sample.GetSampleRate(GetType()), sample.rootNote); if(sample.uFlags[CHN_SUSTAINLOOP]) { chunk.loops[chunk.info.numLoops++].ConvertToWAV(sample.nSustainStart, sample.nSustainEnd, sample.uFlags[CHN_PINGPONGSUSTAIN]); chunk.header.length += sizeof(WAVSampleLoop); } if(sample.uFlags[CHN_LOOP]) { chunk.loops[chunk.info.numLoops++].ConvertToWAV(sample.nLoopStart, sample.nLoopEnd, sample.uFlags[CHN_PINGPONGLOOP]); chunk.header.length += sizeof(WAVSampleLoop); } const uint32 length = sizeof(RIFFChunk) + chunk.header.length; FLAC__metadata_object_application_set_data(metadata[numBlocks], reinterpret_cast(&chunk), length, true); numBlocks++; } if(metadata[numBlocks] && sample.HasCustomCuePoints()) { // Store cue points memcpy(metadata[numBlocks]->data.application.id, "riff", 4); struct { RIFFChunk header; uint32le numPoints; WAVCuePoint cues[CountOf(sample.cues)]; } chunk; chunk.header.id = RIFFChunk::idcue_; chunk.header.length = 4 + sizeof(chunk.cues); chunk.numPoints = CountOf(sample.cues); for(uint32 i = 0; i < CountOf(sample.cues); i++) { chunk.cues[i].ConvertToWAV(i, sample.cues[i]); } const uint32 length = sizeof(RIFFChunk) + chunk.header.length; FLAC__metadata_object_application_set_data(metadata[numBlocks], reinterpret_cast(&chunk), length, true); numBlocks++; } // FLAC allows a maximum sample rate of 655350 Hz. // If the real rate is higher, we store it in a Vorbis comment above. LimitMax(sampleRate, FLAC__MAX_SAMPLE_RATE); if(!FLAC__format_sample_rate_is_subset(sampleRate)) { // FLAC only supports 10 Hz granularity for frequencies above 65535 Hz if the streamable subset is chosen. FLAC__stream_encoder_set_streamable_subset(encoder, false); } FLAC__stream_encoder_set_channels(encoder, sample.GetNumChannels()); FLAC__stream_encoder_set_bits_per_sample(encoder, sample.GetElementarySampleSize() * 8); FLAC__stream_encoder_set_sample_rate(encoder, sampleRate); FLAC__stream_encoder_set_total_samples_estimate(encoder, sample.nLength); FLAC__stream_encoder_set_metadata(encoder, metadata, numBlocks); #ifdef MODPLUG_TRACKER FLAC__stream_encoder_set_compression_level(encoder, TrackerSettings::Instance().m_FLACCompressionLevel); #endif // MODPLUG_TRACKER bool result = false; FLAC__int32 *sampleData = nullptr; encoder.f = mpt_fopen(filename, "wb"); if(encoder.f == nullptr || FLAC__stream_encoder_init_FILE(encoder, encoder.f, nullptr, nullptr) != FLAC__STREAM_ENCODER_INIT_STATUS_OK) { goto fail; } // Convert sample data to signed 32-Bit integer array. const SmpLength numSamples = sample.nLength * sample.GetNumChannels(); sampleData = new (std::nothrow) FLAC__int32[numSamples]; if(sampleData == nullptr) { goto fail; } if(sample.GetElementarySampleSize() == 1) { SampleToFLAC32(sampleData, sample.pSample8, numSamples); } else if(sample.GetElementarySampleSize() == 2) { SampleToFLAC32(sampleData, sample.pSample16, numSamples); } else { MPT_ASSERT_NOTREACHED(); } // Do the actual conversion. FLAC__stream_encoder_process_interleaved(encoder, sampleData, sample.nLength); result = true; fail: FLAC__stream_encoder_finish(encoder); delete[] sampleData; for(auto m : metadata) { FLAC__metadata_object_delete(m); } return result; #else MPT_UNREFERENCED_PARAMETER(nSample); MPT_UNREFERENCED_PARAMETER(filename); return false; #endif // MPT_WITH_FLAC } #endif // MODPLUG_NO_FILESAVE OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/load_j2b.cpp0000644000372100037210000006617513222676633020306 00000000000000/* * load_j2b.cpp * ------------ * Purpose: RIFF AM and RIFF AMFF (Galaxy Sound System) module loader * Notes : J2B is a compressed variant of RIFF AM and RIFF AMFF files used in Jazz Jackrabbit 2. * It seems like no other game used the AM(FF) format. * RIFF AM is the newer version of the format, generally following the RIFF "standard" closely. * Authors: Johannes Schultz (OpenMPT port, reverse engineering + loader implementation of the instrument format) * Chris Moeller (foo_dumb - this is almost a complete port of his code, thanks) * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" #include "ChunkReader.h" #if defined(MPT_WITH_ZLIB) #include #elif defined(MPT_WITH_MINIZ) #include #endif OPENMPT_NAMESPACE_BEGIN // First off, a nice vibrato translation LUT. static const uint8 j2bAutoVibratoTrans[] = { VIB_SINE, VIB_SQUARE, VIB_RAMP_UP, VIB_RAMP_DOWN, VIB_RANDOM, }; // header for compressed j2b files struct J2BFileHeader { // Magic Bytes // 32-Bit J2B header identifiers static const uint32 magicDEADBEAF = 0xAFBEADDEu; static const uint32 magicDEADBABE = 0xBEBAADDEu; char signature[4]; // MUSE uint32le deadbeaf; // 0xDEADBEAF (AM) or 0xDEADBABE (AMFF) uint32le fileLength; // complete filesize uint32le crc32; // checksum of the compressed data block uint32le packedLength; // length of the compressed data block uint32le unpackedLength; // length of the decompressed module }; MPT_BINARY_STRUCT(J2BFileHeader, 24) // AM(FF) stuff struct AMFFRiffChunk { // 32-Bit chunk identifiers enum ChunkIdentifiers { idRIFF = MAGIC4LE('R','I','F','F'), idAMFF = MAGIC4LE('A','M','F','F'), idAM__ = MAGIC4LE('A','M',' ',' '), idMAIN = MAGIC4LE('M','A','I','N'), idINIT = MAGIC4LE('I','N','I','T'), idORDR = MAGIC4LE('O','R','D','R'), idPATT = MAGIC4LE('P','A','T','T'), idINST = MAGIC4LE('I','N','S','T'), idSAMP = MAGIC4LE('S','A','M','P'), idAI__ = MAGIC4LE('A','I',' ',' '), idAS__ = MAGIC4LE('A','S',' ',' '), }; uint32le id; // See ChunkIdentifiers uint32le length; // Chunk size without header size_t GetLength() const { return length; } ChunkIdentifiers GetID() const { return static_cast(id.get()); } }; MPT_BINARY_STRUCT(AMFFRiffChunk, 8) // This header is used for both AM's "INIT" as well as AMFF's "MAIN" chunk struct AMFFMainChunk { // Main Chunk flags enum MainFlags { amigaSlides = 0x01, }; char songname[64]; uint8le flags; uint8le channels; uint8le speed; uint8le tempo; uint16le minPeriod; // 16x Amiga periods, but we should ignore them - otherwise some high notes in Medivo.j2b won't sound correct. uint16le maxPeriod; // Ditto uint8le globalvolume; }; MPT_BINARY_STRUCT(AMFFMainChunk, 73) // AMFF instrument envelope (old format) struct AMFFEnvelope { // Envelope flags (also used for RIFF AM) enum EnvelopeFlags { envEnabled = 0x01, envSustain = 0x02, envLoop = 0x04, }; struct EnvPoint { uint16le tick; uint8le value; // 0...64 }; uint8le envFlags; // high nibble = pan env flags, low nibble = vol env flags (both nibbles work the same way) uint8le envNumPoints; // high nibble = pan env length, low nibble = vol env length uint8le envSustainPoints; // you guessed it... high nibble = pan env sustain point, low nibble = vol env sustain point uint8le envLoopStarts; // I guess you know the pattern now. uint8le envLoopEnds; // same here. EnvPoint volEnv[10]; EnvPoint panEnv[10]; // Convert weird envelope data to OpenMPT's internal format. void ConvertEnvelope(uint8 flags, uint8 numPoints, uint8 sustainPoint, uint8 loopStart, uint8 loopEnd, const EnvPoint (&points)[10], InstrumentEnvelope &mptEnv) const { // The buggy mod2j2b converter will actually NOT limit this to 10 points if the envelope is longer. mptEnv.resize(std::min(numPoints, static_cast(10))); mptEnv.nSustainStart = mptEnv.nSustainEnd = sustainPoint; mptEnv.nLoopStart = loopStart; mptEnv.nLoopEnd = loopEnd; for(uint32 i = 0; i < mptEnv.size(); i++) { mptEnv[i].tick = points[i].tick >> 4; if(i == 0) mptEnv[0].tick = 0; else if(mptEnv[i].tick < mptEnv[i - 1].tick) mptEnv[i].tick = mptEnv[i - 1].tick + 1; mptEnv[i].value = Clamp(points[i].value, 0, 64); } mptEnv.dwFlags.set(ENV_ENABLED, (flags & AMFFEnvelope::envEnabled) != 0); mptEnv.dwFlags.set(ENV_SUSTAIN, (flags & AMFFEnvelope::envSustain) && mptEnv.nSustainStart <= mptEnv.size()); mptEnv.dwFlags.set(ENV_LOOP, (flags & AMFFEnvelope::envLoop) && mptEnv.nLoopStart <= mptEnv.nLoopEnd && mptEnv.nLoopStart <= mptEnv.size()); } void ConvertToMPT(ModInstrument &mptIns) const { // interleaved envelope data... meh. gotta split it up here and decode it separately. // note: mod2j2b is BUGGY and always writes ($original_num_points & 0x0F) in the header, // but just has room for 10 envelope points. That means that long (>= 16 points) // envelopes are cut off, and envelopes have to be trimmed to 10 points, even if // the header claims that they are longer. // For XM files the number of points also appears to be off by one, // but luckily there are no official J2Bs using envelopes anyway. ConvertEnvelope(envFlags & 0x0F, envNumPoints & 0x0F, envSustainPoints & 0x0F, envLoopStarts & 0x0F, envLoopEnds & 0x0F, volEnv, mptIns.VolEnv); ConvertEnvelope(envFlags >> 4, envNumPoints >> 4, envSustainPoints >> 4, envLoopStarts >> 4, envLoopEnds >> 4, panEnv, mptIns.PanEnv); } }; MPT_BINARY_STRUCT(AMFFEnvelope::EnvPoint, 3) MPT_BINARY_STRUCT(AMFFEnvelope, 65) // AMFF instrument header (old format) struct AMFFInstrumentHeader { uint8le unknown; // 0x00 uint8le index; // actual instrument number char name[28]; uint8le numSamples; uint8le sampleMap[120]; uint8le vibratoType; uint16le vibratoSweep; uint16le vibratoDepth; uint16le vibratoRate; AMFFEnvelope envelopes; uint16le fadeout; // Convert instrument data to OpenMPT's internal format. void ConvertToMPT(ModInstrument &mptIns, SAMPLEINDEX baseSample) { mpt::String::Read(mptIns.name, name); STATIC_ASSERT(CountOf(sampleMap) <= CountOf(mptIns.Keyboard)); for(size_t i = 0; i < CountOf(sampleMap); i++) { mptIns.Keyboard[i] = sampleMap[i] + baseSample + 1; } mptIns.nFadeOut = fadeout << 5; envelopes.ConvertToMPT(mptIns); } }; MPT_BINARY_STRUCT(AMFFInstrumentHeader, 225) // AMFF sample header (old format) struct AMFFSampleHeader { // Sample flags (also used for RIFF AM) enum SampleFlags { smp16Bit = 0x04, smpLoop = 0x08, smpPingPong = 0x10, smpPanning = 0x20, smpExists = 0x80, // some flags are still missing... what is e.g. 0x8000? }; uint32le id; // "SAMP" uint32le chunkSize; // header + sample size char name[28]; uint8le pan; uint8le volume; uint16le flags; uint32le length; uint32le loopStart; uint32le loopEnd; uint32le sampleRate; uint32le reserved1; uint32le reserved2; // Convert sample header to OpenMPT's internal format. void ConvertToMPT(AMFFInstrumentHeader &instrHeader, ModSample &mptSmp) const { mptSmp.Initialize(); mptSmp.nPan = pan * 4; mptSmp.nVolume = volume * 4; mptSmp.nGlobalVol = 64; mptSmp.nLength = length; mptSmp.nLoopStart = loopStart; mptSmp.nLoopEnd = loopEnd; mptSmp.nC5Speed = sampleRate; if(instrHeader.vibratoType < CountOf(j2bAutoVibratoTrans)) mptSmp.nVibType = j2bAutoVibratoTrans[instrHeader.vibratoType]; mptSmp.nVibSweep = static_cast(instrHeader.vibratoSweep); mptSmp.nVibRate = static_cast(instrHeader.vibratoRate / 16); mptSmp.nVibDepth = static_cast(instrHeader.vibratoDepth / 4); if((mptSmp.nVibRate | mptSmp.nVibDepth) != 0) { // Convert XM-style vibrato sweep to IT mptSmp.nVibSweep = 255 - mptSmp.nVibSweep; } if(flags & AMFFSampleHeader::smp16Bit) mptSmp.uFlags.set(CHN_16BIT); if(flags & AMFFSampleHeader::smpLoop) mptSmp.uFlags.set(CHN_LOOP); if(flags & AMFFSampleHeader::smpPingPong) mptSmp.uFlags.set(CHN_PINGPONGLOOP); if(flags & AMFFSampleHeader::smpPanning) mptSmp.uFlags.set(CHN_PANNING); } // Retrieve the internal sample format flags for this sample. SampleIO GetSampleFormat() const { return SampleIO( (flags & AMFFSampleHeader::smp16Bit) ? SampleIO::_16bit : SampleIO::_8bit, SampleIO::mono, SampleIO::littleEndian, SampleIO::signedPCM); } }; MPT_BINARY_STRUCT(AMFFSampleHeader, 64) // AM instrument envelope (new format) struct AMEnvelope { struct EnvPoint { uint16le tick; uint16le value; }; uint16le flags; uint8le numPoints; // actually, it's num. points - 1, and 0xFF if there is no envelope uint8le sustainPoint; uint8le loopStart; uint8le loopEnd; EnvPoint values[10]; uint16le fadeout; // why is this here? it's only needed for the volume envelope... // Convert envelope data to OpenMPT's internal format. void ConvertToMPT(InstrumentEnvelope &mptEnv, EnvelopeType envType) const { if(numPoints == 0xFF || numPoints == 0) return; mptEnv.resize(std::min(numPoints + 1, 10)); mptEnv.nSustainStart = mptEnv.nSustainEnd = sustainPoint; mptEnv.nLoopStart = loopStart; mptEnv.nLoopEnd = loopEnd; for(uint32 i = 0; i < mptEnv.size(); i++) { mptEnv[i].tick = values[i].tick >> 4; if(i == 0) mptEnv[i].tick = 0; else if(mptEnv[i].tick < mptEnv[i - 1].tick) mptEnv[i].tick = mptEnv[i - 1].tick + 1; const uint16 val = values[i].value; switch(envType) { case ENV_VOLUME: // 0....32767 default: mptEnv[i].value = (uint8)((val + 1) >> 9); break; case ENV_PITCH: // -4096....4096 mptEnv[i].value = (uint8)((((int16)val) + 0x1001) >> 7); break; case ENV_PANNING: // -32768...32767 mptEnv[i].value = (uint8)((((int16)val) + 0x8001) >> 10); break; } Limit(mptEnv[i].value, uint8(ENVELOPE_MIN), uint8(ENVELOPE_MAX)); } mptEnv.dwFlags.set(ENV_ENABLED, (flags & AMFFEnvelope::envEnabled) != 0); mptEnv.dwFlags.set(ENV_SUSTAIN, (flags & AMFFEnvelope::envSustain) && mptEnv.nSustainStart <= mptEnv.size()); mptEnv.dwFlags.set(ENV_LOOP, (flags & AMFFEnvelope::envLoop) && mptEnv.nLoopStart <= mptEnv.nLoopEnd && mptEnv.nLoopStart <= mptEnv.size()); } }; MPT_BINARY_STRUCT(AMEnvelope::EnvPoint, 4) MPT_BINARY_STRUCT(AMEnvelope, 48) // AM instrument header (new format) struct AMInstrumentHeader { uint32le headSize; // Header size (i.e. the size of this struct) uint8le unknown1; // 0x00 uint8le index; // Actual instrument number char name[32]; uint8le sampleMap[128]; uint8le vibratoType; uint16le vibratoSweep; uint16le vibratoDepth; uint16le vibratoRate; uint8le unknown2[7]; AMEnvelope volEnv; AMEnvelope pitchEnv; AMEnvelope panEnv; uint16le numSamples; // Convert instrument data to OpenMPT's internal format. void ConvertToMPT(ModInstrument &mptIns, SAMPLEINDEX baseSample) { mpt::String::Read(mptIns.name, name); STATIC_ASSERT(CountOf(sampleMap) <= CountOf(mptIns.Keyboard)); for(uint8 i = 0; i < CountOf(sampleMap); i++) { mptIns.Keyboard[i] = sampleMap[i] + baseSample + 1; } mptIns.nFadeOut = volEnv.fadeout << 5; volEnv.ConvertToMPT(mptIns.VolEnv, ENV_VOLUME); pitchEnv.ConvertToMPT(mptIns.PitchEnv, ENV_PITCH); panEnv.ConvertToMPT(mptIns.PanEnv, ENV_PANNING); if(numSamples == 0) { MemsetZero(mptIns.Keyboard); } } }; MPT_BINARY_STRUCT(AMInstrumentHeader, 326) // AM sample header (new format) struct AMSampleHeader { uint32le headSize; // Header size (i.e. the size of this struct), apparently not including headSize. char name[32]; uint16le pan; uint16le volume; uint16le flags; uint16le unknown; // 0x0000 / 0x0080? uint32le length; uint32le loopStart; uint32le loopEnd; uint32le sampleRate; // Convert sample header to OpenMPT's internal format. void ConvertToMPT(AMInstrumentHeader &instrHeader, ModSample &mptSmp) const { mptSmp.Initialize(); mptSmp.nPan = std::min(pan, 32767) * 256 / 32767; mptSmp.nVolume = std::min(volume, 32767) * 256 / 32767; mptSmp.nGlobalVol = 64; mptSmp.nLength = length; mptSmp.nLoopStart = loopStart; mptSmp.nLoopEnd = loopEnd; mptSmp.nC5Speed = sampleRate; if(instrHeader.vibratoType < CountOf(j2bAutoVibratoTrans)) mptSmp.nVibType = j2bAutoVibratoTrans[instrHeader.vibratoType]; mptSmp.nVibSweep = static_cast(instrHeader.vibratoSweep); mptSmp.nVibRate = static_cast(instrHeader.vibratoRate / 16); mptSmp.nVibDepth = static_cast(instrHeader.vibratoDepth / 4); if((mptSmp.nVibRate | mptSmp.nVibDepth) != 0) { // Convert XM-style vibrato sweep to IT mptSmp.nVibSweep = 255 - mptSmp.nVibSweep; } if(flags & AMFFSampleHeader::smp16Bit) mptSmp.uFlags.set(CHN_16BIT); if(flags & AMFFSampleHeader::smpLoop) mptSmp.uFlags.set(CHN_LOOP); if(flags & AMFFSampleHeader::smpPingPong) mptSmp.uFlags.set(CHN_PINGPONGLOOP); if(flags & AMFFSampleHeader::smpPanning) mptSmp.uFlags.set(CHN_PANNING); } // Retrieve the internal sample format flags for this sample. SampleIO GetSampleFormat() const { return SampleIO( (flags & AMFFSampleHeader::smp16Bit) ? SampleIO::_16bit : SampleIO::_8bit, SampleIO::mono, SampleIO::littleEndian, SampleIO::signedPCM); } }; MPT_BINARY_STRUCT(AMSampleHeader, 60) // Convert RIFF AM(FF) pattern data to MPT pattern data. static bool ConvertAMPattern(FileReader chunk, PATTERNINDEX pat, bool isAM, CSoundFile &sndFile) { // Effect translation LUT static const EffectCommand amEffTrans[] = { CMD_ARPEGGIO, CMD_PORTAMENTOUP, CMD_PORTAMENTODOWN, CMD_TONEPORTAMENTO, CMD_VIBRATO, CMD_TONEPORTAVOL, CMD_VIBRATOVOL, CMD_TREMOLO, CMD_PANNING8, CMD_OFFSET, CMD_VOLUMESLIDE, CMD_POSITIONJUMP, CMD_VOLUME, CMD_PATTERNBREAK, CMD_MODCMDEX, CMD_TEMPO, CMD_GLOBALVOLUME, CMD_GLOBALVOLSLIDE, CMD_KEYOFF, CMD_SETENVPOSITION, CMD_CHANNELVOLUME, CMD_CHANNELVOLSLIDE, CMD_PANNINGSLIDE, CMD_RETRIG, CMD_TREMOR, CMD_XFINEPORTAUPDOWN, }; enum { rowDone = 0, // Advance to next row channelMask = 0x1F, // Mask for retrieving channel information volFlag = 0x20, // Volume effect present noteFlag = 0x40, // Note + instr present effectFlag = 0x80, // Effect information present dataFlag = 0xE0, // Channel data present }; if(chunk.NoBytesLeft()) { return false; } ROWINDEX numRows = Clamp(static_cast(chunk.ReadUint8()) + 1, ROWINDEX(1), MAX_PATTERN_ROWS); if(!sndFile.Patterns.Insert(pat, numRows)) return false; const CHANNELINDEX channels = sndFile.GetNumChannels(); if(channels == 0) return false; PatternRow rowBase = sndFile.Patterns[pat].GetRow(0); ROWINDEX row = 0; while(row < numRows && chunk.CanRead(1)) { const uint8 flags = chunk.ReadUint8(); if(flags == rowDone) { row++; rowBase = sndFile.Patterns[pat].GetRow(row); continue; } ModCommand &m = rowBase[std::min((flags & channelMask), channels - 1)]; if(flags & dataFlag) { if(flags & effectFlag) // effect { m.param = chunk.ReadUint8(); uint8 command = chunk.ReadUint8(); if(command < CountOf(amEffTrans)) { // command translation m.command = amEffTrans[command]; } else { #ifdef DEBUG Log(mpt::format("J2B: Unknown command: 0x%1, param 0x%2")(mpt::fmt::HEX0<2>(command), mpt::fmt::HEX0<2>(m.param))); #endif // DEBUG m.command = CMD_NONE; } // Handling special commands switch(m.command) { case CMD_ARPEGGIO: if(m.param == 0) m.command = CMD_NONE; break; case CMD_VOLUME: if(m.volcmd == VOLCMD_NONE) { m.volcmd = VOLCMD_VOLUME; m.vol = Clamp(m.param, uint8(0), uint8(64)); m.command = CMD_NONE; m.param = 0; } break; case CMD_TONEPORTAVOL: case CMD_VIBRATOVOL: case CMD_VOLUMESLIDE: case CMD_GLOBALVOLSLIDE: case CMD_PANNINGSLIDE: if (m.param & 0xF0) m.param &= 0xF0; break; case CMD_PANNING8: if(m.param <= 0x80) m.param = MIN(m.param << 1, 0xFF); else if(m.param == 0xA4) {m.command = CMD_S3MCMDEX; m.param = 0x91;} break; case CMD_PATTERNBREAK: m.param = ((m.param >> 4) * 10) + (m.param & 0x0F); break; case CMD_MODCMDEX: m.ExtendedMODtoS3MEffect(); break; case CMD_TEMPO: if(m.param <= 0x1F) m.command = CMD_SPEED; break; case CMD_XFINEPORTAUPDOWN: switch(m.param & 0xF0) { case 0x10: m.command = CMD_PORTAMENTOUP; break; case 0x20: m.command = CMD_PORTAMENTODOWN; break; } m.param = (m.param & 0x0F) | 0xE0; break; } } if (flags & noteFlag) // note + ins { m.instr = chunk.ReadUint8(); m.note = chunk.ReadUint8(); if(m.note == 0x80) m.note = NOTE_KEYOFF; else if(m.note > 0x80) m.note = NOTE_FADE; // I guess the support for IT "note fade" notes was not intended in mod2j2b, but hey, it works! :-D } if (flags & volFlag) // volume { m.volcmd = VOLCMD_VOLUME; m.vol = chunk.ReadUint8(); if(isAM) { m.vol = m.vol * 64 / 127; } } } } return true; } struct AMFFRiffChunkFormat { uint32le format; }; MPT_BINARY_STRUCT(AMFFRiffChunkFormat, 4) static bool ValidateHeader(const AMFFRiffChunk &fileHeader) { if(fileHeader.id != AMFFRiffChunk::idRIFF) { return false; } if(fileHeader.GetLength() < 8 + sizeof(AMFFMainChunk)) { return false; } return true; } static bool ValidateHeader(const AMFFRiffChunkFormat &formatHeader) { if(formatHeader.format != AMFFRiffChunk::idAMFF && formatHeader.format != AMFFRiffChunk::idAM__) { return false; } return true; } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderAM(MemoryFileReader file, const uint64 *pfilesize) { AMFFRiffChunk fileHeader; if(!file.ReadStruct(fileHeader)) { return ProbeWantMoreData; } if(!ValidateHeader(fileHeader)) { return ProbeFailure; } AMFFRiffChunkFormat formatHeader; if(!file.ReadStruct(formatHeader)) { return ProbeWantMoreData; } if(!ValidateHeader(formatHeader)) { return ProbeFailure; } MPT_UNREFERENCED_PARAMETER(pfilesize); return ProbeSuccess; } bool CSoundFile::ReadAM(FileReader &file, ModLoadingFlags loadFlags) { file.Rewind(); AMFFRiffChunk fileHeader; if(!file.ReadStruct(fileHeader)) { return false; } if(!ValidateHeader(fileHeader)) { return false; } AMFFRiffChunkFormat formatHeader; if(!file.ReadStruct(formatHeader)) { return false; } if(!ValidateHeader(formatHeader)) { return false; } bool isAM; // false: AMFF, true: AM uint32 format = formatHeader.format; if(format == AMFFRiffChunk::idAMFF) isAM = false; // "AMFF" else if(format == AMFFRiffChunk::idAM__) isAM = true; // "AM " else return false; ChunkReader chunkFile(file); // The main chunk is almost identical in both formats but uses different chunk IDs. // "MAIN" - Song info (AMFF) // "INIT" - Song info (AM) AMFFRiffChunk::ChunkIdentifiers mainChunkID = isAM ? AMFFRiffChunk::idINIT : AMFFRiffChunk::idMAIN; // RIFF AM has a padding byte so that all chunks have an even size. ChunkReader::ChunkList chunks; if(loadFlags == onlyVerifyHeader) chunks = chunkFile.ReadChunksUntil(isAM ? 2 : 1, mainChunkID); else chunks = chunkFile.ReadChunks(isAM ? 2 : 1); FileReader chunkMain(chunks.GetChunk(mainChunkID)); AMFFMainChunk mainChunk; if(!chunkMain.IsValid() || !chunkMain.ReadStruct(mainChunk) || mainChunk.channels < 1 || !chunkMain.CanRead(mainChunk.channels)) { return false; } else if(loadFlags == onlyVerifyHeader) { return true; } InitializeGlobals(MOD_TYPE_J2B); m_SongFlags = SONG_ITOLDEFFECTS | SONG_ITCOMPATGXX; m_SongFlags.set(SONG_LINEARSLIDES, !(mainChunk.flags & AMFFMainChunk::amigaSlides)); m_nChannels = MIN(mainChunk.channels, MAX_BASECHANNELS); m_nDefaultSpeed = mainChunk.speed; m_nDefaultTempo.Set(mainChunk.tempo); m_nDefaultGlobalVolume = mainChunk.globalvolume * 2; m_madeWithTracker = MPT_USTRING("Galaxy Sound System ("); if(isAM) m_madeWithTracker += MPT_USTRING("new version)"); else m_madeWithTracker += MPT_USTRING("old version)"); mpt::String::Read(m_songName, mainChunk.songname); // It seems like there's no way to differentiate between // Muted and Surround channels (they're all 0xA0) - might // be a limitation in mod2j2b. for(CHANNELINDEX nChn = 0; nChn < m_nChannels; nChn++) { ChnSettings[nChn].Reset(); uint8 pan = chunkMain.ReadUint8(); if(isAM) { if(pan > 128) ChnSettings[nChn].dwFlags = CHN_MUTE; else ChnSettings[nChn].nPan = pan * 2; } else { if(pan >= 128) ChnSettings[nChn].dwFlags = CHN_MUTE; else ChnSettings[nChn].nPan = static_cast(std::min(pan * 4, 256)); } } if(chunks.ChunkExists(AMFFRiffChunk::idORDR)) { // "ORDR" - Order list FileReader chunk(chunks.GetChunk(AMFFRiffChunk::idORDR)); uint8 numOrders = chunk.ReadUint8() + 1; ReadOrderFromFile(Order(), chunk, numOrders, 0xFF, 0xFE); } // "PATT" - Pattern data for one pattern if(loadFlags & loadPatternData) { PATTERNINDEX maxPattern = 0; auto pattChunks = chunks.GetAllChunks(AMFFRiffChunk::idPATT); Patterns.ResizeArray(static_cast(pattChunks.size())); for(auto chunk : pattChunks) { PATTERNINDEX pat = chunk.ReadUint8(); size_t patternSize = chunk.ReadUint32LE(); ConvertAMPattern(chunk.ReadChunk(patternSize), pat, isAM, *this); maxPattern = std::max(maxPattern, pat); } for(PATTERNINDEX pat = 0; pat < maxPattern; pat++) { if(!Patterns.IsValidPat(pat)) Patterns.Insert(pat, 64); } } if(!isAM) { // "INST" - Instrument (only in RIFF AMFF) auto instChunks = chunks.GetAllChunks(AMFFRiffChunk::idINST); for(auto chunk : instChunks) { AMFFInstrumentHeader instrHeader; if(!chunk.ReadStruct(instrHeader)) { continue; } const INSTRUMENTINDEX instr = instrHeader.index + 1; if(instr >= MAX_INSTRUMENTS) continue; ModInstrument *pIns = AllocateInstrument(instr); if(pIns == nullptr) { continue; } instrHeader.ConvertToMPT(*pIns, m_nSamples); // read sample sub-chunks - this is a rather "flat" format compared to RIFF AM and has no nested RIFF chunks. for(size_t samples = 0; samples < instrHeader.numSamples; samples++) { AMFFSampleHeader sampleHeader; if(m_nSamples + 1 >= MAX_SAMPLES || !chunk.ReadStruct(sampleHeader)) { continue; } const SAMPLEINDEX smp = ++m_nSamples; if(sampleHeader.id != AMFFRiffChunk::idSAMP) { continue; } mpt::String::Read(m_szNames[smp], sampleHeader.name); sampleHeader.ConvertToMPT(instrHeader, Samples[smp]); if(loadFlags & loadSampleData) sampleHeader.GetSampleFormat().ReadSample(Samples[smp], chunk); else chunk.Skip(Samples[smp].GetSampleSizeInBytes()); } } } else { // "RIFF" - Instrument (only in RIFF AM) auto instChunks = chunks.GetAllChunks(AMFFRiffChunk::idRIFF); for(ChunkReader chunk : instChunks) { if(chunk.ReadUint32LE() != AMFFRiffChunk::idAI__) { continue; } AMFFRiffChunk instChunk; if(!chunk.ReadStruct(instChunk) || instChunk.id != AMFFRiffChunk::idINST) { continue; } AMInstrumentHeader instrHeader; if(!chunk.ReadStruct(instrHeader)) { continue; } MPT_ASSERT(instrHeader.headSize + 4 == sizeof(instrHeader)); const INSTRUMENTINDEX instr = instrHeader.index + 1; if(instr >= MAX_INSTRUMENTS) continue; ModInstrument *pIns = AllocateInstrument(instr); if(pIns == nullptr) { continue; } instrHeader.ConvertToMPT(*pIns, m_nSamples); // Read sample sub-chunks (RIFF nesting ftw) auto sampleChunks = chunk.ReadChunks(2).GetAllChunks(AMFFRiffChunk::idRIFF); MPT_ASSERT(sampleChunks.size() == instrHeader.numSamples); for(auto sampleChunk : sampleChunks) { if(sampleChunk.ReadUint32LE() != AMFFRiffChunk::idAS__ || m_nSamples + 1 >= MAX_SAMPLES) { continue; } // Don't read more samples than the instrument header claims to have. if((instrHeader.numSamples--) == 0) { break; } const SAMPLEINDEX smp = ++m_nSamples; // Aaand even more nested chunks! Great, innit? AMFFRiffChunk sampleHeaderChunk; if(!sampleChunk.ReadStruct(sampleHeaderChunk) || sampleHeaderChunk.id != AMFFRiffChunk::idSAMP) { break; } FileReader sampleFileChunk = sampleChunk.ReadChunk(sampleHeaderChunk.length); AMSampleHeader sampleHeader; if(!sampleFileChunk.ReadStruct(sampleHeader)) { break; } mpt::String::Read(m_szNames[smp], sampleHeader.name); sampleHeader.ConvertToMPT(instrHeader, Samples[smp]); if(loadFlags & loadSampleData) { sampleFileChunk.Seek(sampleHeader.headSize + 4); sampleHeader.GetSampleFormat().ReadSample(Samples[smp], sampleFileChunk); } } } } return true; } static bool ValidateHeader(const J2BFileHeader &fileHeader) { if(std::memcmp(fileHeader.signature, "MUSE", 4) || (fileHeader.deadbeaf != J2BFileHeader::magicDEADBEAF // 0xDEADBEAF (RIFF AM) && fileHeader.deadbeaf != J2BFileHeader::magicDEADBABE) // 0xDEADBABE (RIFF AMFF) ) { return false; } if(fileHeader.packedLength == 0) { return false; } if(fileHeader.fileLength != fileHeader.packedLength + sizeof(J2BFileHeader)) { return false; } return true; } static bool ValidateHeaderFileSize(const J2BFileHeader &fileHeader, uint64 filesize) { if(filesize != fileHeader.fileLength) { return false; } return true; } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderJ2B(MemoryFileReader file, const uint64 *pfilesize) { J2BFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return ProbeWantMoreData; } if(!ValidateHeader(fileHeader)) { return ProbeFailure; } if(pfilesize) { if(!ValidateHeaderFileSize(fileHeader, *pfilesize)) { return ProbeFailure; } } MPT_UNREFERENCED_PARAMETER(pfilesize); return ProbeSuccess; } bool CSoundFile::ReadJ2B(FileReader &file, ModLoadingFlags loadFlags) { #if !defined(MPT_WITH_ZLIB) && !defined(MPT_WITH_MINIZ) MPT_UNREFERENCED_PARAMETER(file); MPT_UNREFERENCED_PARAMETER(loadFlags); return false; #else file.Rewind(); J2BFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return false; } if(!ValidateHeader(fileHeader)) { return false; } if(fileHeader.fileLength != file.GetLength() || fileHeader.packedLength != file.BytesLeft() ) { return false; } if(loadFlags == onlyVerifyHeader) { return true; } FileReader::PinnedRawDataView filePackedView = file.GetPinnedRawDataView(fileHeader.packedLength); #ifndef MPT_BUILD_FUZZER if(fileHeader.crc32 != crc32(0, mpt::byte_cast(filePackedView.data()), static_cast(filePackedView.size()))) { return false; } #endif // Header is valid, now unpack the RIFF AM file using inflate uLongf destSize = fileHeader.unpackedLength; std::vector amFileData(destSize); int retVal = uncompress(amFileData.data(), &destSize, mpt::byte_cast(filePackedView.data()), static_cast(filePackedView.size())); bool result = false; #ifndef MPT_BUILD_FUZZER if(destSize == fileHeader.unpackedLength && retVal == Z_OK) #endif { // Success, now load the RIFF AM(FF) module. FileReader amFile(mpt::as_span(amFileData)); result = ReadAM(amFile, loadFlags); } return result; #endif } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/RowVisitor.cpp0000644000372100037210000001501413161656666020751 00000000000000/* * RowVisitor.cpp * -------------- * Purpose: Class for managing which rows of a song has already been visited. Useful for detecting backwards jumps, loops, etc. * Notes : The class keeps track of rows that have been visited by the player before. * This way, we can tell when the module starts to loop, i.e. we can determine the song length, * or find out that a given point of the module can never be reached. * * Specific implementations: * * Length detection code: * As the ModPlug engine already deals with pattern loops sufficiently (though not always correctly), * there's no problem with (infinite) pattern loops in this code. * * Normal player code: * Bear in mind that rows inside pattern loops should only be evaluated once, or else the algorithm will cancel too early! * So in that case, the pattern loop rows have to be reset when looping back. * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Sndfile.h" #include "RowVisitor.h" OPENMPT_NAMESPACE_BEGIN RowVisitor::RowVisitor(const CSoundFile &sf, SEQUENCEINDEX sequence) : m_sndFile(sf) , m_currentOrder(0) , m_sequence(sequence) { Initialize(true); } const ModSequence &RowVisitor::Order() const { if(m_sequence >= m_sndFile.Order.GetNumSequences()) return m_sndFile.Order(); else return m_sndFile.Order(m_sequence); } // Resize / Clear the row vector. // If reset is true, the vector is not only resized to the required dimensions, but also completely cleared (i.e. all visited rows are unset). void RowVisitor::Initialize(bool reset) { auto &order = Order(); const ORDERINDEX endOrder = order.GetLengthTailTrimmed(); m_visitedRows.resize(endOrder); if(reset) { m_visitOrder.clear(); // Pre-allocate maximum amount of memory most likely needed for keeping track of visited rows in a pattern if(m_visitOrder.capacity() < MAX_PATTERN_ROWS) { ROWINDEX maxRows = 0; for(PATTERNINDEX pat = 0; pat < m_sndFile.Patterns.Size(); pat++) { maxRows = std::max(maxRows, m_sndFile.Patterns[pat].GetNumRows()); } m_visitOrder.reserve(maxRows); } } for(ORDERINDEX ord = 0; ord < endOrder; ord++) { auto &row = m_visitedRows[ord]; const size_t size = GetVisitedRowsVectorSize(order[ord]); if(reset) { // If we want to reset the vectors completely, we overwrite existing items with false. row.assign(size, false); } else { row.resize(size, false); } } } // (Un)sets a given row as visited. // order, row - which row should be (un)set // If visited is true, the row will be set as visited. void RowVisitor::SetVisited(ORDERINDEX ord, ROWINDEX row, bool visited) { auto &order = Order(); if(ord >= order.size() || row >= GetVisitedRowsVectorSize(order[ord])) { return; } // The module might have been edited in the meantime - so we have to extend this a bit. if(ord >= m_visitedRows.size() || row >= m_visitedRows[ord].size()) { Initialize(false); // If it's still past the end of the vector, this means that ord >= order.GetLengthTailTrimmed(), i.e. we are trying to play an empty order. if(ord >= m_visitedRows.size()) { return; } } m_visitedRows[ord][row] = visited; if(visited) { AddVisitedRow(ord, row); } } // Returns whether a given row has been visited yet. // If autoSet is true, the queried row will automatically be marked as visited. // Use this parameter instead of consecutive IsRowVisited / SetRowVisited calls. bool RowVisitor::IsVisited(ORDERINDEX ord, ROWINDEX row, bool autoSet) { if(ord >= Order().size()) { return false; } // The row slot for this row has not been assigned yet - Just return false, as this means that the program has not played the row yet. if(ord >= m_visitedRows.size() || row >= m_visitedRows[ord].size()) { if(autoSet) { SetVisited(ord, row, true); } return false; } if(m_visitedRows[ord][row]) { // We visited this row already - this module must be looping. return true; } else if(autoSet) { m_visitedRows[ord][row] = true; AddVisitedRow(ord, row); } return false; } // Get the needed vector size for pattern nPat. size_t RowVisitor::GetVisitedRowsVectorSize(PATTERNINDEX pattern) const { if(m_sndFile.Patterns.IsValidPat(pattern)) { return static_cast(m_sndFile.Patterns[pattern].GetNumRows()); } else { // Invalid patterns consist of a "fake" row. return 1; } } // Find the first row that has not been played yet. // The order and row is stored in the order and row variables on success, on failure they contain invalid values. // If fastSearch is true (default), only the first row of each pattern is looked at, otherwise every row is examined. // Function returns true on success. bool RowVisitor::GetFirstUnvisitedRow(ORDERINDEX &ord, ROWINDEX &row, bool fastSearch) const { auto &order = Order(); const ORDERINDEX endOrder = order.GetLengthTailTrimmed(); for(ord = 0; ord < endOrder; ord++) { const PATTERNINDEX pattern = order[ord]; if(!m_sndFile.Patterns.IsValidPat(pattern)) { continue; } if(ord >= m_visitedRows.size()) { // Not yet initialized => unvisited return true; } const ROWINDEX endRow = (fastSearch ? 1 : m_sndFile.Patterns[pattern].GetNumRows()); for(row = 0; row < endRow; row++) { if(row >= m_visitedRows[ord].size() || m_visitedRows[ord][row] == false) { // Not yet initialized, or unvisited return true; } } } // Didn't find anything :( ord = ORDERINDEX_INVALID; row = ROWINDEX_INVALID; return false; } // Set all rows of a previous pattern loop as unvisited. void RowVisitor::ResetPatternLoop(ORDERINDEX ord, ROWINDEX startRow) { MPT_ASSERT(ord == m_currentOrder); // Shouldn't trigger, unless we're jumping around in the GUI during a pattern loop. // Unvisit all rows that are in the visited row buffer, until we hit the start row for this pattern loop. ROWINDEX row = ROWINDEX_INVALID; for(auto iter = m_visitOrder.crbegin(); iter != m_visitOrder.crend() && row != startRow; iter++) { row = *iter; Unvisit(ord, row); } } // Add a row to the visited row memory for this pattern. void RowVisitor::AddVisitedRow(ORDERINDEX ord, ROWINDEX row) { if(ord != m_currentOrder) { // We're in a new pattern! Forget about which rows we previously visited... m_visitOrder.clear(); m_currentOrder = ord; } if(m_visitOrder.empty()) { m_visitOrder.reserve(GetVisitedRowsVectorSize(Order()[ord])); } // And now add the played row to our memory. m_visitOrder.push_back(row); } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Dither.h0000644000372100037210000000311313161656666017503 00000000000000/* * Dither.h * -------- * Purpose: Dithering when converting to lower resolution sample formats. * Notes : (currently none) * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "../common/mptRandom.h" OPENMPT_NAMESPACE_BEGIN struct DitherModPlugState { uint32 rng_a; uint32 rng_b; DitherModPlugState() { rng_a = 0; rng_b = 0; } }; struct DitherSimpleState { int32 error[4]; DitherSimpleState() { error[0] = 0; error[1] = 0; error[2] = 0; error[3] = 0; } }; struct DitherState { DitherModPlugState modplug; DitherSimpleState simple; mpt::fast_prng prng; void Reset() { modplug = DitherModPlugState(); simple = DitherSimpleState(); } template DitherState(Trd & rd) : prng(mpt::make_prng(rd)) { return; } }; enum DitherMode { DitherNone = 0, DitherDefault = 1, // chosen by OpenMPT code, might change DitherModPlug = 2, // rectangular, 0.5 bit depth, no noise shaping (original ModPlug Tracker) DitherSimple = 3, // rectangular, 1 bit depth, simple 1st order noise shaping NumDitherModes }; class Dither { private: DitherState state; DitherMode mode; public: template Dither(Trd & rd) : state(rd) { mode = DitherDefault; } void SetMode(DitherMode mode_); DitherMode GetMode() const; void Reset(); void Process(int *mixbuffer, std::size_t count, std::size_t channels, int bits); static mpt::ustring GetModeName(DitherMode mode); }; OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/MIDIMacros.cpp0000644000372100037210000002727413161656666020524 00000000000000/* * MIDIMacros.cpp * -------------- * Purpose: Helper functions / classes for MIDI Macro functionality. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "../soundlib/MIDIEvents.h" #include "MIDIMacros.h" #include "../common/StringFixer.h" #include "../common/misc_util.h" #ifdef MODPLUG_TRACKER #include "Sndfile.h" #include "plugins/PlugInterface.h" #endif // MODPLUG_TRACKER OPENMPT_NAMESPACE_BEGIN parameteredMacroType MIDIMacroConfig::GetParameteredMacroType(uint32 macroIndex) const { const std::string macro = GetSafeMacro(szMidiSFXExt[macroIndex]); for(uint32 i = 0; i < sfx_max; i++) { parameteredMacroType sfx = static_cast(i); if(sfx != sfx_custom) { if(macro.compare(CreateParameteredMacro(sfx)) == 0) return sfx; } } // Special macros with additional "parameter": if (macro.compare(CreateParameteredMacro(sfx_cc, MIDIEvents::MIDICC_start)) >= 0 && macro.compare(CreateParameteredMacro(sfx_cc, MIDIEvents::MIDICC_end)) <= 0 && macro.size() == 5) return sfx_cc; if (macro.compare(CreateParameteredMacro(sfx_plug, 0)) >= 0 && macro.compare(CreateParameteredMacro(sfx_plug, 0x17F)) <= 0 && macro.size() == 7) return sfx_plug; return sfx_custom; // custom / unknown } // Retrieve Zxx (Z80-ZFF) type from current macro configuration fixedMacroType MIDIMacroConfig::GetFixedMacroType() const { // Compare with all possible preset patterns for(uint32 i = 0; i < zxx_max; i++) { fixedMacroType zxx = static_cast(i); if(zxx != zxx_custom) { // Prepare macro pattern to compare char macros[128][MACRO_LENGTH]; CreateFixedMacro(macros, zxx); bool found = true; for(uint32 j = 0; j < 128; j++) { if(strncmp(macros[j], szMidiZXXExt[j], MACRO_LENGTH)) { found = false; break; } } if(found) return zxx; } } return zxx_custom; // Custom setup } void MIDIMacroConfig::CreateParameteredMacro(char (¶meteredMacro)[MACRO_LENGTH], parameteredMacroType macroType, int subType) const { switch(macroType) { case sfx_unused: strcpy(parameteredMacro, ""); break; case sfx_cutoff: strcpy(parameteredMacro, "F0F000z"); break; case sfx_reso: strcpy(parameteredMacro, "F0F001z"); break; case sfx_mode: strcpy(parameteredMacro, "F0F002z"); break; case sfx_drywet: strcpy(parameteredMacro, "F0F003z"); break; case sfx_cc: sprintf(parameteredMacro, "Bc%02Xz", (subType & 0x7F)); break; case sfx_plug: sprintf(parameteredMacro, "F0F%03Xz", std::min(subType, 0x17F) + 0x80); break; case sfx_channelAT: strcpy(parameteredMacro, "Dcz"); break; case sfx_polyAT: strcpy(parameteredMacro, "Acnz"); break; case sfx_pitch: strcpy(parameteredMacro, "Ec00z"); break; case sfx_custom: default: MPT_ASSERT_NOTREACHED(); break; } } // Create Zxx (Z80 - ZFF) from one out of five presets void MIDIMacroConfig::CreateFixedMacro(char (&fixedMacros)[128][MACRO_LENGTH], fixedMacroType macroType) const { for(uint32 i = 0; i < 128; i++) { switch(macroType) { case zxx_unused: strcpy(fixedMacros[i], ""); break; case zxx_reso4Bit: // Type 1 - Z80 - Z8F controls resonance if (i < 16) sprintf(fixedMacros[i], "F0F001%02X", i * 8); else strcpy(fixedMacros[i], ""); break; case zxx_reso7Bit: // Type 2 - Z80 - ZFF controls resonance sprintf(fixedMacros[i], "F0F001%02X", i); break; case zxx_cutoff: // Type 3 - Z80 - ZFF controls cutoff sprintf(fixedMacros[i], "F0F000%02X", i); break; case zxx_mode: // Type 4 - Z80 - ZFF controls filter mode sprintf(fixedMacros[i], "F0F002%02X", i); break; case zxx_resomode: // Type 5 - Z80 - Z9F controls resonance + filter mode if (i < 16) sprintf(fixedMacros[i], "F0F001%02X", i * 8); else if (i < 32) sprintf(fixedMacros[i], "F0F002%02X", (i - 16) * 8); else strcpy(fixedMacros[i], ""); break; case zxx_channelAT: // Type 6 - Z80 - ZFF controls Channel Aftertouch sprintf(fixedMacros[i], "Dc%02X", i); break; case zxx_polyAT: // Type 7 - Z80 - ZFF controls Poly Aftertouch sprintf(fixedMacros[i], "Acn%02X", i); break; case zxx_pitch: // Type 7 - Z80 - ZFF controls Pitch Bend sprintf(fixedMacros[i], "Ec00%02X", i); break; case zxx_custom: default: MPT_ASSERT_NOTREACHED(); break; } } } #ifdef MODPLUG_TRACKER bool MIDIMacroConfig::operator== (const MIDIMacroConfig &other) const { for(uint32 i = 0; i < CountOf(szMidiGlb); i++) { if(strncmp(szMidiGlb[i], other.szMidiGlb[i], MACRO_LENGTH)) return false; } for(uint32 i = 0; i < CountOf(szMidiSFXExt); i++) { if(strncmp(szMidiSFXExt[i], other.szMidiSFXExt[i], MACRO_LENGTH)) return false; } for(uint32 i = 0; i < CountOf(szMidiZXXExt); i++) { if(strncmp(szMidiZXXExt[i], other.szMidiZXXExt[i], MACRO_LENGTH)) return false; } return true; } // Returns macro description including plugin parameter / MIDI CC information CString MIDIMacroConfig::GetParameteredMacroName(uint32 macroIndex, IMixPlugin *plugin) const { const parameteredMacroType macroType = GetParameteredMacroType(macroIndex); switch(macroType) { case sfx_plug: { const int param = MacroToPlugParam(macroIndex); CString formattedName; formattedName.Format(_T("Param %u"), param); #ifndef NO_PLUGINS if(plugin != nullptr) { CString paramName = plugin->GetParamName(param); if(!paramName.IsEmpty()) { formattedName += _T(" (") + paramName + _T(")"); } } else #else MPT_UNREFERENCED_PARAMETER(plugin); #endif // NO_PLUGINS { formattedName += _T(" (N/A)"); } return formattedName; } case sfx_cc: { CString formattedCC; formattedCC.Format(_T("MIDI CC %u"), MacroToMidiCC(macroIndex)); return formattedCC; } default: return GetParameteredMacroName(macroType); } } // Returns generic macro description. CString MIDIMacroConfig::GetParameteredMacroName(parameteredMacroType macroType) const { switch(macroType) { case sfx_unused: return _T("Unused"); case sfx_cutoff: return _T("Set Filter Cutoff"); case sfx_reso: return _T("Set Filter Resonance"); case sfx_mode: return _T("Set Filter Mode"); case sfx_drywet: return _T("Set Plugin Dry/Wet Ratio"); case sfx_plug: return _T("Control Plugin Parameter..."); case sfx_cc: return _T("MIDI CC..."); case sfx_channelAT: return _T("Channel Aftertouch"); case sfx_polyAT: return _T("Polyphonic Aftertouch"); case sfx_pitch: return _T("Pitch Bend"); case sfx_custom: default: return _T("Custom"); } } // Returns generic macro description. CString MIDIMacroConfig::GetFixedMacroName(fixedMacroType macroType) const { switch(macroType) { case zxx_unused: return _T("Unused"); case zxx_reso4Bit: return _T("Z80 - Z8F controls Resonant Filter Resonance"); case zxx_reso7Bit: return _T("Z80 - ZFF controls Resonant Filter Resonance"); case zxx_cutoff: return _T("Z80 - ZFF controls Resonant Filter Cutoff"); case zxx_mode: return _T("Z80 - ZFF controls Resonant Filter Mode"); case zxx_resomode: return _T("Z80 - Z9F controls Resonance + Filter Mode"); case zxx_channelAT: return _T("Z80 - ZFF controls Channel Aftertouch"); case zxx_polyAT: return _T("Z80 - ZFF controls Polyphonic Aftertouch"); case zxx_pitch: return _T("Z80 - ZFF controls Pitch Bend"); case zxx_custom: default: return _T("Custom"); } } int MIDIMacroConfig::MacroToPlugParam(uint32 macroIndex) const { const std::string macro = GetSafeMacro(szMidiSFXExt[macroIndex]); int code = 0; const char *param = macro.c_str(); param += 4; if ((param[0] >= '0') && (param[0] <= '9')) code = (param[0] - '0') << 4; else if ((param[0] >= 'A') && (param[0] <= 'F')) code = (param[0] - 'A' + 0x0A) << 4; if ((param[1] >= '0') && (param[1] <= '9')) code += (param[1] - '0'); else if ((param[1] >= 'A') && (param[1] <= 'F')) code += (param[1] - 'A' + 0x0A); if (macro.size() >= 4 && macro.at(3) == '0') return (code - 128); else return (code + 128); } int MIDIMacroConfig::MacroToMidiCC(uint32 macroIndex) const { const std::string macro = GetSafeMacro(szMidiSFXExt[macroIndex]); int code = 0; const char *param = macro.c_str(); param += 2; if ((param[0] >= '0') && (param[0] <= '9')) code = (param[0] - '0') << 4; else if ((param[0] >= 'A') && (param[0] <= 'F')) code = (param[0] - 'A' + 0x0A) << 4; if ((param[1] >= '0') && (param[1] <= '9')) code += (param[1] - '0'); else if ((param[1] >= 'A') && (param[1] <= 'F')) code += (param[1] - 'A' + 0x0A); return code; } int MIDIMacroConfig::FindMacroForParam(PlugParamIndex param) const { for(int macroIndex = 0; macroIndex < NUM_MACROS; macroIndex++) { if(GetParameteredMacroType(macroIndex) == sfx_plug && MacroToPlugParam(macroIndex) == param) { return macroIndex; } } return -1; } #endif // MODPLUG_TRACKER // Check if the MIDI Macro configuration used is the default one, // i.e. the configuration that is assumed when loading a file that has no macros embedded. bool MIDIMacroConfig::IsMacroDefaultSetupUsed() const { const MIDIMacroConfig defaultConfig; // TODO - Global macros (currently not checked because they are not editable) // SF0: Z00-Z7F controls cutoff, all other parametered macros are unused for(uint32 i = 0; i < NUM_MACROS; i++) { if(GetParameteredMacroType(i) != defaultConfig.GetParameteredMacroType(i)) { return false; } } // Z80-Z8F controls resonance if(GetFixedMacroType() != defaultConfig.GetFixedMacroType()) { return false; } return true; } // Reset MIDI macro config to default values. void MIDIMacroConfig::Reset() { MemsetZero(szMidiGlb); MemsetZero(szMidiSFXExt); MemsetZero(szMidiZXXExt); strcpy(szMidiGlb[MIDIOUT_START], "FF"); strcpy(szMidiGlb[MIDIOUT_STOP], "FC"); strcpy(szMidiGlb[MIDIOUT_NOTEON], "9c n v"); strcpy(szMidiGlb[MIDIOUT_NOTEOFF], "9c n 0"); strcpy(szMidiGlb[MIDIOUT_PROGRAM], "Cc p"); // SF0: Z00-Z7F controls cutoff CreateParameteredMacro(0, sfx_cutoff); // Z80-Z8F controls resonance CreateFixedMacro(zxx_reso4Bit); } // Clear all Zxx macros so that they do nothing. void MIDIMacroConfig::ClearZxxMacros() { MemsetZero(szMidiSFXExt); MemsetZero(szMidiZXXExt); } // Sanitize all macro config strings. void MIDIMacroConfig::Sanitize() { for(uint32 i = 0; i < CountOf(szMidiGlb); i++) { mpt::String::FixNullString(szMidiGlb[i]); } for(uint32 i = 0; i < CountOf(szMidiSFXExt); i++) { mpt::String::FixNullString(szMidiSFXExt[i]); } for(uint32 i = 0; i < CountOf(szMidiZXXExt); i++) { mpt::String::FixNullString(szMidiZXXExt[i]); } } // Helper function for UpgradeMacros() void MIDIMacroConfig::UpgradeMacroString(char *macro) const { for(uint32 i = 0; i < MACRO_LENGTH; i++) { if(macro[i] >= 'a' && macro[i] <= 'f') // both A-F and a-f were treated as hex constants { macro[i] = macro[i] - 'a' + 'A'; } else if(macro[i] == 'K' || macro[i] == 'k') // channel was K or k { macro[i] = 'c'; } else if(macro[i] == 'X' || macro[i] == 'x' || macro[i] == 'Y' || macro[i] == 'y') // those were pointless { macro[i] = 'z'; } } } // Fix old-format (not conforming to IT's MIDI macro definitions) MIDI config strings. void MIDIMacroConfig::UpgradeMacros() { for(uint32 i = 0; i < CountOf(szMidiSFXExt); i++) { UpgradeMacroString(szMidiSFXExt[i]); } for(uint32 i = 0; i < CountOf(szMidiZXXExt); i++) { UpgradeMacroString(szMidiZXXExt[i]); } } // Normalize by removing blanks and other unwanted characters from macro strings for internal usage. std::string MIDIMacroConfig::GetSafeMacro(const char *macro) const { std::string sanitizedMacro = macro; std::string::size_type pos; while((pos = sanitizedMacro.find_first_not_of("0123456789ABCDEFabpcnuvxyz")) != std::string::npos) { sanitizedMacro.erase(pos, 1); } return sanitizedMacro; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/SoundFilePlayConfig.cpp0000644000372100037210000000751113161656666022471 00000000000000/* * SoundFilePlayConfig.cpp * ----------------------- * Purpose: Configuration of sound levels, pan laws, etc... for various mix configurations. * Notes : (currently none) * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Mixer.h" #include "SoundFilePlayConfig.h" OPENMPT_NAMESPACE_BEGIN CSoundFilePlayConfig::CSoundFilePlayConfig() { setVSTiVolume(1.0f); } CSoundFilePlayConfig::~CSoundFilePlayConfig() { } void CSoundFilePlayConfig::SetMixLevels(MixLevels mixLevelType) { switch (mixLevelType) { // Olivier's version gives us floats in [-0.5; 0.5] and slightly saturates VSTis. case mixLevelsOriginal: setVSTiAttenuation(NO_ATTENUATION); setIntToFloat(1.0f/static_cast(1<<28)); setFloatToInt(static_cast(1<<28)); setGlobalVolumeAppliesToMaster(false); setUseGlobalPreAmp(true); setForcePanningMode(dontForcePanningMode); setDisplayDBValues(false); setNormalSamplePreAmp(256.0); setNormalVSTiVol(100.0); setNormalGlobalVol(128.0); setExtraSampleAttenuation(MIXING_ATTENUATION); break; // Ericus' version gives us floats in [-0.06;0.06] and requires attenuation to // avoid massive VSTi saturation. case mixLevels1_17RC1: setVSTiAttenuation(32.0f); setIntToFloat(1.0f/static_cast(0x07FFFFFFF)); setFloatToInt(static_cast(0x07FFFFFFF)); setGlobalVolumeAppliesToMaster(false); setUseGlobalPreAmp(true); setForcePanningMode(dontForcePanningMode); setDisplayDBValues(false); setNormalSamplePreAmp(256.0); setNormalVSTiVol(100.0); setNormalGlobalVol(128.0); setExtraSampleAttenuation(MIXING_ATTENUATION); break; // 117RC2 gives us floats in [-1.0; 1.0] and hopefully plays VSTis at // the right volume... but we attenuate by 2x to approx. match sample volume. case mixLevels1_17RC2: setVSTiAttenuation(2.0f); setIntToFloat(1.0f/MIXING_SCALEF); setFloatToInt(MIXING_SCALEF); setGlobalVolumeAppliesToMaster(true); setUseGlobalPreAmp(true); setForcePanningMode(dontForcePanningMode); setDisplayDBValues(false); setNormalSamplePreAmp(256.0); setNormalVSTiVol(100.0); setNormalGlobalVol(128.0); setExtraSampleAttenuation(MIXING_ATTENUATION); break; // 117RC3 ignores the horrible global, system-specific pre-amp, // treats panning as balance to avoid saturation on loud sample (and because I think it's better :), // and allows display of attenuation in decibels. default: case mixLevels1_17RC3: setVSTiAttenuation(1.0f); setIntToFloat(1.0f/MIXING_SCALEF); setFloatToInt(MIXING_SCALEF); setGlobalVolumeAppliesToMaster(true); setUseGlobalPreAmp(false); setForcePanningMode(forceSoftPanning); setDisplayDBValues(true); setNormalSamplePreAmp(128.0); setNormalVSTiVol(128.0); setNormalGlobalVol(256.0); setExtraSampleAttenuation(0); break; // A mixmode that is intended to be compatible to legacy trackers (IT/FT2/etc). // This is basically derived from mixmode 1.17 RC3, with panning mode and volume levels changed. // Sample attenuation is the same as in Schism Tracker (more attenuation than with RC3, thus VSTi attenuation is also higher). case mixLevelsCompatible: case mixLevelsCompatibleFT2: setVSTiAttenuation(0.75f); setIntToFloat(1.0f/MIXING_SCALEF); setFloatToInt(MIXING_SCALEF); setGlobalVolumeAppliesToMaster(true); setUseGlobalPreAmp(false); setForcePanningMode(mixLevelType == mixLevelsCompatible ? forceNoSoftPanning : forceFT2Panning); setDisplayDBValues(true); setNormalSamplePreAmp(mixLevelType == mixLevelsCompatible ? 256.0 : 192.0); setNormalVSTiVol(mixLevelType == mixLevelsCompatible ? 256.0 : 192.0); setNormalGlobalVol(256.0); setExtraSampleAttenuation(1); break; } return; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Message.cpp0000644000372100037210000001367513161656666020221 00000000000000/* * Message.cpp * ----------- * Purpose: Various functions for processing song messages (allocating, reading from file...) * Notes : Those functions should offer a rather high level of abstraction compared to * previous ways of reading the song messages. There are still many things to do, * though. Future versions of ReadMessage() could e.g. offer charset conversion * and the code is not yet ready for unicode. * Some functions for preparing the message text to be written to a file would * also be handy. * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Message.h" #include "../common/FileReader.h" OPENMPT_NAMESPACE_BEGIN // Read song message from a mapped file. // [in] data: pointer to the data in memory that is going to be read // [in] length: number of characters that should be read, not including a possible trailing null terminator (it is automatically appended). // [in] lineEnding: line ending formatting of the text in memory. // [out] returns true on success. bool SongMessage::Read(const mpt::byte *data, size_t length, LineEnding lineEnding) { const char *str = mpt::byte_cast(data); while(length != 0 && str[length - 1] == '\0') { // Ignore trailing null character. length--; } // Simple line-ending detection algorithm. VERY simple. if(lineEnding == leAutodetect) { char cprev = 0; size_t nCR = 0, nLF = 0, nCRLF = 0; // find CRs, LFs and CRLFs for(size_t i = 0; i < length; i++) { char c = str[i]; if(c == '\r') nCR++; else if(c == '\n') nLF++; if(i && cprev == '\r' && c == '\n') nCRLF++; cprev = c; } // evaluate findings if(nCR == nLF && nCR == nCRLF) lineEnding = leCRLF; else if(nCR && !nLF) lineEnding = leCR; else if(!nCR && nLF) lineEnding = leLF; else lineEnding = leMixed; } size_t finalLength = 0; // calculate the final amount of characters to be allocated. for(size_t i = 0; i < length; i++) { char c = str[i]; if(c != '\n' || lineEnding != leCRLF) finalLength++; } resize(finalLength); size_t cpos = 0; for(size_t i = 0; i < length; i++, cpos++) { char c = str[i]; switch(c) { case '\r': if(lineEnding != leLF) at(cpos) = InternalLineEnding; else at(cpos) = ' '; if(lineEnding == leCRLF) i++; // skip the LF break; case '\n': if(lineEnding != leCR && lineEnding != leCRLF) at(cpos) = InternalLineEnding; else at(cpos) = ' '; break; case '\0': at(cpos) = ' '; break; default: at(cpos) = c; break; } } return true; } bool SongMessage::Read(FileReader &file, const size_t length, LineEnding lineEnding) { FileReader::off_t readLength = std::min(static_cast(length), file.BytesLeft()); FileReader::PinnedRawDataView fileView = file.ReadPinnedRawDataView(readLength); bool success = Read(fileView.data(), fileView.size(), lineEnding); return success; } // Read comments with fixed line length from a mapped file. // [in] data: pointer to the data in memory that is going to be read // [in] length: number of characters that should be read, not including a possible trailing null terminator (it is automatically appended). // [in] lineLength: The fixed length of a line. // [in] lineEndingLength: The padding space between two fixed lines. (there could for example be a null char after every line) // [out] returns true on success. bool SongMessage::ReadFixedLineLength(const mpt::byte *data, const size_t length, const size_t lineLength, const size_t lineEndingLength) { if(lineLength == 0) return false; clear(); reserve(length); size_t readPos = 0, writePos = 0; while(readPos < length) { size_t thisLineLength = std::min(lineLength, length - readPos); append(mpt::byte_cast(data) + readPos, thisLineLength); append(1, InternalLineEnding); // Fix weird chars for(size_t pos = writePos; pos < writePos + thisLineLength; pos++) { switch(at(pos)) { case '\0': case '\n': case '\r': at(pos) = ' '; break; } } readPos += thisLineLength + std::min(lineEndingLength, length - readPos - thisLineLength); writePos += thisLineLength + 1; } return true; } bool SongMessage::ReadFixedLineLength(FileReader &file, const size_t length, const size_t lineLength, const size_t lineEndingLength) { FileReader::off_t readLength = std::min(static_cast(length), file.BytesLeft()); FileReader::PinnedRawDataView fileView = file.ReadPinnedRawDataView(readLength); bool success = ReadFixedLineLength(fileView.data(), fileView.size(), lineLength, lineEndingLength); return success; } // Retrieve song message. // [in] lineEnding: line ending formatting of the text in memory. // [out] returns formatted song message. std::string SongMessage::GetFormatted(const LineEnding lineEnding) const { std::string comments; comments.reserve(length()); for(auto c : *this) { if(c == InternalLineEnding) { switch(lineEnding) { case leCR: comments.push_back('\r'); break; case leCRLF: comments.push_back('\r'); comments.push_back('\n'); break; case leLF: comments.push_back('\n'); break; default: comments.push_back('\r'); break; } } else { comments.push_back(c); } } return comments; } bool SongMessage::SetFormatted(std::string message, LineEnding lineEnding) { MPT_ASSERT(lineEnding == leLF || lineEnding == leCR || lineEnding == leCRLF); switch (lineEnding) { case leLF: message = mpt::String::Replace(message, "\n", std::string(1, InternalLineEnding)); break; case leCR: message = mpt::String::Replace(message, "\r", std::string(1, InternalLineEnding)); break; case leCRLF: message = mpt::String::Replace(message, "\r\n", std::string(1, InternalLineEnding)); break; default: MPT_ASSERT_NOTREACHED(); break; } if(message == *this) { return false; } assign(message); return true; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/ModChannel.cpp0000644000372100037210000000612713161656666020637 00000000000000/* * ModChannel.cpp * -------------- * Purpose: Module Channel header class and helpers * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Sndfile.h" #include "ModChannel.h" OPENMPT_NAMESPACE_BEGIN void ModChannel::Reset(ResetFlags resetMask, const CSoundFile &sndFile, CHANNELINDEX sourceChannel) { if(resetMask & resetSetPosBasic) { nNote = nNewNote = NOTE_NONE; nNewIns = nOldIns = 0; pModSample = nullptr; pModInstrument = nullptr; nPortamentoDest = 0; nCommand = CMD_NONE; nPatternLoopCount = 0; nPatternLoop = 0; nFadeOutVol = 0; dwFlags.set(CHN_KEYOFF | CHN_NOTEFADE); dwOldFlags.reset(); //IT compatibility 15. Retrigger if(sndFile.m_playBehaviour[kITRetrigger]) { nRetrigParam = 1; nRetrigCount = 0; } nTremorCount = 0; nEFxSpeed = 0; proTrackerOffset = 0; lastZxxParam = 0xFF; isFirstTick = false; } if(resetMask & resetSetPosAdvanced) { nPeriod = 0; position.Set(0); nLength = 0; nLoopStart = 0; nLoopEnd = 0; nROfs = nLOfs = 0; pModSample = nullptr; pModInstrument = nullptr; nCutOff = 0x7F; nResonance = 0; nFilterMode = 0; rightVol = leftVol = 0; newRightVol = newLeftVol = 0; rightRamp = leftRamp = 0; nVolume = 0; // Needs to be 0 for SMP_NODEFAULTVOLUME flag nVibratoPos = nTremoloPos = nPanbrelloPos = 0; nOldHiOffset = 0; nLeftVU = nRightVU = 0; //-->Custom tuning related m_ReCalculateFreqOnFirstTick = false; m_CalculateFreq = false; m_PortamentoFineSteps = 0; m_PortamentoTickSlide = 0; m_Freq = 0; //<--Custom tuning related. } if(resetMask & resetChannelSettings) { if(sourceChannel < MAX_BASECHANNELS) { dwFlags = sndFile.ChnSettings[sourceChannel].dwFlags; nPan = sndFile.ChnSettings[sourceChannel].nPan; nGlobalVol = sndFile.ChnSettings[sourceChannel].nVolume; } else { dwFlags.reset(); nPan = 128; nGlobalVol = 64; } nRestorePanOnNewNote = 0; nRestoreCutoffOnNewNote = 0; nRestoreResonanceOnNewNote = 0; } } void ModChannel::Stop() { nPeriod = 0; increment.Set(0); position.Set(0); nLeftVU = nRightVU = 0; nVolume = 0; pCurrentSample = nullptr; } void ModChannel::UpdateInstrumentVolume(const ModSample *smp, const ModInstrument *ins) { nInsVol = 64; if(smp != nullptr) nInsVol = smp->nGlobalVol; if(ins != nullptr) nInsVol = (nInsVol * ins->nGlobalVol) / 64; } ModCommand::NOTE ModChannel::GetPluginNote(bool realNoteMapping) const { if(nArpeggioLastNote != NOTE_NONE) { // If an arpeggio is playing, this definitely the last playing note, which may be different from the arpeggio base note stored in nNote. return nArpeggioLastNote; } ModCommand::NOTE plugNote = nNote; // Caution: When in compatible mode, ModChannel::nNote stores the "real" note, not the mapped note! if(realNoteMapping && pModInstrument != nullptr && plugNote >= NOTE_MIN && plugNote < (MPT_ARRAY_COUNT(pModInstrument->NoteMap) + NOTE_MIN)) { plugNote = pModInstrument->NoteMap[plugNote - NOTE_MIN]; } return plugNote; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Container.h0000644000372100037210000000203213112730415020162 00000000000000/* * Container.h * ----------- * Purpose: General interface for MDO container and/or packers. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "../common/FileReader.h" #include OPENMPT_NAMESPACE_BEGIN struct ContainerItem { mpt::ustring name; FileReader file; std::unique_ptr > data_cache; // may be empty }; enum ContainerLoadingFlags { ContainerOnlyVerifyHeader = 0x00, ContainerUnwrapData = 0x01, }; bool UnpackXPK(std::vector &containerItems, FileReader &file, ContainerLoadingFlags loadFlags); bool UnpackPP20(std::vector &containerItems, FileReader &file, ContainerLoadingFlags loadFlags); bool UnpackMMCMP(std::vector &containerItems, FileReader &file, ContainerLoadingFlags loadFlags); bool UnpackUMX(std::vector &containerItems, FileReader &file, ContainerLoadingFlags loadFlags); OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/MIDIMacros.h0000644000372100037210000001156413161656666020164 00000000000000/* * MIDIMacros.h * ------------ * Purpose: Helper functions / classes for MIDI Macro functionality. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once enum { NUM_MACROS = 16, // number of parametered macros MACRO_LENGTH = 32, // max number of chars per macro }; #ifdef MODPLUG_TRACKER #include "plugins/PluginStructs.h" #endif // MODPLUG_TRACKER OPENMPT_NAMESPACE_BEGIN // Parametered macro presets enum parameteredMacroType { sfx_unused = 0, sfx_cutoff, // Type 1 - Z00 - Z7F controls resonant filter cutoff sfx_reso, // Type 2 - Z00 - Z7F controls resonant filter resonance sfx_mode, // Type 3 - Z00 - Z7F controls resonant filter mode (lowpass / highpass) sfx_drywet, // Type 4 - Z00 - Z7F controls plugin Dry / Wet ratio sfx_plug, // Type 5 - Z00 - Z7F controls a plugin parameter sfx_cc, // Type 6 - Z00 - Z7F controls MIDI CC sfx_channelAT, // Type 7 - Z00 - Z7F controls Channel Aftertouch sfx_polyAT, // Type 8 - Z00 - Z7F controls Poly Aftertouch sfx_pitch, // Type 9 - Z00 - Z7F controls Pitch Bend sfx_custom, sfx_max }; // Fixed macro presets enum fixedMacroType { zxx_unused = 0, zxx_reso4Bit, // Type 1 - Z80 - Z8F controls resonant filter resonance zxx_reso7Bit, // Type 2 - Z80 - ZFF controls resonant filter resonance zxx_cutoff, // Type 3 - Z80 - ZFF controls resonant filter cutoff zxx_mode, // Type 4 - Z80 - ZFF controls resonant filter mode (lowpass / highpass) zxx_resomode, // Type 5 - Z80 - Z9F controls resonance + filter mode zxx_channelAT, // Type 6 - Z80 - ZFF controls Channel Aftertouch zxx_polyAT, // Type 7 - Z80 - ZFF controls Poly Aftertouch zxx_pitch, // Type 8 - Z80 - ZFF controls Pitch Bend zxx_custom, zxx_max }; // Global macro types enum { MIDIOUT_START = 0, MIDIOUT_STOP, MIDIOUT_TICK, MIDIOUT_NOTEON, MIDIOUT_NOTEOFF, MIDIOUT_VOLUME, MIDIOUT_PAN, MIDIOUT_BANKSEL, MIDIOUT_PROGRAM, }; struct MIDIMacroConfigData { // encoding is ASCII char szMidiGlb[9][MACRO_LENGTH]; // Global MIDI macros char szMidiSFXExt[16][MACRO_LENGTH]; // Parametric MIDI macros char szMidiZXXExt[128][MACRO_LENGTH]; // Fixed MIDI macros }; MPT_BINARY_STRUCT(MIDIMacroConfigData, 4896) // this is directly written to files, so the size must be correct! class MIDIMacroConfig : public MIDIMacroConfigData { public: MIDIMacroConfig() { Reset(); }; // Get macro type from a macro string parameteredMacroType GetParameteredMacroType(uint32 macroIndex) const; fixedMacroType GetFixedMacroType() const; // Create a new macro protected: void CreateParameteredMacro(char (¶meteredMacro)[MACRO_LENGTH], parameteredMacroType macroType, int subType) const; public: void CreateParameteredMacro(uint32 macroIndex, parameteredMacroType macroType, int subType = 0) { CreateParameteredMacro(szMidiSFXExt[macroIndex], macroType, subType); }; std::string CreateParameteredMacro(parameteredMacroType macroType, int subType = 0) const { char parameteredMacro[MACRO_LENGTH]; CreateParameteredMacro(parameteredMacro, macroType, subType); return std::string(parameteredMacro); }; protected: void CreateFixedMacro(char (&fixedMacros)[128][MACRO_LENGTH], fixedMacroType macroType) const; public: void CreateFixedMacro(fixedMacroType macroType) { CreateFixedMacro(szMidiZXXExt, macroType); }; #ifdef MODPLUG_TRACKER bool operator== (const MIDIMacroConfig &other) const; bool operator!= (const MIDIMacroConfig &other) const { return !(*this == other); } // Translate macro type or macro string to macro name CString GetParameteredMacroName(uint32 macroIndex, IMixPlugin *plugin = nullptr) const; CString GetParameteredMacroName(parameteredMacroType macroType) const; CString GetFixedMacroName(fixedMacroType macroType) const; // Extract information from a parametered macro string. int MacroToPlugParam(uint32 macroIndex) const; int MacroToMidiCC(uint32 macroIndex) const; // Check if any macro can automate a given plugin parameter int FindMacroForParam(PlugParamIndex param) const; #endif // MODPLUG_TRACKER // Check if a given set of macros is the default IT macro set. bool IsMacroDefaultSetupUsed() const; // Reset MIDI macro config to default values. void Reset(); // Clear all Zxx macros so that they do nothing. void ClearZxxMacros(); // Sanitize all macro config strings. void Sanitize(); // Fix old-format (not conforming to IT's MIDI macro definitions) MIDI config strings. void UpgradeMacros(); protected: // Helper function for FixMacroFormat() void UpgradeMacroString(char *macro) const; // Remove blanks and other unwanted characters from macro strings for internal usage. std::string GetSafeMacro(const char *macro) const; }; STATIC_ASSERT(sizeof(MIDIMacroConfig) == sizeof(MIDIMacroConfigData)); // this is directly written to files, so the size must be correct! OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Load_digi.cpp0000644000372100037210000001227213161656666020500 00000000000000/* * Load_digi.cpp * ------------- * Purpose: Digi Booster module loader * Notes : Basically these are like ProTracker MODs with a few extra features such as more channels, longer samples and a few more effects. * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" OPENMPT_NAMESPACE_BEGIN // DIGI File Header struct DIGIFileHeader { char signature[20]; char versionStr[4]; // Supposed to be "V1.6" or similar, but other values like "TAP!" have been found as well. uint8be versionInt; // e.g. 0x16 = 1.6 uint8be numChannels; uint8be packEnable; char unknown[19]; uint8be lastPatIndex; uint8be lastOrdIndex; uint8be orders[128]; uint32be smpLength[31]; uint32be smpLoopStart[31]; uint32be smpLoopLength[31]; uint8be smpVolume[31]; uint8be smpFinetune[31]; }; MPT_BINARY_STRUCT(DIGIFileHeader, 610) static void ReadDIGIPatternEntry(FileReader &file, ModCommand &m) { CSoundFile::ReadMODPatternEntry(file, m); CSoundFile::ConvertModCommand(m); if(m.command == CMD_MODCMDEX) { switch(m.param & 0xF0) { case 0x30: // E30 / E31: Play sample backwards (with some weird parameters that we won't support for now) if(m.param <= 0x31) { m.command = CMD_S3MCMDEX; m.param = 0x9F; } break; case 0x40: // E40: Stop playing sample if(m.param == 0x40) { m.note = NOTE_NOTECUT; m.command = CMD_NONE; } break; case 0x80: // E8x: High sample offset m.command = CMD_S3MCMDEX; m.param = 0xA0 | (m.param & 0x0F); } } else if(m.command == CMD_PANNING8) { // 8xx "Robot" effect (not supported) m.command = CMD_NONE; } } static bool ValidateHeader(const DIGIFileHeader &fileHeader) { if(std::memcmp(fileHeader.signature, "DIGI Booster module\0", 20) || !fileHeader.numChannels || fileHeader.numChannels > 8 || fileHeader.lastOrdIndex > 127) { return false; } return true; } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderDIGI(MemoryFileReader file, const uint64 *pfilesize) { DIGIFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return ProbeWantMoreData; } if(!ValidateHeader(fileHeader)) { return ProbeFailure; } MPT_UNREFERENCED_PARAMETER(pfilesize); return ProbeSuccess; } bool CSoundFile::ReadDIGI(FileReader &file, ModLoadingFlags loadFlags) { file.Rewind(); DIGIFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return false; } if(!ValidateHeader(fileHeader)) { return false; } if(loadFlags == onlyVerifyHeader) { return true; } // Globals InitializeGlobals(MOD_TYPE_DIGI); InitializeChannels(); m_nChannels = fileHeader.numChannels; m_nSamples = 31; m_nSamplePreAmp = 256 / m_nChannels; m_madeWithTracker = mpt::format(MPT_USTRING("Digi Booster %1.%2"))(fileHeader.versionInt >> 4, fileHeader.versionInt & 0x0F); ReadOrderFromArray(Order(), fileHeader.orders, fileHeader.lastOrdIndex + 1); // Read sample headers for(SAMPLEINDEX smp = 0; smp < 31; smp++) { ModSample &sample = Samples[smp + 1]; sample.Initialize(MOD_TYPE_MOD); sample.nLength = fileHeader.smpLength[smp]; sample.nLoopStart = fileHeader.smpLoopStart[smp]; sample.nLoopEnd = sample.nLoopStart + fileHeader.smpLoopLength[smp]; if(fileHeader.smpLoopLength[smp]) { sample.uFlags.set(CHN_LOOP); } sample.SanitizeLoops(); sample.nVolume = std::min(fileHeader.smpVolume[smp], 64) * 4; sample.nFineTune = MOD2XMFineTune(fileHeader.smpFinetune[smp]); } // Read song + sample names file.ReadString(m_songName, 32); for(SAMPLEINDEX smp = 1; smp <= 31; smp++) { file.ReadString(m_szNames[smp], 30); } if(loadFlags & loadPatternData) Patterns.ResizeArray(fileHeader.lastPatIndex + 1); for(PATTERNINDEX pat = 0; pat <= fileHeader.lastPatIndex; pat++) { FileReader patternChunk; if(fileHeader.packEnable) { patternChunk = file.ReadChunk(file.ReadUint16BE()); } else { patternChunk = file.ReadChunk(4 * 64 * GetNumChannels()); } if(!(loadFlags & loadPatternData) || !Patterns.Insert(pat, 64)) { continue; } if(fileHeader.packEnable) { uint8 eventMask[64]; patternChunk.ReadArray(eventMask); // Compressed patterns are stored in row-major order... for(ROWINDEX row = 0; row < 64; row++) { PatternRow patRow = Patterns[pat].GetRow(row); uint8 bit = 0x80; for(CHANNELINDEX chn = 0; chn < GetNumChannels(); chn++, bit >>= 1) { if(eventMask[row] & bit) { ModCommand &m = patRow[chn]; ReadDIGIPatternEntry(patternChunk, m); } } } } else { // ...but uncompressed patterns are stored in column-major order. WTF! for(CHANNELINDEX chn = 0; chn < GetNumChannels(); chn++) { for(ROWINDEX row = 0; row < 64; row++) { ReadDIGIPatternEntry(patternChunk, *Patterns[pat].GetpModCommand(row, chn)); } } } } if(loadFlags & loadSampleData) { // Reading Samples const SampleIO sampleIO( SampleIO::_8bit, SampleIO::mono, SampleIO::bigEndian, SampleIO::signedPCM); for(SAMPLEINDEX smp = 1; smp <= 31; smp++) { sampleIO.ReadSample(Samples[smp], file); } } return true; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/AudioReadTarget.h0000644000372100037210000001504613161656666021300 00000000000000/* * AudioReadTarget.h * ----------------- * Purpose: Callback class implementations for audio data read via CSoundFile::Read. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "Sndfile.h" #include "Dither.h" #include "../soundbase/SampleFormat.h" #include "../soundbase/SampleFormatConverters.h" #include "../soundbase/SampleFormatCopy.h" #include "MixerLoops.h" #include "Mixer.h" OPENMPT_NAMESPACE_BEGIN template class AudioReadTargetBuffer : public IAudioReadTarget { private: std::size_t countRendered; Dither &dither; protected: Tsample *outputBuffer; Tsample * const *outputBuffers; public: AudioReadTargetBuffer(Dither &dither_, Tsample *buffer, Tsample * const *buffers) : countRendered(0) , dither(dither_) , outputBuffer(buffer) , outputBuffers(buffers) { MPT_ASSERT(SampleFormat(SampleFormatTraits::sampleFormat).IsValid()); } virtual ~AudioReadTargetBuffer() { } std::size_t GetRenderedCount() const { return countRendered; } public: virtual void DataCallback(int *MixSoundBuffer, std::size_t channels, std::size_t countChunk) { // Convert to output sample format and optionally perform dithering and clipping if needed const SampleFormat sampleFormat = SampleFormatTraits::sampleFormat; if(sampleFormat.IsInt()) { dither.Process(MixSoundBuffer, countChunk, channels, sampleFormat.GetBitsPerSample()); } if(outputBuffer) { ConvertInterleavedFixedPointToInterleaved(outputBuffer + (channels * countRendered), MixSoundBuffer, channels, countChunk); } if(outputBuffers) { Tsample *buffers[4] = { nullptr, nullptr, nullptr, nullptr }; for(std::size_t channel = 0; channel < channels; ++channel) { buffers[channel] = outputBuffers[channel] + countRendered; } ConvertInterleavedFixedPointToNonInterleaved(buffers, MixSoundBuffer, channels, countChunk); } countRendered += countChunk; } }; #if defined(MODPLUG_TRACKER) class AudioReadTargetBufferInterleavedDynamic : public IAudioReadTarget { private: const SampleFormat sampleFormat; bool clipFloat; Dither &dither; void *buffer; public: AudioReadTargetBufferInterleavedDynamic(SampleFormat sampleFormat_, bool clipFloat_, Dither &dither_, void *buffer_) : sampleFormat(sampleFormat_) , clipFloat(clipFloat_) , dither(dither_) , buffer(buffer_) { MPT_ASSERT_ALWAYS(sampleFormat.IsValid()); } virtual void DataCallback(int *MixSoundBuffer, std::size_t channels, std::size_t countChunk) { switch(sampleFormat.value) { case SampleFormatUnsigned8: { typedef SampleFormatToType::type Tsample; AudioReadTargetBuffer target(dither, reinterpret_cast(buffer), nullptr); target.DataCallback(MixSoundBuffer, channels, countChunk); } break; case SampleFormatInt16: { typedef SampleFormatToType::type Tsample; AudioReadTargetBuffer target(dither, reinterpret_cast(buffer), nullptr); target.DataCallback(MixSoundBuffer, channels, countChunk); } break; case SampleFormatInt24: { typedef SampleFormatToType::type Tsample; AudioReadTargetBuffer target(dither, reinterpret_cast(buffer), nullptr); target.DataCallback(MixSoundBuffer, channels, countChunk); } break; case SampleFormatInt32: { typedef SampleFormatToType::type Tsample; AudioReadTargetBuffer target(dither, reinterpret_cast(buffer), nullptr); target.DataCallback(MixSoundBuffer, channels, countChunk); } break; case SampleFormatFloat32: if(clipFloat) { typedef SampleFormatToType::type Tsample; AudioReadTargetBuffer target(dither, reinterpret_cast(buffer), nullptr); target.DataCallback(MixSoundBuffer, channels, countChunk); } else { typedef SampleFormatToType::type Tsample; AudioReadTargetBuffer target(dither, reinterpret_cast(buffer), nullptr); target.DataCallback(MixSoundBuffer, channels, countChunk); } break; } // increment output buffer for potentially next callback buffer = reinterpret_cast(buffer) + (sampleFormat.GetBitsPerSample()/8) * channels * countChunk; } }; #else // !MODPLUG_TRACKER template void ApplyGainBeforeConversionIfAppropriate(int *MixSoundBuffer, std::size_t channels, std::size_t countChunk, float gainFactor) { // Apply final output gain for non floating point output ApplyGain(MixSoundBuffer, channels, countChunk, Util::Round(gainFactor * (1<<16))); } template<> void ApplyGainBeforeConversionIfAppropriate(int * /*MixSoundBuffer*/, std::size_t /*channels*/, std::size_t /*countChunk*/, float /*gainFactor*/) { // nothing } template void ApplyGainAfterConversionIfAppropriate(Tsample * /*buffer*/, Tsample * const * /*buffers*/, std::size_t /*countRendered*/, std::size_t /*channels*/, std::size_t /*countChunk*/, float /*gainFactor*/) { // nothing } template<> void ApplyGainAfterConversionIfAppropriate(float *buffer, float * const *buffers, std::size_t countRendered, std::size_t channels, std::size_t countChunk, float gainFactor) { // Apply final output gain for floating point output after conversion so we do not suffer underflow or clipping ApplyGain(buffer, buffers, countRendered, channels, countChunk, gainFactor); } template class AudioReadTargetGainBuffer : public AudioReadTargetBuffer { private: typedef AudioReadTargetBuffer Tbase; private: const float gainFactor; public: AudioReadTargetGainBuffer(Dither &dither, Tsample *buffer, Tsample * const *buffers, float gainFactor_) : Tbase(dither, buffer, buffers) , gainFactor(gainFactor_) { return; } virtual ~AudioReadTargetGainBuffer() { } public: virtual void DataCallback(int *MixSoundBuffer, std::size_t channels, std::size_t countChunk) { const std::size_t countRendered_ = Tbase::GetRenderedCount(); ApplyGainBeforeConversionIfAppropriate(MixSoundBuffer, channels, countChunk, gainFactor); Tbase::DataCallback(MixSoundBuffer, channels, countChunk); ApplyGainAfterConversionIfAppropriate(Tbase::outputBuffer, Tbase::outputBuffers, countRendered_, channels, countChunk, gainFactor); } }; #endif // MODPLUG_TRACKER OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Load_wav.cpp0000644000372100037210000001241213161656666020355 00000000000000/* * Load_wav.cpp * ------------ * Purpose: WAV importer * Notes : This loader converts each WAV channel into a separate mono sample. * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" #include "WAVTools.h" #include "../soundbase/SampleFormatConverters.h" #include "../soundbase/SampleFormatCopy.h" OPENMPT_NAMESPACE_BEGIN ///////////////////////////////////////////////////////////// // WAV file support template bool CopyWavChannel(ModSample &sample, const FileReader &file, size_t channelIndex, size_t numChannels, SampleConversion conv = SampleConversion()) { MPT_ASSERT(sample.GetNumChannels() == 1); MPT_ASSERT(sample.GetElementarySampleSize() == sizeof(typename SampleConversion::output_t)); const size_t offset = channelIndex * sizeof(typename SampleConversion::input_t) * SampleConversion::input_inc; if(sample.AllocateSample() == 0 || !file.CanRead(offset)) { return false; } const mpt::byte *inBuf = file.GetRawData(); CopySample(reinterpret_cast(sample.pSample), sample.nLength, 1, inBuf + offset, file.BytesLeft() - offset, numChannels, conv); return true; } bool CSoundFile::ReadWav(FileReader &file, ModLoadingFlags loadFlags) { WAVReader wavFile(file); if(!wavFile.IsValid() || wavFile.GetNumChannels() == 0 || wavFile.GetNumChannels() > MAX_BASECHANNELS || wavFile.GetBitsPerSample() == 0 || wavFile.GetBitsPerSample() > 32 || (wavFile.GetSampleFormat() != WAVFormatChunk::fmtPCM && wavFile.GetSampleFormat() != WAVFormatChunk::fmtFloat)) { return false; } else if(loadFlags == onlyVerifyHeader) { return true; } InitializeGlobals(MOD_TYPE_MPT); m_ContainerType = MOD_CONTAINERTYPE_WAV; m_nChannels = std::max(wavFile.GetNumChannels(), uint16(2)); Patterns.ResizeArray(2); if(!Patterns.Insert(0, 64) || !Patterns.Insert(1, 64)) { return false; } const SmpLength sampleLength = wavFile.GetSampleLength(); // Setting up module length // Calculate sample length in ticks at tempo 125 const uint32 sampleRate = std::max(uint32(1), wavFile.GetSampleRate()); const uint32 sampleTicks = mpt::saturate_cast(((sampleLength * 50) / sampleRate) + 1); uint32 ticksPerRow = std::max((sampleTicks + 63u) / 63u, 1u); Order().assign(1, 0); ORDERINDEX numOrders = 1; while(ticksPerRow >= 32 && numOrders < MAX_ORDERS) { numOrders++; ticksPerRow = (sampleTicks + (64 * numOrders - 1)) / (64 * numOrders); } Order().resize(numOrders, 1); m_nSamples = wavFile.GetNumChannels(); m_nInstruments = 0; m_nDefaultSpeed = ticksPerRow; m_nDefaultTempo.Set(125); m_SongFlags = SONG_LINEARSLIDES; for(CHANNELINDEX channel = 0; channel < m_nChannels; channel++) { ChnSettings[channel].Reset(); ChnSettings[channel].nPan = (channel % 2u) ? 256 : 0; } // Setting up pattern PatternRow pattern = Patterns[0].GetRow(0); pattern[0].note = pattern[1].note = NOTE_MIDDLEC; pattern[0].instr = pattern[1].instr = 1; const FileReader sampleChunk = wavFile.GetSampleData(); // Read every channel into its own sample lot. for(SAMPLEINDEX channel = 0; channel < GetNumSamples(); channel++) { pattern[channel].note = pattern[0].note; pattern[channel].instr = static_cast(channel + 1); ModSample &sample = Samples[channel + 1]; sample.Initialize(); sample.uFlags = CHN_PANNING; sample.nLength = sampleLength; sample.nC5Speed = wavFile.GetSampleRate(); strcpy(m_szNames[channel + 1], ""); wavFile.ApplySampleSettings(sample, m_szNames[channel + 1]); if(wavFile.GetNumChannels() > 1) { // Pan all samples appropriately switch(channel) { case 0: sample.nPan = 0; break; case 1: sample.nPan = 256; break; case 2: sample.nPan = (wavFile.GetNumChannels() == 3 ? 128u : 64u); pattern[channel].command = CMD_S3MCMDEX; pattern[channel].param = 0x91; break; case 3: sample.nPan = 192; pattern[channel].command = CMD_S3MCMDEX; pattern[channel].param = 0x91; break; default: sample.nPan = 128; break; } } if(wavFile.GetBitsPerSample() > 8) { sample.uFlags.set(CHN_16BIT); } if(wavFile.GetSampleFormat() == WAVFormatChunk::fmtFloat) { CopyWavChannel, SC::DecodeFloat32 > >(sample, sampleChunk, channel, wavFile.GetNumChannels()); } else { if(wavFile.GetBitsPerSample() <= 8) { CopyWavChannel(sample, sampleChunk, channel, wavFile.GetNumChannels()); } else if(wavFile.GetBitsPerSample() <= 16) { CopyWavChannel >(sample, sampleChunk, channel, wavFile.GetNumChannels()); } else if(wavFile.GetBitsPerSample() <= 24) { CopyWavChannel, SC::DecodeInt24<0, littleEndian24> > >(sample, sampleChunk, channel, wavFile.GetNumChannels()); } else if(wavFile.GetBitsPerSample() <= 32) { CopyWavChannel, SC::DecodeInt32<0, littleEndian32> > >(sample, sampleChunk, channel, wavFile.GetNumChannels()); } } sample.PrecomputeLoops(*this, false); } return true; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/tuningCollection.cpp0000644000372100037210000001532713161656666022151 00000000000000/* * tuningCollection.cpp * -------------------- * Purpose: Alternative sample tuning collection class. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "tuningcollection.h" #include "../common/mptIO.h" #include "../common/serialization_utils.h" #include #include "../common/mptFileIO.h" #include "Loaders.h" OPENMPT_NAMESPACE_BEGIN namespace Tuning { /* Version history: 2->3: Serialization revamp(August 2007) 1->2: Sizetypes of string serialisation from size_t(uint32) to uint8. (March 2007) */ const char CTuningCollection::s_FileExtension[4] = ".tc"; namespace CTuningS11n { void ReadStr(std::istream& iStrm, std::string& str, const size_t); void WriteStr(std::ostream& oStrm, const std::string& str); } // namespace CTuningS11n using namespace CTuningS11n; static void ReadTuning(std::istream& iStrm, CTuningCollection& Tc, const size_t) { Tc.AddTuning(iStrm); } static void WriteTuning(std::ostream& oStrm, const CTuning& t) { t.Serialize(oStrm); } CTuning* CTuningCollection::GetTuning(const std::string& name) { for(std::size_t i = 0; iGetName() == name) { return m_Tunings[i].get(); } } return nullptr; } const CTuning* CTuningCollection::GetTuning(const std::string& name) const { for(std::size_t i = 0; iGetName() == name) { return m_Tunings[i].get(); } } return nullptr; } Tuning::SerializationResult CTuningCollection::Serialize(std::ostream& oStrm, const std::string &name) const { srlztn::SsbWrite ssb(oStrm); ssb.BeginWrite("TC", 3); // version ssb.WriteItem(name, "0", &WriteStr); uint16 dummyEditMask = 0xffff; ssb.WriteItem(dummyEditMask, "1"); const size_t tcount = m_Tunings.size(); for(size_t i = 0; i(inStrm, beginMarker); if(beginMarker != MAGIC4BE('T','C','S','H')) return Tuning::SerializationResult::NoMagic; //2. version int32 version = 0; mpt::IO::ReadIntLE(inStrm, version); if(version > 2 || version < 1) return Tuning::SerializationResult::Failure; //3. Name if(version < 2) { if(!mpt::IO::ReadSizedStringLE(inStrm, name, 256)) return Tuning::SerializationResult::Failure; } else { if(!mpt::IO::ReadSizedStringLE(inStrm, name)) return Tuning::SerializationResult::Failure; } //4. Editmask int16 em = 0; mpt::IO::ReadIntLE(inStrm, em); //Not assigning the value yet, for if it sets some property const, //further loading might fail. //5. Tunings { uint32 s = 0; mpt::IO::ReadIntLE(inStrm, s); if(s > 50) return Tuning::SerializationResult::Failure; for(size_t i = 0; i(inStrm, endMarker); if(endMarker != MAGIC4BE('T','C','S','F')) return Tuning::SerializationResult::Failure; return Tuning::SerializationResult::Success; } bool CTuningCollection::Remove(const CTuning *pT) { const auto it = std::find_if(m_Tunings.begin(), m_Tunings.end(), [&] (const std::unique_ptr & upT) -> bool { return upT.get() == pT; } ); if(it == m_Tunings.end()) { return false; } m_Tunings.erase(it); return true; } bool CTuningCollection::Remove(const std::size_t i) { if(i >= m_Tunings.size()) { return false; } m_Tunings.erase(m_Tunings.begin() + i); return true; } bool CTuningCollection::AddTuning(CTuning *pT) { if(m_Tunings.size() >= s_nMaxTuningCount) return true; if(pT == NULL) return true; m_Tunings.push_back(std::unique_ptr(pT)); return false; } bool CTuningCollection::AddTuning(std::istream& inStrm) { if(m_Tunings.size() >= s_nMaxTuningCount) return true; if(!inStrm.good()) return true; CTuning* pT = CTuning::CreateDeserializeOLD(inStrm); if(pT == 0) pT = CTuning::CreateDeserialize(inStrm); if(pT == 0) return true; else { m_Tunings.push_back(std::unique_ptr(pT)); return false; } } #ifdef MODPLUG_TRACKER bool UnpackTuningCollection(const CTuningCollection &tc, const mpt::PathString &prefix) { bool error = false; auto numberFmt = mpt::FormatSpec().Dec().FillNul().Width(1 + static_cast(std::log10(tc.GetNumTunings()))); for(std::size_t i = 0; i < tc.GetNumTunings(); ++i) { const CTuning & tuning = tc.GetTuning(i); mpt::PathString fn; fn += prefix; mpt::ustring tuningName = mpt::ToUnicode(mpt::CharsetLocale, tuning.GetName()); if(tuningName.empty()) { tuningName = MPT_USTRING("untitled"); } SanitizeFilename(tuningName); fn += mpt::PathString::FromUnicode(mpt::format(MPT_USTRING("%1 - %2"))(numberFmt.ToWString(i + 1), tuningName)); fn += mpt::PathString::FromUTF8(CTuning::s_FileExtension); if(fn.FileOrDirectoryExists()) { error = true; } else { mpt::ofstream fout(fn, std::ios::binary); if(tuning.Serialize(fout) != Tuning::SerializationResult::Success) { error = true; } fout.close(); } } return !error; } #endif } // namespace Tuning OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/ITCompression.h0000644000372100037210000000654713161656666021040 00000000000000/* * ITCompression.h * --------------- * Purpose: Code for IT sample compression and decompression. * Notes : The original Python compression code was written by GreaseMonkey and has been released into the public domain. * Authors: OpenMPT Devs * Ben "GreaseMonkey" Russell * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include #include #include "Snd_defs.h" #include "../common/FileReader.h" OPENMPT_NAMESPACE_BEGIN struct ModSample; class ITCompression { public: ITCompression(const ModSample &sample, bool it215, std::ostream *f, SmpLength maxLength = 0); size_t GetCompressedSize() const { return packedTotalLength; } static const size_t bufferSize = 2 + 0xFFFF; // Our output buffer can't be longer than this. static const size_t blockSize = 0x8000; // Block size (in bytes) in which samples are being processed protected: std::vector bwt; // Bit width table for each sampling point uint8 *packedData; // Compressed data for current sample block std::ostream *file; // File to which compressed data will be written (can be nullptr if you only want to find out the sample size) void *sampleData; // Pre-processed sample data for currently compressed sample block const ModSample &mptSample; // Sample that is being processed size_t packedLength; // Size of currently compressed sample block size_t packedTotalLength; // Size of all compressed data so far SmpLength baseLength; // Length of the currently compressed sample block (in samples) // Bit writer int8 bitPos; // Current bit position in this byte int8 remBits; // Remaining bits in this byte uint8 byteVal; // Current byte value to be written bool is215; // Use IT2.15 compression (double deltas) template static void CopySample(void *target, const void *source, SmpLength offset, SmpLength length, SmpLength skip); template void Deltafy(); template void Compress(const void *data, SmpLength offset, SmpLength actualLength); static int8 GetWidthChangeSize(int8 w, bool is16); template void SquishRecurse(int8 sWidth, int8 lWidth, int8 rWidth, int8 width, SmpLength offset, SmpLength length); static int8 ConvertWidth(int8 curWidth, int8 newWidth); void WriteBits(int8 width, int v); void WriteByte(uint8 v); }; class ITDecompression { public: ITDecompression(FileReader &file, ModSample &sample, bool it215); protected: ModSample &mptSample; // Sample that is being processed SmpLength writtenSamples; // Number of samples so far written on this channel SmpLength writePos; // Absolut write position in sample (for stereo samples) SmpLength curLength; // Length of currently processed block unsigned int mem1, mem2; // Integrator memory int dataPos, dataSize; // Position in and size of input block // Bit reader int bitPos; // Current bit position in this byte int remBits; // Remaining bits in this byte bool is215; // Use IT2.15 compression (double deltas) mpt::byte chunk[65535]; // Input block template void Uncompress(typename Properties::sample_t *target); static void ChangeWidth(int &curWidth, int width); int ReadBits(int width); template void Write(int v, int topbit, typename Properties::sample_t *target); }; OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Load_mid.cpp0000644000372100037210000011124613174430063020317 00000000000000/* * Load_mid.cpp * ------------ * Purpose: MIDI file loader * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" #include "Dlsbank.h" #include "MIDIEvents.h" #ifdef MODPLUG_TRACKER #include "../mptrack/TrackerSettings.h" #include "../mptrack/Moddoc.h" #include "../mptrack/Mptrack.h" #include "../common/mptFileIO.h" #endif // MODPLUG_TRACKER OPENMPT_NAMESPACE_BEGIN #if defined(MODPLUG_TRACKER) || defined(MPT_FUZZ_TRACKER) #ifdef LIBOPENMPT_BUILD struct CDLSBank { static int32 DLSMidiVolumeToLinear(uint32) { return 256; } }; #endif // LIBOPENMPT_BUILD #define MIDI_DRUMCHANNEL 10 const char *szMidiGroupNames[17] = { "Piano", "Chromatic Percussion", "Organ", "Guitar", "Bass", "Strings", "Ensemble", "Brass", "Reed", "Pipe", "Synth Lead", "Synth Pad", "Synth Effects", "Ethnic", "Percussive", "Sound Effects", "Percussions" }; const char *szMidiProgramNames[128] = { // 1-8: Piano "Acoustic Grand Piano", "Bright Acoustic Piano", "Electric Grand Piano", "Honky-tonk Piano", "Electric Piano 1", "Electric Piano 2", "Harpsichord", "Clavi", // 9-16: Chromatic Percussion "Celesta", "Glockenspiel", "Music Box", "Vibraphone", "Marimba", "Xylophone", "Tubular Bells", "Dulcimer", // 17-24: Organ "Drawbar Organ", "Percussive Organ", "Rock Organ", "Church Organ", "Reed Organ", "Accordion", "Harmonica", "Tango Accordion", // 25-32: Guitar "Acoustic Guitar (nylon)", "Acoustic Guitar (steel)", "Electric Guitar (jazz)", "Electric Guitar (clean)", "Electric Guitar (muted)", "Overdriven Guitar", "Distortion Guitar", "Guitar harmonics", // 33-40 Bass "Acoustic Bass", "Electric Bass (finger)", "Electric Bass (pick)", "Fretless Bass", "Slap Bass 1", "Slap Bass 2", "Synth Bass 1", "Synth Bass 2", // 41-48 Strings "Violin", "Viola", "Cello", "Contrabass", "Tremolo Strings", "Pizzicato Strings", "Orchestral Harp", "Timpani", // 49-56 Ensemble "String Ensemble 1", "String Ensemble 2", "SynthStrings 1", "SynthStrings 2", "Choir Aahs", "Voice Oohs", "Synth Voice", "Orchestra Hit", // 57-64 Brass "Trumpet", "Trombone", "Tuba", "Muted Trumpet", "French Horn", "Brass Section", "SynthBrass 1", "SynthBrass 2", // 65-72 Reed "Soprano Sax", "Alto Sax", "Tenor Sax", "Baritone Sax", "Oboe", "English Horn", "Bassoon", "Clarinet", // 73-80 Pipe "Piccolo", "Flute", "Recorder", "Pan Flute", "Blown Bottle", "Shakuhachi", "Whistle", "Ocarina", // 81-88 Synth Lead "Lead 1 (square)", "Lead 2 (sawtooth)", "Lead 3 (calliope)", "Lead 4 (chiff)", "Lead 5 (charang)", "Lead 6 (voice)", "Lead 7 (fifths)", "Lead 8 (bass + lead)", // 89-96 Synth Pad "Pad 1 (new age)", "Pad 2 (warm)", "Pad 3 (polysynth)", "Pad 4 (choir)", "Pad 5 (bowed)", "Pad 6 (metallic)", "Pad 7 (halo)", "Pad 8 (sweep)", // 97-104 Synth Effects "FX 1 (rain)", "FX 2 (soundtrack)", "FX 3 (crystal)", "FX 4 (atmosphere)", "FX 5 (brightness)", "FX 6 (goblins)", "FX 7 (echoes)", "FX 8 (sci-fi)", // 105-112 Ethnic "Sitar", "Banjo", "Shamisen", "Koto", "Kalimba", "Bag pipe", "Fiddle", "Shanai", // 113-120 Percussive "Tinkle Bell", "Agogo", "Steel Drums", "Woodblock", "Taiko Drum", "Melodic Tom", "Synth Drum", "Reverse Cymbal", // 121-128 Sound Effects "Guitar Fret Noise", "Breath Noise", "Seashore", "Bird Tweet", "Telephone Ring", "Helicopter", "Applause", "Gunshot" }; // Notes 25-85 const char *szMidiPercussionNames[61] = { "Seq Click", "Brush Tap", "Brush Swirl", "Brush Slap", "Brush Swirl W/Attack", "Snare Roll", "Castanet", "Snare Lo", "Sticks", "Bass Drum Lo", "Open Rim Shot", "Acoustic Bass Drum", "Bass Drum 1", "Side Stick", "Acoustic Snare", "Hand Clap", "Electric Snare", "Low Floor Tom", "Closed Hi-Hat", "High Floor Tom", "Pedal Hi-Hat", "Low Tom", "Open Hi-Hat", "Low-Mid Tom", "Hi Mid Tom", "Crash Cymbal 1", "High Tom", "Ride Cymbal 1", "Chinese Cymbal", "Ride Bell", "Tambourine", "Splash Cymbal", "Cowbell", "Crash Cymbal 2", "Vibraslap", "Ride Cymbal 2", "Hi Bongo", "Low Bongo", "Mute Hi Conga", "Open Hi Conga", "Low Conga", "High Timbale", "Low Timbale", "High Agogo", "Low Agogo", "Cabasa", "Maracas", "Short Whistle", "Long Whistle", "Short Guiro", "Long Guiro", "Claves", "Hi Wood Block", "Low Wood Block", "Mute Cuica", "Open Cuica", "Mute Triangle", "Open Triangle", "Shaker", "Jingle Bell", "Bell Tree", }; //////////////////////////////////////////////////////////////////////////////// // Maps a midi instrument - returns the instrument number in the file uint32 CSoundFile::MapMidiInstrument(uint8 program, uint16 bank, uint8 midiChannel, uint8 note, bool isXG, std::bitset<16> drumChns) { ModInstrument *pIns; program &= 0x7F; bank &= 0x3FFF; note &= 0x7F; // In XG mode, extra drums are on banks with MSB 7F const bool isDrum = drumChns[midiChannel - 1] || (bank >= 0x3F80 && isXG); for (uint32 i = 1; i <= m_nInstruments; i++) if (Instruments[i]) { ModInstrument *p = Instruments[i]; // Drum Kit? if (isDrum) { if (note == p->nMidiDrumKey && bank + 1 == p->wMidiBank) return i; } else // Melodic Instrument { if (program + 1 == p->nMidiProgram && bank + 1 == p->wMidiBank && p->nMidiDrumKey == 0) return i; } } if ((m_nInstruments + 1 >= MAX_INSTRUMENTS) || (m_nSamples + 1 >= MAX_SAMPLES)) return 0; pIns = AllocateInstrument(m_nInstruments + 1); if(pIns == nullptr) { return 0; } m_nSamples++; pIns->wMidiBank = bank + 1; pIns->nMidiProgram = program + 1; pIns->nFadeOut = 1024; pIns->nNNA = NNA_NOTEOFF; pIns->nDCT = isDrum ? DCT_SAMPLE : DCT_NOTE; pIns->nDNA = DNA_NOTEFADE; if(isDrum) { pIns->nMidiChannel = MIDI_DRUMCHANNEL; pIns->nMidiDrumKey = note; for(auto &key : pIns->NoteMap) { key = NOTE_MIDDLEC; } } pIns->VolEnv.dwFlags.set(ENV_ENABLED); if (!isDrum) pIns->VolEnv.dwFlags.set(ENV_SUSTAIN); pIns->VolEnv.reserve(4); pIns->VolEnv.push_back(EnvelopeNode(0, ENVELOPE_MAX)); pIns->VolEnv.push_back(EnvelopeNode(10, ENVELOPE_MAX)); pIns->VolEnv.push_back(EnvelopeNode(15, (ENVELOPE_MAX + ENVELOPE_MID) / 2)); pIns->VolEnv.push_back(EnvelopeNode(20, ENVELOPE_MIN)); pIns->VolEnv.nSustainStart = pIns->VolEnv.nSustainEnd = 1; // Set GM program / drum name if (!isDrum) { strcpy(pIns->name, szMidiProgramNames[program]); } else { if (note >= 24 && note <= 84) strcpy(pIns->name, szMidiPercussionNames[note - 24]); else strcpy(pIns->name, "Percussions"); } return m_nInstruments; } struct MThd { uint32be headerLength; uint16be format; // 0 = single-track, 1 = multi-track, 2 = multi-song uint16be numTracks; // Number of track chunks uint16be division; // Delta timing value: positive = units/beat; negative = smpte compatible units }; MPT_BINARY_STRUCT(MThd, 10); typedef uint32 tick_t; struct TrackState { FileReader track; tick_t nextEvent; uint8 command; bool finished; TrackState() : nextEvent(0) , command(0) , finished(false) { } }; struct ModChannelState { static const uint8 NOMIDI = 0xFF; // No MIDI channel assigned. tick_t age; // At which MIDI tick the channel was triggered int32 porta; // Current portamento position in extra-fine slide units (1/64th of a semitone) uint8 vol; // MIDI note volume (0...127) uint8 pan; // MIDI channel panning (0...256) uint8 midiCh; // MIDI channel that was last played on this channel ModCommand::NOTE note; // MIDI note that was last played on this channel bool sustained : 1; // If true, the note was already released by a note-off event, but sustain pedal CC is still active ModChannelState() : age(0) , porta(0) , vol(100) , pan(128) , midiCh(NOMIDI) , note(NOTE_NONE) , sustained(false) { } }; struct MidiChannelState { int32 pitchbendMod; // Pre-computed pitchbend in extra-fine slide units (1/64th of a semitone) int16 pitchbend; // 0...16383 uint16 bank; // 0...16383 uint8 program; // 0...127 // -- Controllers ------------- function ---------- CC# --- range ---- init (midi) --- uint8 pan; // Channel Panning 10 [0-255] 128 (64) uint8 expression; // Channel Expression 11 0-128 128 (127) uint8 volume; // Channel Volume 7 0-128 80 (100) uint16 rpn; // Currently selected RPN 100/101 n/a uint8 pitchBendRange; // Pitch Bend Range 2 int8 transpose; // Channel transpose 0 bool monoMode : 1; // Mono/Poly operation 126/127 n/a Poly bool sustain : 1; // Sustain pedal 64 on/off off CHANNELINDEX noteOn[128]; // Value != CHANNELINDEX_INVALID: Note is active and mapped to mod channel in value MidiChannelState() : pitchbendMod(0) , pitchbend(MIDIEvents::pitchBendCentre) , bank(0) , program(0) , pan(128) , expression(128) , volume(80) , rpn(0x3FFF) , pitchBendRange(2) , transpose(0) , monoMode(false) , sustain(false) { for(auto ¬e : noteOn) { note = CHANNELINDEX_INVALID; } } void SetPitchbend(uint16 value) { pitchbend = value; // Convert from arbitrary MIDI pitchbend to 64th of semitone pitchbendMod = Util::muldiv(pitchbend - MIDIEvents::pitchBendCentre, pitchBendRange * 64, MIDIEvents::pitchBendCentre); } void ResetAllControllers() { expression = 128; pitchBendRange = 2; SetPitchbend(MIDIEvents::pitchBendCentre); transpose = 0; rpn = 0x3FFF; monoMode = false; sustain = false; // Should also reset modulation, pedals (40h-43h), aftertouch } void SetRPN(uint8 value) { switch(rpn) { case 0: // Pitch Bend Range pitchBendRange = std::max(value, uint8(1)); SetPitchbend(pitchbend); break; case 2: // Coarse Tune transpose = static_cast(value) - 64; break; } } uint8 GetRPN() const { switch(rpn) { case 0: // Pitch Bend Range return pitchBendRange; case 2: // Coarse Tune return transpose; } return 0; } }; static CHANNELINDEX FindUnusedChannel(uint8 midiCh, ModCommand::NOTE note, const std::vector &channels, bool monoMode, PatternRow patRow) { for(size_t i = 0; i < channels.size(); i++) { // Check if this note is already playing, or find any note of the same MIDI channel in case of mono mode if(channels[i].midiCh == midiCh && (channels[i].note == note || (monoMode && channels[i].note != NOTE_NONE))) { return static_cast(i); } } CHANNELINDEX anyUnusedChannel = CHANNELINDEX_INVALID; CHANNELINDEX anyFreeChannel = CHANNELINDEX_INVALID; CHANNELINDEX oldsetMidiCh = CHANNELINDEX_INVALID; tick_t oldestMidiChAge = Util::MaxValueOfType(oldestMidiChAge); CHANNELINDEX oldestAnyCh = 0; tick_t oldestAnyChAge = Util::MaxValueOfType(oldestAnyChAge); for(size_t i = 0; i < channels.size(); i++) { if(channels[i].note == NOTE_NONE && !patRow[i].IsNote()) { // Recycle channel previously used by the same MIDI channel if(channels[i].midiCh == midiCh) return static_cast(i); // If we cannot find a channel that was already used for the same MIDI channel, try a completely unused channel next else if(channels[i].midiCh == ModChannelState::NOMIDI && anyUnusedChannel == CHANNELINDEX_INVALID) anyUnusedChannel = static_cast(i); // And if that fails, try any channel that currently doesn't play a note. if(anyFreeChannel == CHANNELINDEX_INVALID) anyFreeChannel = static_cast(i); } // If we can't find any free channels, look for the oldest channels if(channels[i].midiCh == midiCh && channels[i].age < oldestMidiChAge) { // Oldest channel matching this MIDI channel oldestMidiChAge = channels[i].age; oldsetMidiCh = static_cast(i); } else if(channels[i].age < oldestAnyChAge) { // Any oldest channel oldestAnyChAge = channels[i].age; oldestAnyCh = static_cast(i); } } if(anyUnusedChannel != CHANNELINDEX_INVALID) return anyUnusedChannel; if(anyFreeChannel != CHANNELINDEX_INVALID) return anyFreeChannel; if(oldsetMidiCh != CHANNELINDEX_INVALID) return oldsetMidiCh; return oldestAnyCh; } static void MIDINoteOff(MidiChannelState &midiChn, std::vector &modChnStatus, uint8 note, uint8 delay, PatternRow patRow, std::bitset<16> drumChns) { CHANNELINDEX chn = midiChn.noteOn[note]; if(chn == CHANNELINDEX_INVALID) return; if(midiChn.sustain) { // Turn this off later modChnStatus[chn].sustained = true; return; } uint8 midiCh = modChnStatus[chn].midiCh; modChnStatus[chn].note = NOTE_NONE; midiChn.noteOn[note] = CHANNELINDEX_INVALID; ModCommand &m = patRow[chn]; if(m.note == NOTE_NONE) { m.note = NOTE_KEYOFF; if(delay != 0) { m.command = CMD_S3MCMDEX; m.param = 0xD0 | delay; } } else if(m.IsNote() && !drumChns[midiCh]) { // Only do note cuts for melodic instruments - they sound weird on drums which should fade out naturally. if(m.command == CMD_S3MCMDEX && (m.param & 0xF0) == 0xD0) { // Already have a note delay m.command = CMD_DELAYCUT; m.param = (m.param << 4) | (delay - (m.param & 0x0F)); } else if(m.command == CMD_NONE || m.command == CMD_PANNING8) { m.command = CMD_S3MCMDEX; m.param = 0xC0 | delay; } } } static void EnterMIDIVolume(ModCommand &m, ModChannelState &modChn, const MidiChannelState &midiChn) { m.volcmd = VOLCMD_VOLUME; int32 vol = CDLSBank::DLSMidiVolumeToLinear(modChn.vol) >> 8; vol = (vol * midiChn.volume * midiChn.expression) >> 13; Limit(vol, 4, 256); m.vol = static_cast(vol / 4); } bool CSoundFile::ReadMID(FileReader &file, ModLoadingFlags loadFlags) { file.Rewind(); // Microsoft MIDI files if(file.ReadMagic("RIFF")) { file.Skip(4); if(!file.ReadMagic("RMID")) { return false; } else if(loadFlags == onlyVerifyHeader) { return true; } do { char id[4]; file.ReadArray(id); uint32 length = file.ReadUint32LE(); if(memcmp(id, "data", 4)) { file.Skip(length); } else { break; } } while(file.CanRead(8)); } MThd fileHeader; if(!file.ReadMagic("MThd") || !file.ReadStruct(fileHeader) || fileHeader.numTracks == 0 || fileHeader.headerLength < 6 || !file.Skip(fileHeader.headerLength - 6)) { return false; } else if(loadFlags == onlyVerifyHeader) { return true; } InitializeGlobals(MOD_TYPE_MID); InitializeChannels(); #ifdef MODPLUG_TRACKER const uint32 quantize = Clamp(TrackerSettings::Instance().midiImportQuantize.Get(), 4u, 256u); const ROWINDEX patternLen = Clamp(TrackerSettings::Instance().midiImportPatternLen.Get(), ROWINDEX(1), MAX_PATTERN_ROWS); const uint8 ticksPerRow = Clamp(TrackerSettings::Instance().midiImportTicks.Get(), uint8(2), uint8(16)); #else const uint32 quantize = 32; // Must be 4 or higher const ROWINDEX patternLen = 128; const uint8 ticksPerRow = 16; // Must be in range 2...16 #endif #ifdef MPT_FUZZ_TRACKER // Avoid generating test cases that take overly long to evaluate const ORDERINDEX MPT_MIDI_IMPORT_MAX_ORDERS = 64; #else const ORDERINDEX MPT_MIDI_IMPORT_MAX_ORDERS = MAX_ORDERS; #endif m_songArtist = MPT_USTRING("MIDI Conversion"); m_madeWithTracker = MPT_USTRING("Standard MIDI File"); SetMixLevels(mixLevels1_17RC3); m_nTempoMode = tempoModeModern; m_SongFlags = SONG_LINEARSLIDES; m_nDefaultTempo.Set(120); m_nDefaultSpeed = ticksPerRow; m_nChannels = MAX_BASECHANNELS; m_nDefaultRowsPerBeat = quantize / 4; m_nDefaultRowsPerMeasure = 4 * m_nDefaultRowsPerBeat; m_nSamplePreAmp = m_nVSTiVolume = 32; TEMPO tempo = m_nDefaultTempo; uint16 ppqn = fileHeader.division; if(ppqn & 0x8000) { // SMPTE compatible units (approximation) int frames = 256 - (ppqn >> 8), subFrames = (ppqn & 0xFF); ppqn = static_cast(frames * subFrames / 2); } if(!ppqn) ppqn = 96; Order().clear(); MidiChannelState midiChnStatus[16]; const CHANNELINDEX tempoChannel = m_nChannels - 2, globalVolChannel = m_nChannels - 1; const uint16 numTracks = fileHeader.numTracks; std::vector tracks(numTracks); std::vector modChnStatus(m_nChannels); std::bitset<16> drumChns; drumChns.set(MIDI_DRUMCHANNEL - 1); for(uint16 t = 0; t < numTracks; t++) { if(!file.ReadMagic("MTrk")) return false; tracks[t].track = file.ReadChunk(file.ReadUint32BE()); tick_t delta = 0; tracks[t].track.ReadVarInt(delta); tracks[t].nextEvent = delta; } uint16 finishedTracks = 0; PATTERNINDEX emptyPattern = PATTERNINDEX_INVALID; ORDERINDEX lastOrd = 0; ROWINDEX lastRow = 0; ROWINDEX restartRow = ROWINDEX_INVALID; int8 masterTranspose = 0; bool isXG = false; bool isEMIDI = false; bool isType2 = (fileHeader.format == 2); while(finishedTracks < numTracks) { uint16 t = 0; tick_t tick = Util::MaxValueOfType(tick); for(uint16 track = 0; track < numTracks; track++) { if(!tracks[track].finished && tracks[track].nextEvent < tick) { tick = tracks[track].nextEvent; t = track; if(isType2) break; } } FileReader &track = tracks[t].track; tick_t modTicks = Util::muldivr_unsigned(tick, quantize * ticksPerRow, ppqn * 4u); ORDERINDEX ord = static_cast((modTicks / ticksPerRow) / patternLen); ROWINDEX row = (modTicks / ticksPerRow) % patternLen; uint8 delay = static_cast(modTicks % ticksPerRow); if(ord >= Order().GetLength()) { if(ord > MPT_MIDI_IMPORT_MAX_ORDERS) break; ORDERINDEX curSize = Order().GetLength(); // If we need to extend the order list by more than one pattern, this means that we // will be filling in empty patterns. Just recycle one empty pattern for this job. // We read events in chronological order, so it is never possible for the loader to // "jump back" to one of those empty patterns and write into it. if(ord > curSize && emptyPattern == PATTERNINDEX_INVALID) { if((emptyPattern = Patterns.InsertAny(patternLen)) == PATTERNINDEX_INVALID) break; } Order().resize(ord + 1, emptyPattern); if((Order()[ord] = Patterns.InsertAny(patternLen)) == PATTERNINDEX_INVALID) break; } // Keep track of position of last event for resizing the last pattern if(ord > lastOrd) { lastOrd = ord; lastRow = row; } else if(ord == lastOrd) { lastRow = std::max(lastRow, row); } PATTERNINDEX pat = Order()[ord]; PatternRow patRow = Patterns[pat].GetRow(row); uint8 data1 = track.ReadUint8(); if(data1 == 0xFF) { // Meta events data1 = track.ReadUint8(); size_t len = 0; track.ReadVarInt(len); FileReader chunk = track.ReadChunk(len); switch(data1) { case 1: // Text case 2: // Copyright m_songMessage.Read(chunk, len, SongMessage::leAutodetect); break; case 3: // Track Name if(len > 0) { std::string s; chunk.ReadString(s, len); if(!m_songMessage.empty()) m_songMessage.append(1, SongMessage::InternalLineEnding); m_songMessage += s; if(m_songName.empty()) m_songName = s; } break; case 4: // Instrument case 5: // Lyric break; case 6: // Marker case 7: // Cue point { std::string s; chunk.ReadString(s, len); Patterns[pat].SetName(s); if(!mpt::CompareNoCaseAscii(s, "loopStart")) { Order().SetRestartPos(ord); restartRow = row; } } break; case 8: // Patch name case 9: // Port name break; case 0x2F: // End Of Track tracks[t].finished = true; break; case 0x51: // Tempo { uint8 tempoRaw[3]; chunk.ReadArray(tempoRaw); uint32 tempoInt = (tempoRaw[0] << 16) | (tempoRaw[1] << 8) | tempoRaw[2]; if(tempoInt == 0) break; TEMPO newTempo(60000000.0 / tempoInt); if(!tick) { m_nDefaultTempo = newTempo; } else if(newTempo != tempo) { patRow[tempoChannel].command = CMD_TEMPO; patRow[tempoChannel].param = mpt::saturate_cast(std::max(32.0, Util::Round(newTempo.ToDouble()))); } tempo = newTempo; } break; default: break; } } else { if(data1 & 0x80) { // Command byte (if not present, repeat previous command byte) tracks[t].command = data1; if(data1 < 0xF0) data1 = track.ReadUint8(); } uint8 midiCh = tracks[t].command & 0x0F; switch(tracks[t].command & 0xF0) { case 0x80: // Note Off case 0x90: // Note On { data1 &= 0x7F; ModCommand::NOTE note = static_cast(Clamp(data1 + NOTE_MIN, NOTE_MIN, NOTE_MAX)); uint8 data2 = track.ReadUint8(); if(data2 > 0 && (tracks[t].command & 0xF0) == 0x90) { // Note On CHANNELINDEX chn = FindUnusedChannel(midiCh, note, modChnStatus, midiChnStatus[midiCh].monoMode, patRow); if(chn != CHANNELINDEX_INVALID) { modChnStatus[chn].age = tick; modChnStatus[chn].note = note; modChnStatus[chn].midiCh = midiCh; modChnStatus[chn].vol = data2; modChnStatus[chn].sustained = false; midiChnStatus[midiCh].noteOn[data1] = chn; int32 pitchOffset = 0; if(midiChnStatus[midiCh].pitchbendMod != 0) { pitchOffset = (midiChnStatus[midiCh].pitchbendMod + (midiChnStatus[midiCh].pitchbendMod > 0 ? 32 : -32)) / 64; modChnStatus[chn].porta = pitchOffset * 64; } else { modChnStatus[chn].porta = 0; } patRow[chn].note = static_cast(Clamp(note + pitchOffset + midiChnStatus[midiCh].transpose + masterTranspose, NOTE_MIN, NOTE_MAX)); patRow[chn].instr = mpt::saturate_cast(MapMidiInstrument(midiChnStatus[midiCh].program, midiChnStatus[midiCh].bank, midiCh + 1, data1, isXG, drumChns)); EnterMIDIVolume(patRow[chn], modChnStatus[chn], midiChnStatus[midiCh]); if(patRow[chn].command == CMD_PORTAMENTODOWN || patRow[chn].command == CMD_PORTAMENTOUP) { patRow[chn].command = CMD_NONE; } if(delay != 0) { patRow[chn].command = CMD_S3MCMDEX; patRow[chn].param = 0xD0 | delay; } if(modChnStatus[chn].pan != midiChnStatus[midiCh].pan && patRow[chn].command == CMD_NONE) { patRow[chn].command = CMD_PANNING8; patRow[chn].param = midiChnStatus[midiCh].pan; modChnStatus[chn].pan = midiChnStatus[midiCh].pan; } } } else { // Note Off MIDINoteOff(midiChnStatus[midiCh], modChnStatus, data1, delay, patRow, drumChns); } } break; case 0xA0: // Note Aftertouch { track.Skip(1); } break; case 0xB0: // Controller { uint8 data2 = track.ReadUint8(); switch(data1) { case MIDIEvents::MIDICC_Panposition_Coarse: midiChnStatus[midiCh].pan = data2 * 2u; for(auto chn : midiChnStatus[midiCh].noteOn) { if(chn != CHANNELINDEX_INVALID) { if(Patterns[pat].WriteEffect(EffectWriter(CMD_PANNING8, midiChnStatus[midiCh].pan).Channel(chn).Row(row))) { modChnStatus[chn].pan = midiChnStatus[midiCh].pan; } } } break; case MIDIEvents::MIDICC_DataEntry_Coarse: midiChnStatus[midiCh].SetRPN(data2); break; case MIDIEvents::MIDICC_Volume_Coarse: midiChnStatus[midiCh].volume = (uint8)(CDLSBank::DLSMidiVolumeToLinear(data2) >> 9); for(auto chn : midiChnStatus[midiCh].noteOn) { if(chn != CHANNELINDEX_INVALID) { EnterMIDIVolume(patRow[chn], modChnStatus[chn], midiChnStatus[midiCh]); } } break; case MIDIEvents::MIDICC_Expression_Coarse: midiChnStatus[midiCh].expression = (uint8)(CDLSBank::DLSMidiVolumeToLinear(data2) >> 9); for(auto chn : midiChnStatus[midiCh].noteOn) { if(chn != CHANNELINDEX_INVALID) { EnterMIDIVolume(patRow[chn], modChnStatus[chn], midiChnStatus[midiCh]); } } break; case MIDIEvents::MIDICC_BankSelect_Coarse: midiChnStatus[midiCh].bank &= 0x7F; midiChnStatus[midiCh].bank |= (data2 << 7); break; case MIDIEvents::MIDICC_BankSelect_Fine: midiChnStatus[midiCh].bank &= (0x7F << 7); midiChnStatus[midiCh].bank |= data2; break; case MIDIEvents::MIDICC_HoldPedal_OnOff: midiChnStatus[midiCh].sustain = (data2 >= 0x40); if(data2 < 0x40) { // Release notes that are still being held after note-off for(const auto &chnState : modChnStatus) { if(chnState.midiCh == midiCh && chnState.sustained) { MIDINoteOff(midiChnStatus[midiCh], modChnStatus, chnState.note - NOTE_MIN, delay, patRow, drumChns); } } } break; case MIDIEvents::MIDICC_DataButtonincrement: case MIDIEvents::MIDICC_DataButtondecrement: midiChnStatus[midiCh].SetRPN(midiChnStatus[midiCh].GetRPN() + ((data1 == MIDIEvents::MIDICC_DataButtonincrement) ? 1 : -1)); break; case MIDIEvents::MIDICC_NonRegisteredParameter_Fine: case MIDIEvents::MIDICC_NonRegisteredParameter_Coarse: midiChnStatus[midiCh].rpn = 0x3FFF; break; case MIDIEvents::MIDICC_RegisteredParameter_Fine: midiChnStatus[midiCh].rpn &= (0x7F << 7); midiChnStatus[midiCh].rpn |= data2; break; case MIDIEvents::MIDICC_RegisteredParameter_Coarse: midiChnStatus[midiCh].rpn &= 0x7F; midiChnStatus[midiCh].rpn |= (data2 << 7); break; case 110: isEMIDI = true; break; case 111: // Non-standard MIDI loop point. May conflict with Apogee EMIDI CCs (110/111), which is why we also check if CC 110 is ever used. if(data2 == 0) { Order().SetRestartPos(ord); restartRow = row; } break; case MIDIEvents::MIDICC_AllControllersOff: midiChnStatus[midiCh].ResetAllControllers(); break; // Bn.78.00: All Sound Off (GS) // Bn.7B.00: All Notes Off (GM) case MIDIEvents::MIDICC_AllSoundOff: case MIDIEvents::MIDICC_AllNotesOff: // All Notes Off midiChnStatus[midiCh].sustain = false; for(uint8 note = 0; note < 128; note++) { MIDINoteOff(midiChnStatus[midiCh], modChnStatus, note, delay, patRow, drumChns); } break; case MIDIEvents::MIDICC_MonoOperation: if(data2 == 0) { midiChnStatus[midiCh].monoMode = true; } break; case MIDIEvents::MIDICC_PolyOperation: if(data2 == 0) { midiChnStatus[midiCh].monoMode = false; } break; } } break; case 0xC0: // Program Change midiChnStatus[midiCh].program = data1 & 0x7F; break; case 0xD0: // Channel aftertouch break; case 0xE0: // Pitch bend midiChnStatus[midiCh].SetPitchbend(data1 | (track.ReadUint8() << 7)); break; case 0xF0: // General / Immediate switch(midiCh) { case MIDIEvents::sysExStart: // SysEx case MIDIEvents::sysExEnd: // SysEx (continued) { uint32 len; track.ReadVarInt(len); FileReader sysex = track.ReadChunk(len); if(midiCh == MIDIEvents::sysExEnd) break; if(sysex.ReadMagic("\x7F\x7F\x04\x01")) { // Master volume uint8 volumeRaw[2]; sysex.ReadArray(volumeRaw); uint16 globalVol = volumeRaw[0] | (volumeRaw[1] << 7); if(tick == 0) { m_nDefaultGlobalVolume = Util::muldivr_unsigned(globalVol, MAX_GLOBAL_VOLUME, 16383); } else { patRow[globalVolChannel].command = CMD_GLOBALVOLUME; patRow[globalVolChannel].param = static_cast(Util::muldivr_unsigned(globalVol, 128, 16383)); } } else { uint8 xg[7]; sysex.ReadArray(xg); if(!memcmp(xg, "\x43\x10\x4C\x00\x00\x7E\x00", 7)) { // XG System On isXG = true; } else if(!memcmp(xg, "\x43\x10\x4C\x00\x00\x06", 6)) { // XG Master Transpose masterTranspose = static_cast(xg[6]) - 64; } else if(!memcmp(xg, "\x41\x10\x42\x12\x40", 5) && (xg[5] & 0xF0) == 0x10 && xg[6] == 0x15) { // GS Drum Kit uint8 chn = xg[5] & 0x0F; if(chn == 0) chn = 9; else if(chn < 10) chn--; drumChns.set(chn, xg[6] != 0); } } } break; case MIDIEvents::sysQuarterFrame: track.Skip(1); break; case MIDIEvents::sysPositionPointer: track.Skip(2); break; case MIDIEvents::sysSongSelect: track.Skip(1); break; case MIDIEvents::sysTuneRequest: case MIDIEvents::sysMIDIClock: case MIDIEvents::sysMIDITick: case MIDIEvents::sysStart: case MIDIEvents::sysContinue: case MIDIEvents::sysStop: case MIDIEvents::sysActiveSense: case MIDIEvents::sysReset: break; default: break; } break; default: break; } } // Pitch bend any channels that haven't reached their target yet // TODO: This is currently not called on any rows without events! for(size_t chn = 0; chn < modChnStatus.size(); chn++) { ModChannelState &chnState = modChnStatus[chn]; ModCommand &m = patRow[chn]; uint8 midiCh = chnState.midiCh; if(chnState.note == NOTE_NONE || m.command == CMD_S3MCMDEX || m.command == CMD_DELAYCUT || midiCh == ModChannelState::NOMIDI) continue; int32 diff = midiChnStatus[midiCh].pitchbendMod - chnState.porta; if(diff == 0) continue; if(m.command == CMD_PORTAMENTODOWN || m.command == CMD_PORTAMENTOUP) { // First, undo the effect of an existing portamento command int32 porta = 0; if(m.param < 0xE0) porta = m.param * 4 * (ticksPerRow - 1); else if(m.param < 0xF0) porta = (m.param & 0x0F); else porta = (m.param & 0x0F) * 4; if(m.command == CMD_PORTAMENTODOWN) porta = -porta; diff += porta; chnState.porta -= porta; if(diff == 0) { m.command = CMD_NONE; continue; } } m.command = static_cast(diff < 0 ? CMD_PORTAMENTODOWN : CMD_PORTAMENTOUP); int32 absDiff = mpt::abs(diff); int32 realDiff = 0; if(absDiff < 16) { // Extra-fine slides can do this. m.param = 0xE0 | static_cast(absDiff); realDiff = absDiff; } else if(absDiff < 64) { // Fine slides can do this. absDiff = std::min((absDiff + 3) / 4, 0x0F); m.param = 0xF0 | static_cast(absDiff); realDiff = absDiff * 4; } else { // Need a normal slide. absDiff /= 4 * (ticksPerRow - 1); LimitMax(absDiff, 0xDF); m.param = static_cast(absDiff); realDiff = absDiff * 4 * (ticksPerRow - 1); } chnState.porta += realDiff * sgn(diff); } tick_t delta = 0; if(track.ReadVarInt(delta) && track.CanRead(1)) { tracks[t].nextEvent += delta; } else { finishedTracks++; tracks[t].nextEvent = Util::MaxValueOfType(delta); tracks[t].finished = true; // Add another sub-song for type-2 files if(isType2 && finishedTracks < numTracks) { if(Order.AddSequence(false) == SEQUENCEINDEX_INVALID) break; Order().clear(); } } } if(isEMIDI) { Order().SetRestartPos(0); } if(Order().IsValidPat(lastOrd)) { PATTERNINDEX lastPat = Order()[lastOrd]; Patterns[lastPat].Resize(lastRow + 1); if(restartRow != ROWINDEX_INVALID && !isEMIDI) { Patterns[lastPat].WriteEffect(EffectWriter(CMD_PATTERNBREAK, mpt::saturate_cast(restartRow)).Row(lastRow)); } } Order.SetSequence(0); std::vector channels; channels.reserve(m_nChannels); for(CHANNELINDEX i = 0; i < m_nChannels; i++) { if(modChnStatus[i].midiCh != ModChannelState::NOMIDI #ifdef MODPLUG_TRACKER || (GetpModDoc() != nullptr && !GetpModDoc()->IsChannelUnused(i)) #endif // MODPLUG_TRACKER ) { channels.push_back(i); if(modChnStatus[i].midiCh != ModChannelState::NOMIDI) sprintf(ChnSettings[i].szName, "MIDI Ch %u", 1 + modChnStatus[i].midiCh); else if(i == tempoChannel) strcpy(ChnSettings[i].szName, "Tempo"); else if(i == globalVolChannel) strcpy(ChnSettings[i].szName, "Global Volume"); } } if(channels.empty()) return false; #ifdef MODPLUG_TRACKER if(GetpModDoc() != nullptr) { // Keep MIDI channels in patterns neatly grouped std::sort(channels.begin(), channels.end(), [&modChnStatus] (CHANNELINDEX c1, CHANNELINDEX c2) -> bool { if(modChnStatus[c1].midiCh == modChnStatus[c2].midiCh) return c1 < c2; return modChnStatus[c1].midiCh < modChnStatus[c2].midiCh; }); GetpModDoc()->ReArrangeChannels(channels, false); GetpModDoc()->m_ShowSavedialog = true; } std::shared_ptr pCachedBank, pEmbeddedBank; mpt::PathString cachedBankFile; if(CDLSBank::IsDLSBank(file.GetFileName())) { // Soundfont embedded in MIDI file pEmbeddedBank = std::make_shared(); pEmbeddedBank->Open(file.GetFileName()); } else { // Soundfont with same name as MIDI file for(const auto &ext : { MPT_PATHSTRING(".sf2"), MPT_PATHSTRING(".sbk"), MPT_PATHSTRING(".dls") }) { mpt::PathString filename = file.GetFileName().ReplaceExt(ext); if(filename.IsFile()) { pEmbeddedBank = std::make_shared(); if(pEmbeddedBank->Open(filename)) break; } } } ChangeModTypeTo(MOD_TYPE_MPT); MIDILIBSTRUCT &midiLib = CTrackApp::GetMidiLibrary(); // Scan Instruments for (INSTRUMENTINDEX nIns = 1; nIns <= m_nInstruments; nIns++) if (Instruments[nIns]) { mpt::PathString pszMidiMapName; ModInstrument *pIns = Instruments[nIns]; uint32 nMidiCode; bool embedded = false; if (pIns->nMidiChannel == MIDI_DRUMCHANNEL) nMidiCode = 0x80 | (pIns->nMidiDrumKey & 0x7F); else nMidiCode = pIns->nMidiProgram & 0x7F; pszMidiMapName = midiLib.MidiMap[nMidiCode]; if (pEmbeddedBank) { uint32 nDlsIns = 0, nDrumRgn = 0; uint32 nProgram = (pIns->nMidiProgram != 0) ? pIns->nMidiProgram - 1 : 0; uint32 dwKey = (nMidiCode < 128) ? 0xFF : (nMidiCode & 0x7F); if ((pEmbeddedBank->FindInstrument( (nMidiCode >= 128), ((pIns->wMidiBank - 1) & 0x3FFF), nProgram, dwKey, &nDlsIns)) || (pEmbeddedBank->FindInstrument( (nMidiCode >= 128), 0xFFFF, (nMidiCode >= 128) ? 0xFF : nProgram, dwKey, &nDlsIns))) { if (dwKey < 0x80) nDrumRgn = pEmbeddedBank->GetRegionFromKey(nDlsIns, dwKey); if (pEmbeddedBank->ExtractInstrument(*this, nIns, nDlsIns, nDrumRgn)) { pIns = Instruments[nIns]; // Reset pIns because ExtractInstrument may delete the previous value. if ((dwKey >= 24) && (dwKey < 24 + MPT_ARRAY_COUNT(szMidiPercussionNames))) { mpt::String::CopyN(pIns->name, szMidiPercussionNames[dwKey - 24]); } embedded = true; } else pIns = Instruments[nIns]; // Reset pIns because ExtractInstrument may delete the previous value. } } if((!pszMidiMapName.empty()) && (!embedded)) { // Load From DLS Bank if (CDLSBank::IsDLSBank(pszMidiMapName)) { std::shared_ptr pDLSBank = nullptr; if ((pCachedBank) && (!mpt::PathString::CompareNoCase(cachedBankFile, pszMidiMapName))) { pDLSBank = pCachedBank; } else { pCachedBank = std::make_shared(); cachedBankFile = pszMidiMapName; if (pCachedBank->Open(pszMidiMapName)) pDLSBank = pCachedBank; } if (pDLSBank) { uint32 nDlsIns = 0, nDrumRgn = 0; uint32 nProgram = (pIns->nMidiProgram != 0) ? pIns->nMidiProgram - 1 : 0; uint32 dwKey = (nMidiCode < 128) ? 0xFF : (nMidiCode & 0x7F); if ((pDLSBank->FindInstrument( (nMidiCode >= 128), ((pIns->wMidiBank - 1) & 0x3FFF), nProgram, dwKey, &nDlsIns)) || (pDLSBank->FindInstrument( (nMidiCode >= 128), 0xFFFF, (nMidiCode >= 128) ? 0xFF : nProgram, dwKey, &nDlsIns))) { if (dwKey < 0x80) nDrumRgn = pDLSBank->GetRegionFromKey(nDlsIns, dwKey); pDLSBank->ExtractInstrument(*this, nIns, nDlsIns, nDrumRgn); pIns = Instruments[nIns]; // Reset pIns because ExtractInstrument may delete the previous value. if ((dwKey >= 24) && (dwKey < 24 + MPT_ARRAY_COUNT(szMidiPercussionNames))) { mpt::String::CopyN(pIns->name, szMidiPercussionNames[dwKey - 24]); } } } } else { // Load from Instrument or Sample file InputFile f; if(f.Open(pszMidiMapName)) { FileReader insFile = GetFileReader(f); if(insFile.IsValid()) { ReadInstrumentFromFile(nIns, insFile, false); mpt::PathString szName = pszMidiMapName.GetFullFileName(); pIns = Instruments[nIns]; if (!pIns->filename[0]) mpt::String::Copy(pIns->filename, szName.ToLocale().c_str()); if (!pIns->name[0]) { if (nMidiCode < 128) { mpt::String::CopyN(pIns->name, szMidiProgramNames[nMidiCode]); } else { uint32 nKey = nMidiCode & 0x7F; if (nKey >= 24) mpt::String::CopyN(pIns->name, szMidiPercussionNames[nKey - 24]); } } } } } } } #endif // MODPLUG_TRACKER return true; } #else // !MODPLUG_TRACKER && !MPT_FUZZ_TRACKER bool CSoundFile::ReadMID(FileReader &/*file*/, ModLoadingFlags /*loadFlags*/) { return false; } #endif OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/AudioCriticalSection.h0000644000372100037210000000311513127442605022313 00000000000000/* * AudioCriticalSection.h * --------- * Purpose: Implementation of OpenMPT's critical section for access to CSoundFile. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once OPENMPT_NAMESPACE_BEGIN #if defined(MODPLUG_TRACKER) namespace mpt { class recursive_mutex_with_lock_count; } // namespace mpt namespace Tracker { // implemented in mptrack/Mptrack.cpp mpt::recursive_mutex_with_lock_count & GetGlobalMutexRef(); } // namespace Tracker // Critical section handling done in (safe) RAII style. // Create a CriticalSection object whenever you need exclusive access to CSoundFile. // One object = one lock / critical section. // The critical section is automatically left when the object is destroyed, but // Enter() and Leave() can also be called manually if needed. class CriticalSection { private: mpt::recursive_mutex_with_lock_count & m_refGlobalMutex; protected: bool inSection; public: enum InitialState { InitialLocked = 0, InitialUnlocked = 1 }; public: CriticalSection(); CriticalSection(CriticalSection &&other); explicit CriticalSection(InitialState state); void Enter(); void Leave(); ~CriticalSection(); }; #else // !MODPLUG_TRACKER class CriticalSection { public: enum InitialState { InitialLocked = 0, InitialUnlocked = 1 }; public: CriticalSection() {} explicit CriticalSection(InitialState state) { MPT_UNREFERENCED_PARAMETER(state); } void Enter() {} void Leave() {} ~CriticalSection() {} }; #endif // MODPLUG_TRACKER OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/XMTools.h0000644000372100037210000001511513105337554017624 00000000000000/* * XMTools.h * --------- * Purpose: Definition of XM file structures and helper functions * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once OPENMPT_NAMESPACE_BEGIN // XM File Header struct XMFileHeader { enum XMHeaderFlags { linearSlides = 0x01, extendedFilterRange = 0x1000, }; char signature[17]; // "Extended Module: " char songName[20]; // Song Name, not null-terminated (any nulls are treated as spaces) uint8le eof; // DOS EOF Character (0x1A) char trackerName[20]; // Software that was used to create the XM file uint16le version; // File version (1.02 - 1.04 are supported) uint32le size; // Header Size uint16le orders; // Number of Orders uint16le restartPos; // Restart Position uint16le channels; // Number of Channels uint16le patterns; // Number of Patterns uint16le instruments; // Number of Unstruments uint16le flags; // Song Flags uint16le speed; // Default Speed uint16le tempo; // Default Tempo }; MPT_BINARY_STRUCT(XMFileHeader, 80) // XM Instrument Data struct XMInstrument { // Envelope Flags enum XMEnvelopeFlags { envEnabled = 0x01, envSustain = 0x02, envLoop = 0x04, }; uint8le sampleMap[96]; // Note -> Sample assignment uint16le volEnv[24]; // Volume envelope nodes / values (0...64) uint16le panEnv[24]; // Panning envelope nodes / values (0...63) uint8le volPoints; // Volume envelope length uint8le panPoints; // Panning envelope length uint8le volSustain; // Volume envelope sustain point uint8le volLoopStart; // Volume envelope loop start point uint8le volLoopEnd; // Volume envelope loop end point uint8le panSustain; // Panning envelope sustain point uint8le panLoopStart; // Panning envelope loop start point uint8le panLoopEnd; // Panning envelope loop end point uint8le volFlags; // Volume envelope flags uint8le panFlags; // Panning envelope flags uint8le vibType; // Sample Auto-Vibrato Type uint8le vibSweep; // Sample Auto-Vibrato Sweep uint8le vibDepth; // Sample Auto-Vibrato Depth uint8le vibRate; // Sample Auto-Vibrato Rate uint16le volFade; // Volume Fade-Out uint8le midiEnabled; // MIDI Out Enabled (0 / 1) uint8le midiChannel; // MIDI Channel (0...15) uint16le midiProgram; // MIDI Program (0...127) uint16le pitchWheelRange; // MIDI Pitch Wheel Range (0...36 halftones) uint8le muteComputer; // Mute instrument if MIDI is enabled (0 / 1) uint8le reserved[15]; // Reserved enum EnvType { EnvTypeVol, EnvTypePan, }; // Convert OpenMPT's internal envelope representation to XM envelope data. void ConvertEnvelopeToXM(const InstrumentEnvelope &mptEnv, uint8le &numPoints, uint8le &flags, uint8le &sustain, uint8le &loopStart, uint8le &loopEnd, EnvType env); // Convert XM envelope data to an OpenMPT's internal envelope representation. void ConvertEnvelopeToMPT(InstrumentEnvelope &mptEnv, uint8 numPoints, uint8 flags, uint8 sustain, uint8 loopStart, uint8 loopEnd, EnvType env) const; // Convert OpenMPT's internal sample representation to an XMInstrument. uint16 ConvertToXM(const ModInstrument &mptIns, bool compatibilityExport); // Convert an XMInstrument to OpenMPT's internal instrument representation. void ConvertToMPT(ModInstrument &mptIns) const; // Apply auto-vibrato settings from sample to file. void ApplyAutoVibratoToXM(const ModSample &mptSmp, MODTYPE fromType); // Apply auto-vibrato settings from file to a sample. void ApplyAutoVibratoToMPT(ModSample &mptSmp) const; // Get a list of samples that should be written to the file. std::vector GetSampleList(const ModInstrument &mptIns, bool compatibilityExport) const; }; MPT_BINARY_STRUCT(XMInstrument, 230) // XM Instrument Header struct XMInstrumentHeader { uint32le size; // Size of XMInstrumentHeader + XMInstrument char name[22]; // Instrument Name, not null-terminated (any nulls are treated as spaces) uint8le type; // Instrument Type (Apparently FT2 writes some crap here, but it's the same crap for all instruments of the same module!) uint16le numSamples; // Number of Samples associated with instrument uint32le sampleHeaderSize; // Size of XMSample XMInstrument instrument; // Write stuff to the header that's always necessary (also for empty instruments) void Finalise(); // Convert OpenMPT's internal sample representation to an XMInstrument. void ConvertToXM(const ModInstrument &mptIns, bool compatibilityExport); // Convert an XMInstrument to OpenMPT's internal instrument representation. void ConvertToMPT(ModInstrument &mptIns) const; }; MPT_BINARY_STRUCT(XMInstrumentHeader, 263) // XI Instrument Header struct XIInstrumentHeader { enum { fileVersion = 0x102, }; char signature[21]; // "Extended Instrument: " char name[22]; // Instrument Name, not null-terminated (any nulls are treated as spaces) uint8le eof; // DOS EOF Character (0x1A) char trackerName[20]; // Software that was used to create the XI file uint16le version; // File Version (1.02) XMInstrument instrument; uint16le numSamples; // Number of embedded sample headers + samples // Convert OpenMPT's internal sample representation to an XIInstrumentHeader. void ConvertToXM(const ModInstrument &mptIns, bool compatibilityExport); // Convert an XIInstrumentHeader to OpenMPT's internal instrument representation. void ConvertToMPT(ModInstrument &mptIns) const; }; MPT_BINARY_STRUCT(XIInstrumentHeader, 298) // XM Sample Header struct XMSample { enum XMSampleFlags { sampleLoop = 0x01, sampleBidiLoop = 0x02, sample16Bit = 0x10, sampleStereo = 0x20, sampleADPCM = 0xAD, // MODPlugin :( }; uint32le length; // Sample Length (in bytes) uint32le loopStart; // Loop Start (in bytes) uint32le loopLength; // Loop Length (in bytes) uint8le vol; // Default Volume int8le finetune; // Sample Finetune uint8le flags; // Sample Flags uint8le pan; // Sample Panning int8le relnote; // Sample Transpose uint8le reserved; // Reserved (abused for ModPlug's ADPCM compression) char name[22]; // Sample Name, not null-terminated (any nulls are treated as spaces) // Convert OpenMPT's internal sample representation to an XMSample. void ConvertToXM(const ModSample &mptSmp, MODTYPE fromType, bool compatibilityExport); // Convert an XMSample to OpenMPT's internal sample representation. void ConvertToMPT(ModSample &mptSmp) const; // Retrieve the internal sample format flags for this instrument. SampleIO GetSampleFormat() const; }; MPT_BINARY_STRUCT(XMSample, 40) OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Load_uax.cpp0000644000372100037210000001121413161656666020354 00000000000000/* * Load_uax.cpp * ------------ * Purpose: UAX (Unreal Sounds) module ripper * Notes : The sounds are read into module sample slots. * Authors: Johannes Schultz (inspired by code from http://wiki.beyondunreal.com/Legacy:Package_File_Format) * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" #include "UMXTools.h" OPENMPT_NAMESPACE_BEGIN bool CSoundFile::ReadUAX(FileReader &file, ModLoadingFlags loadFlags) { file.Rewind(); UMXFileHeader fileHeader; if(!file.ReadStruct(fileHeader) || memcmp(fileHeader.magic, "\xC1\x83\x2A\x9E", 4) || fileHeader.nameCount == 0 || fileHeader.exportCount == 0 || fileHeader.importCount == 0 ) { return false; } // Note that this can be a false positive, e.g. Unreal maps will have music and sound // in their name table because they usually import such files. However, it spares us // from wildly seeking through the file, as the name table is usually right at the // start of the file, so it is hopefully a good enough heuristic for our purposes. if(!FindUMXNameTableEntry(file, fileHeader, "sound")) { return false; } if(loadFlags == onlyVerifyHeader) { return true; } // Read name table std::vector names = ReadUMXNameTable(file, fileHeader); // Read import table if(!file.Seek(fileHeader.importOffset)) { return false; } std::vector classes; classes.reserve(fileHeader.importCount); for(uint32 i = 0; i < fileHeader.importCount && file.CanRead(4); i++) { int32 objName = ReadUMXImportTableEntry(file, fileHeader.packageVersion); if(static_cast(objName) < names.size()) { classes.push_back(objName); } } // Read export table if(!file.Seek(fileHeader.exportOffset)) { return false; } // Now we can be pretty sure that we're doing the right thing. InitializeGlobals(); m_madeWithTracker = mpt::format(MPT_USTRING("Unreal Package v%1"))(fileHeader.packageVersion); for(uint32 i = 0; i < fileHeader.exportCount && file.CanRead(4); i++) { int32 objClass, objOffset, objSize, objName; ReadUMXExportTableEntry(file, objClass, objOffset, objSize, objName, fileHeader.packageVersion); if(objSize <= 0 || objClass >= 0) { continue; } // Look up object class name (we only want sounds). objClass = -objClass - 1; bool isSound = false; if(static_cast(objClass) < classes.size()) { isSound = (names[classes[objClass]] == "sound"); } if(!isSound) { continue; } FileReader chunk = file.GetChunkAt(objOffset, objSize); if(chunk.IsValid()) { if(fileHeader.packageVersion < 40) { chunk.Skip(8); // 00 00 00 00 00 00 00 00 } if(fileHeader.packageVersion < 60) { chunk.Skip(16); // 81 00 00 00 00 00 FF FF FF FF FF FF FF FF 00 00 } // Read object properties #if 0 size_t propertyName = static_cast(ReadUMXIndex(chunk)); if(propertyName >= names.size() || names[propertyName] != "none") { // Can't bother to implement property reading, as no UMX files I've seen so far use properties for the relevant objects, // and only the UAX files in the Unreal 1997/98 beta seem to use this and still load just fine when ignoring it. // If it should be necessary to implement this, check CUnProperty.cpp in http://ut-files.com/index.php?dir=Utilities/&file=utcms_source.zip MPT_ASSERT_NOTREACHED(); continue; } #else ReadUMXIndex(chunk); #endif if(fileHeader.packageVersion >= 120) { // UT2003 Packages ReadUMXIndex(chunk); chunk.Skip(8); } else if(fileHeader.packageVersion >= 100) { // AAO Packages chunk.Skip(4); ReadUMXIndex(chunk); chunk.Skip(4); } else if(fileHeader.packageVersion >= 62) { // UT Packages // Mech8.umx and a few other UT tunes have packageVersion = 62. // In CUnSound.cpp, the condition above reads "packageVersion >= 63" but if that is used, those tunes won't load properly. ReadUMXIndex(chunk); chunk.Skip(4); } else { // Old Unreal Packagaes ReadUMXIndex(chunk); } int32 size = ReadUMXIndex(chunk); FileReader fileChunk = chunk.ReadChunk(size); if(GetNumSamples() < MAX_SAMPLES - 1) { // Read as sample if(ReadSampleFromFile(GetNumSamples() + 1, fileChunk, true)) { if(static_cast(objName) < names.size()) { mpt::String::Copy(m_szNames[GetNumSamples()], names[objName]); } } } } } if(m_nSamples != 0) { InitializeChannels(); SetType(MOD_TYPE_MPT); m_ContainerType = MOD_CONTAINERTYPE_UAX; m_nChannels = 4; Patterns.Insert(0, 64); Order().assign(1, 0); return true; } else { return false; } } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Paula.h0000644000372100037210000000207313116243551017313 00000000000000/* * Paula.h * ------- * Purpose: Emulating the Amiga's sound chip, Paula, by implementing resampling using band-limited steps (BLEPs) * Notes : (currently none) * Authors: OpenMPT Devs * Antti S. Lankila * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "Snd_defs.h" OPENMPT_NAMESPACE_BEGIN namespace Paula { const int PAULA_HZ = 3546895; const int MINIMUM_INTERVAL = 16; const int BLEP_SCALE = 17; const int BLEP_SIZE = 2048; const int MAX_BLEPS = (BLEP_SIZE / MINIMUM_INTERVAL); class State { struct Blep { int16 level; uint16 age; }; public: SamplePosition remainder, stepRemainder; int numSteps; // Number of full-length steps private: uint16 activeBleps; // Count of simultaneous bleps to keep track of int16 globalOutputLevel; // The instantenous value of Paula output Blep blepState[MAX_BLEPS]; public: State(uint32 sampleRate = 48000); void Reset(); void InputSample(int16 sample); int OutputSample(bool filter); void Clock(int cycles); }; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Load_far.cpp0000644000372100037210000001624713161656666020342 00000000000000/* * Load_far.cpp * ------------ * Purpose: Farandole (FAR) module loader * Notes : (currently none) * Authors: OpenMPT Devs (partly inspired by Storlek's FAR loader from Schism Tracker) * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" OPENMPT_NAMESPACE_BEGIN // FAR File Header struct FARFileHeader { uint8le magic[4]; char songName[40]; uint8le eof[3]; uint16le headerLength; uint8le version; uint8le onOff[16]; uint8le editingState[9]; // Stuff we don't care about uint8le defaultSpeed; uint8le chnPanning[16]; uint8le patternState[4]; // More stuff we don't care about uint16le messageLength; }; MPT_BINARY_STRUCT(FARFileHeader, 98) struct FAROrderHeader { uint8le orders[256]; uint8le numPatterns; // supposed to be "number of patterns stored in the file"; apparently that's wrong uint8le numOrders; uint8le restartPos; uint16le patternSize[256]; }; MPT_BINARY_STRUCT(FAROrderHeader, 771) // FAR Sample header struct FARSampleHeader { // Sample flags enum SampleFlags { smp16Bit = 0x01, smpLoop = 0x08, }; char name[32]; uint32le length; uint8le finetune; uint8le volume; uint32le loopStart; uint32le loopEnd; uint8le type; uint8le loop; // Convert sample header to OpenMPT's internal format. void ConvertToMPT(ModSample &mptSmp) const { mptSmp.Initialize(); mptSmp.nLength = length; mptSmp.nLoopStart = loopStart; mptSmp.nLoopEnd = loopEnd; mptSmp.nC5Speed = 8363 * 2; mptSmp.nVolume = volume * 16; if(type & smp16Bit) { mptSmp.nLength /= 2; mptSmp.nLoopStart /= 2; mptSmp.nLoopEnd /= 2; } if((loop & 8) && mptSmp.nLoopEnd > mptSmp.nLoopStart) { mptSmp.uFlags.set(CHN_LOOP); } } // Retrieve the internal sample format flags for this sample. SampleIO GetSampleFormat() const { return SampleIO( (type & smp16Bit) ? SampleIO::_16bit : SampleIO::_8bit, SampleIO::mono, SampleIO::littleEndian, SampleIO::signedPCM); } }; MPT_BINARY_STRUCT(FARSampleHeader, 48) static bool ValidateHeader(const FARFileHeader &fileHeader) { if(std::memcmp(fileHeader.magic, "FAR\xFE", 4) != 0 || std::memcmp(fileHeader.eof, "\x0D\x0A\x1A", 3) ) { return false; } if(fileHeader.headerLength < sizeof(FARFileHeader)) { return false; } return true; } static uint64 GetHeaderMinimumAdditionalSize(const FARFileHeader &fileHeader) { return fileHeader.headerLength - sizeof(FARFileHeader); } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderFAR(MemoryFileReader file, const uint64 *pfilesize) { FARFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return ProbeWantMoreData; } if(!ValidateHeader(fileHeader)) { return ProbeFailure; } return ProbeAdditionalSize(file, pfilesize, GetHeaderMinimumAdditionalSize(fileHeader)); } bool CSoundFile::ReadFAR(FileReader &file, ModLoadingFlags loadFlags) { file.Rewind(); FARFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return false; } if(!ValidateHeader(fileHeader)) { return false; } if(!file.CanRead(mpt::saturate_cast(GetHeaderMinimumAdditionalSize(fileHeader)))) { return false; } if(loadFlags == onlyVerifyHeader) { return true; } // Globals InitializeGlobals(MOD_TYPE_FAR); m_nChannels = 16; m_nSamplePreAmp = 32; m_nDefaultSpeed = fileHeader.defaultSpeed; m_nDefaultTempo.Set(80); m_nDefaultGlobalVolume = MAX_GLOBAL_VOLUME; mpt::String::Read(m_songName, fileHeader.songName); // Read channel settings for(CHANNELINDEX chn = 0; chn < 16; chn++) { ChnSettings[chn].Reset(); ChnSettings[chn].dwFlags = fileHeader.onOff[chn] ? ChannelFlags(0) : CHN_MUTE; ChnSettings[chn].nPan = ((fileHeader.chnPanning[chn] & 0x0F) << 4) + 8; } // Read song message if(fileHeader.messageLength != 0) { m_songMessage.ReadFixedLineLength(file, fileHeader.messageLength, 132, 0); // 132 characters per line... wow. :) } // Read orders FAROrderHeader orderHeader; if(!file.ReadStruct(orderHeader)) { return false; } ReadOrderFromArray(Order(), orderHeader.orders, orderHeader.numOrders, 0xFF, 0xFE); Order().SetRestartPos(orderHeader.restartPos); file.Seek(fileHeader.headerLength); // Pattern effect LUT static const EffectCommand farEffects[] = { CMD_NONE, CMD_PORTAMENTOUP, CMD_PORTAMENTODOWN, CMD_TONEPORTAMENTO, CMD_RETRIG, CMD_VIBRATO, // depth CMD_VIBRATO, // speed CMD_VOLUMESLIDE, // up CMD_VOLUMESLIDE, // down CMD_VIBRATO, // sustained (?) CMD_NONE, // actually slide-to-volume CMD_S3MCMDEX, // panning CMD_S3MCMDEX, // note offset => note delay? CMD_NONE, // fine tempo down CMD_NONE, // fine tempo up CMD_SPEED, }; // Read patterns for(PATTERNINDEX pat = 0; pat < 256; pat++) { if(!orderHeader.patternSize[pat]) { continue; } FileReader patternChunk = file.ReadChunk(orderHeader.patternSize[pat]); // Calculate pattern length in rows (every event is 4 bytes, and we have 16 channels) ROWINDEX numRows = (orderHeader.patternSize[pat] - 2) / (16 * 4); if(!(loadFlags & loadPatternData) || !Patterns.Insert(pat, numRows)) { continue; } // Read break row and unused value ROWINDEX breakRow = patternChunk.ReadUint8(); patternChunk.Skip(1); if(breakRow > 0 && breakRow < numRows - 2) { breakRow++; } else { breakRow = ROWINDEX_INVALID; } // Read pattern data for(ROWINDEX row = 0; row < numRows; row++) { PatternRow rowBase = Patterns[pat].GetRow(row); for(CHANNELINDEX chn = 0; chn < 16; chn++) { ModCommand &m = rowBase[chn]; uint8 data[4]; patternChunk.ReadArray(data); if(data[0] > 0 && data[0] < 85) { m.note = data[0] + 35 + NOTE_MIN; m.instr = data[1] + 1; } if(data[2] & 0x0F) { m.volcmd = VOLCMD_VOLUME; m.vol = (data[2] & 0x0F) << 2; } m.param = data[3] & 0x0F; switch(data[3] >> 4) { case 0x03: // Porta to note m.param <<= 2; break; case 0x04: // Retrig m.param = 6 / (1 + (m.param & 0xf)) + 1; // ugh? break; case 0x06: // Vibrato speed case 0x07: // Volume slide up m.param *= 8; break; case 0x0A: // Volume-portamento (what!) m.volcmd = VOLCMD_VOLUME; m.vol = (m.param << 2) + 4; break; case 0x0B: // Panning m.param |= 0x80; break; case 0x0C: // Note offset m.param = 6 / (1 + m.param) + 1; m.param |= 0x0D; } m.command = farEffects[data[3] >> 4]; } } Patterns[pat].WriteEffect(EffectWriter(CMD_PATTERNBREAK, 0).Row(breakRow).RetryNextRow()); } if(!(loadFlags & loadSampleData)) { return true; } // Read samples uint8 sampleMap[8]; // Sample usage bitset file.ReadArray(sampleMap); for(SAMPLEINDEX smp = 0; smp < 64; smp++) { if(!(sampleMap[smp >> 3] & (1 << (smp & 7)))) { continue; } FARSampleHeader sampleHeader; if(!file.ReadStruct(sampleHeader)) { return true; } m_nSamples = smp + 1; ModSample &sample = Samples[m_nSamples]; mpt::String::Read(m_szNames[m_nSamples], sampleHeader.name); sampleHeader.ConvertToMPT(sample); sampleHeader.GetSampleFormat().ReadSample(sample, file); } return true; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/XMTools.cpp0000644000372100037210000003036113161656666020171 00000000000000/* * XMTools.cpp * ----------- * Purpose: Definition of XM file structures and helper functions * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" #include "XMTools.h" #include "Sndfile.h" #include "../common/version.h" #include OPENMPT_NAMESPACE_BEGIN // Convert OpenMPT's internal envelope representation to XM envelope data. void XMInstrument::ConvertEnvelopeToXM(const InstrumentEnvelope &mptEnv, uint8le &numPoints, uint8le &flags, uint8le &sustain, uint8le &loopStart, uint8le &loopEnd, EnvType env) { numPoints = static_cast(std::min(12u, mptEnv.size())); // Envelope Data for(uint8 i = 0; i < numPoints; i++) { switch(env) { case EnvTypeVol: volEnv[i * 2] = std::min(mptEnv[i].tick, uint16_max); volEnv[i * 2 + 1] = std::min(mptEnv[i].value, uint8(64)); break; case EnvTypePan: panEnv[i * 2] = std::min(mptEnv[i].tick, uint16_max); panEnv[i * 2 + 1] = std::min(mptEnv[i].value, uint8(63)); break; } } // Envelope Flags if(mptEnv.dwFlags[ENV_ENABLED]) flags |= XMInstrument::envEnabled; if(mptEnv.dwFlags[ENV_SUSTAIN]) flags |= XMInstrument::envSustain; if(mptEnv.dwFlags[ENV_LOOP]) flags |= XMInstrument::envLoop; // Envelope Loops sustain = std::min(uint8(12), mptEnv.nSustainStart); loopStart = std::min(uint8(12), mptEnv.nLoopStart); loopEnd = std::min(uint8(12), mptEnv.nLoopEnd); } // Convert OpenMPT's internal sample representation to an XMInstrument. uint16 XMInstrument::ConvertToXM(const ModInstrument &mptIns, bool compatibilityExport) { MemsetZero(*this); // FFF is maximum in the FT2 GUI, but it can also accept other values. MilkyTracker just allows 0...4095 and 32767 ("cut") volFade = static_cast(std::min(mptIns.nFadeOut, uint32(32767))); // Convert envelopes ConvertEnvelopeToXM(mptIns.VolEnv, volPoints, volFlags, volSustain, volLoopStart, volLoopEnd, EnvTypeVol); ConvertEnvelopeToXM(mptIns.PanEnv, panPoints, panFlags, panSustain, panLoopStart, panLoopEnd, EnvTypePan); // Create sample assignment table auto sampleList = GetSampleList(mptIns, compatibilityExport); for(size_t i = 0; i < CountOf(sampleMap); i++) { if(mptIns.Keyboard[i + 12] > 0) { auto sample = std::find(sampleList.begin(), sampleList.end(), mptIns.Keyboard[i + 12]); if(sample != sampleList.end()) { // Yep, we want to export this sample. sampleMap[i] = static_cast(sample - sampleList.begin()); } } } if(mptIns.nMidiChannel != MidiNoChannel) { midiEnabled = 1; midiChannel = (mptIns.nMidiChannel != MidiMappedChannel ? (mptIns.nMidiChannel - MidiFirstChannel) : 0); } midiProgram = (mptIns.nMidiProgram != 0 ? mptIns.nMidiProgram - 1 : 0); pitchWheelRange = std::min(mptIns.midiPWD, int8(36)); return static_cast(sampleList.size()); } // Get a list of samples that should be written to the file. std::vector XMInstrument::GetSampleList(const ModInstrument &mptIns, bool compatibilityExport) const { std::vector sampleList; // List of samples associated with this instrument std::vector addedToList; // Which samples did we already add to the sample list? uint8 numSamples = 0; for(size_t i = 0; i < CountOf(sampleMap); i++) { const SAMPLEINDEX smp = mptIns.Keyboard[i + 12]; if(smp > 0) { if(smp > addedToList.size()) { addedToList.resize(smp, false); } if(!addedToList[smp - 1] && numSamples < (compatibilityExport ? 16 : 32)) { // We haven't considered this sample yet. addedToList[smp - 1] = true; numSamples++; sampleList.push_back(smp); } } } return sampleList; } // Convert XM envelope data to an OpenMPT's internal envelope representation. void XMInstrument::ConvertEnvelopeToMPT(InstrumentEnvelope &mptEnv, uint8 numPoints, uint8 flags, uint8 sustain, uint8 loopStart, uint8 loopEnd, EnvType env) const { mptEnv.resize(std::min(numPoints, 12)); // Envelope Data for(uint32 i = 0; i < mptEnv.size(); i++) { switch(env) { case EnvTypeVol: mptEnv[i].tick = volEnv[i * 2]; mptEnv[i].value = static_cast(volEnv[i * 2 + 1]); break; case EnvTypePan: mptEnv[i].tick = panEnv[i * 2]; mptEnv[i].value = static_cast(panEnv[i * 2 + 1]); break; } if(i > 0 && mptEnv[i].tick < mptEnv[i - 1].tick) { // libmikmod code says: "Some broken XM editing program will only save the low byte of the position // value. Try to compensate by adding the missing high byte" - I guess that's what this code is for. // Note: It appears that MPT 1.07's XI instrument saver omitted the high byte of envelope nodes. // This might be the source for some broken envelopes in IT and XM files. mptEnv[i].tick &= 0xFF; mptEnv[i].tick += mptEnv[i - 1].tick & 0xFF00; if(mptEnv[i].tick < mptEnv[i - 1].tick) mptEnv[i].tick += 0x100; } } // Envelope Flags mptEnv.dwFlags.reset(); if((flags & XMInstrument::envEnabled) != 0 && !mptEnv.empty()) mptEnv.dwFlags.set(ENV_ENABLED); // Envelope Loops if(sustain < 12) { if((flags & XMInstrument::envSustain) != 0) mptEnv.dwFlags.set(ENV_SUSTAIN); mptEnv.nSustainStart = mptEnv.nSustainEnd = sustain; } if(loopEnd < 12 && loopEnd >= loopStart) { if((flags & XMInstrument::envLoop) != 0) mptEnv.dwFlags.set(ENV_LOOP); mptEnv.nLoopStart = loopStart; mptEnv.nLoopEnd = loopEnd; } } // Convert an XMInstrument to OpenMPT's internal instrument representation. void XMInstrument::ConvertToMPT(ModInstrument &mptIns) const { mptIns.nFadeOut = volFade; // Convert envelopes ConvertEnvelopeToMPT(mptIns.VolEnv, volPoints, volFlags, volSustain, volLoopStart, volLoopEnd, EnvTypeVol); ConvertEnvelopeToMPT(mptIns.PanEnv, panPoints, panFlags, panSustain, panLoopStart, panLoopEnd, EnvTypePan); // Create sample assignment table for(size_t i = 0; i < CountOf(sampleMap); i++) { mptIns.Keyboard[i + 12] = sampleMap[i]; } if(midiEnabled) { mptIns.nMidiChannel = midiChannel + MidiFirstChannel; Limit(mptIns.nMidiChannel, uint8(MidiFirstChannel), uint8(MidiLastChannel)); mptIns.nMidiProgram = static_cast(std::min(midiProgram, 127) + 1); } mptIns.midiPWD = static_cast(pitchWheelRange); } // Apply auto-vibrato settings from sample to file. void XMInstrument::ApplyAutoVibratoToXM(const ModSample &mptSmp, MODTYPE fromType) { vibType = mptSmp.nVibType; vibSweep = mptSmp.nVibSweep; vibDepth = mptSmp.nVibDepth; vibRate = mptSmp.nVibRate; if((vibDepth | vibRate) != 0 && !(fromType & MOD_TYPE_XM)) { if(mptSmp.nVibSweep != 0) vibSweep = mpt::saturate_cast(Util::muldivr_unsigned(mptSmp.nVibDepth, 256, mptSmp.nVibSweep)); else vibSweep = 255; } } // Apply auto-vibrato settings from file to a sample. void XMInstrument::ApplyAutoVibratoToMPT(ModSample &mptSmp) const { mptSmp.nVibType = vibType; mptSmp.nVibSweep = vibSweep; mptSmp.nVibDepth = vibDepth; mptSmp.nVibRate = vibRate; } // Write stuff to the header that's always necessary (also for empty instruments) void XMInstrumentHeader::Finalise() { size = sizeof(XMInstrumentHeader); if(numSamples > 0) { sampleHeaderSize = sizeof(XMSample); } else { // TODO: FT2 completely ignores MIDI settings (and also the less important stuff) if not at least one (empty) sample is assigned to this instrument! size -= sizeof(XMInstrument); sampleHeaderSize = 0; } } // Convert OpenMPT's internal sample representation to an XMInstrumentHeader. void XMInstrumentHeader::ConvertToXM(const ModInstrument &mptIns, bool compatibilityExport) { numSamples = instrument.ConvertToXM(mptIns, compatibilityExport); mpt::String::Write(name, mptIns.name); type = mptIns.nMidiProgram; // If FT2 writes crap here, we can do so, too! (we probably shouldn't, though. This is just for backwards compatibility with old MPT versions.) } // Convert an XMInstrumentHeader to OpenMPT's internal instrument representation. void XMInstrumentHeader::ConvertToMPT(ModInstrument &mptIns) const { instrument.ConvertToMPT(mptIns); // Create sample assignment table for(size_t i = 0; i < CountOf(instrument.sampleMap); i++) { if(instrument.sampleMap[i] < numSamples) { mptIns.Keyboard[i + 12] = instrument.sampleMap[i]; } else { mptIns.Keyboard[i + 12] = 0; } } mpt::String::Read(mptIns.name, name); // Old MPT backwards compatibility if(!instrument.midiEnabled) { mptIns.nMidiProgram = type; } } // Convert OpenMPT's internal sample representation to an XIInstrumentHeader. void XIInstrumentHeader::ConvertToXM(const ModInstrument &mptIns, bool compatibilityExport) { numSamples = instrument.ConvertToXM(mptIns, compatibilityExport); memcpy(signature, "Extended Instrument: ", 21); mpt::String::Write(name, mptIns.name); eof = 0x1A; const std::string openMptTrackerName = MptVersion::GetOpenMPTVersionStr(); mpt::String::Write(trackerName, openMptTrackerName); version = 0x102; } // Convert an XIInstrumentHeader to OpenMPT's internal instrument representation. void XIInstrumentHeader::ConvertToMPT(ModInstrument &mptIns) const { instrument.ConvertToMPT(mptIns); // Fix sample assignment table for(size_t i = 12; i < CountOf(instrument.sampleMap) + 12; i++) { if(mptIns.Keyboard[i] >= numSamples) { mptIns.Keyboard[i] = 0; } } mpt::String::Read(mptIns.name, name); } // Convert OpenMPT's internal sample representation to an XMSample. void XMSample::ConvertToXM(const ModSample &mptSmp, MODTYPE fromType, bool compatibilityExport) { MemsetZero(*this); // Volume / Panning vol = static_cast(std::min(mptSmp.nVolume / 4u, 64u)); pan = static_cast(std::min(mptSmp.nPan, uint16(255))); // Sample Frequency if((fromType & (MOD_TYPE_MOD | MOD_TYPE_XM))) { finetune = mptSmp.nFineTune; relnote = mptSmp.RelativeTone; } else { int f2t = ModSample::FrequencyToTranspose(mptSmp.nC5Speed); relnote = (int8)(f2t >> 7); finetune = (int8)(f2t & 0x7F); } flags = 0; if(mptSmp.uFlags[CHN_PINGPONGLOOP]) flags |= XMSample::sampleBidiLoop; else if(mptSmp.uFlags[CHN_LOOP]) flags |= XMSample::sampleLoop; // Sample Length and Loops length = mpt::saturate_cast(mptSmp.nLength); loopStart = mpt::saturate_cast(mptSmp.nLoopStart); loopLength = mpt::saturate_cast(mptSmp.nLoopEnd - mptSmp.nLoopStart); if(mptSmp.uFlags[CHN_16BIT]) { flags |= XMSample::sample16Bit; length *= 2; loopStart *= 2; loopLength *= 2; } if(mptSmp.uFlags[CHN_STEREO] && !compatibilityExport) { flags |= XMSample::sampleStereo; length *= 2; loopStart *= 2; loopLength *= 2; } } // Convert an XMSample to OpenMPT's internal sample representation. void XMSample::ConvertToMPT(ModSample &mptSmp) const { mptSmp.Initialize(MOD_TYPE_XM); // Volume mptSmp.nVolume = vol * 4; LimitMax(mptSmp.nVolume, uint16(256)); // Panning mptSmp.nPan = pan; mptSmp.uFlags = CHN_PANNING; // Sample Frequency mptSmp.nFineTune = finetune; mptSmp.RelativeTone = relnote; // Sample Length and Loops mptSmp.nLength = length; mptSmp.nLoopStart = loopStart; mptSmp.nLoopEnd = mptSmp.nLoopStart + loopLength; if((flags & XMSample::sample16Bit)) { mptSmp.nLength /= 2; mptSmp.nLoopStart /= 2; mptSmp.nLoopEnd /= 2; } if((flags & XMSample::sampleStereo)) { mptSmp.nLength /= 2; mptSmp.nLoopStart /= 2; mptSmp.nLoopEnd /= 2; } if((flags & (XMSample::sampleLoop | XMSample::sampleBidiLoop)) && mptSmp.nLoopStart < mptSmp.nLength && mptSmp.nLoopEnd > mptSmp.nLoopStart) { mptSmp.uFlags.set(CHN_LOOP); if((flags & XMSample::sampleBidiLoop)) { mptSmp.uFlags.set(CHN_PINGPONGLOOP); } } mptSmp.SanitizeLoops(); strcpy(mptSmp.filename, ""); } // Retrieve the internal sample format flags for this instrument. SampleIO XMSample::GetSampleFormat() const { if(reserved == sampleADPCM && !(flags & (XMSample::sample16Bit | XMSample::sampleStereo))) { // MODPlugin :( return SampleIO(SampleIO::_8bit, SampleIO::mono, SampleIO::littleEndian, SampleIO::ADPCM); } return SampleIO( (flags & XMSample::sample16Bit) ? SampleIO::_16bit : SampleIO::_8bit, (flags & XMSample::sampleStereo) ? SampleIO::stereoSplit : SampleIO::mono, SampleIO::littleEndian, SampleIO::deltaPCM); } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/mod_specifications.cpp0000644000372100037210000004170613161656666022473 00000000000000/* * mod_specifications.cpp * ---------------------- * Purpose: Mod specifications characterise the features of every editable module format in OpenMPT, such as the number of supported channels, samples, effects, etc... * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "mod_specifications.h" #include "../common/misc_util.h" #include OPENMPT_NAMESPACE_BEGIN namespace ModSpecs { // Force built-in integer operations. // C++11 constexpr operations on the enum value_type would also solve this. #define SongFlag FlagSet::store_type MPT_CONSTEXPR11_VAR CModSpecifications mptm_ = { /* TODO: Proper, less arbitrarily chosen values here. NOTE: If changing limits, see whether: -savefile format and GUI methods can handle new values(might not be a small task :). */ MOD_TYPE_MPT, // Internal MODTYPE value "mptm", // File extension NOTE_MIN, // Minimum note index NOTE_MAX, // Maximum note index 4000, // Pattern max. 4000, // Order max. MAX_SEQUENCES, // Sequences max 1, // Channel min 127, // Channel max 32, // Min tempo 512, // Max tempo 1, // Min Speed 255, // Max Speed 1, // Min pattern rows 1024, // Max pattern rows 25, // Max mod name length 25, // Max sample name length 12, // Max sample filename length 25, // Max instrument name length 12, // Max instrument filename length 0, // Max comment line length 3999, // SamplesMax 255, // instrumentMax mixLevels1_17RC3, // defaultMixLevels SongFlag(0) | SONG_LINEARSLIDES | SONG_EXFILTERRANGE | SONG_ITOLDEFFECTS | SONG_ITCOMPATGXX, // Supported song flags 200, // Max MIDI mapping directives MAX_ENVPOINTS, // Envelope point count true, // Has notecut. true, // Has noteoff. true, // Has notefade. true, // Has envelope release node true, // Has song comments true, // Has "+++" pattern true, // Has "---" pattern true, // Has restart position (order) true, // Supports plugins true, // Custom pattern time signatures true, // Pattern names true, // Has artist name true, // Has default resampling true, // Fixed point tempo " JFEGHLKRXODB?CQATI?SMNVW?UY?P?Z\\:#???????", // Supported Effects " vpcdabuh??gfe?o", // Supported Volume Column commands }; MPT_CONSTEXPR11_VAR CModSpecifications mod_ = { MOD_TYPE_MOD, // Internal MODTYPE value "mod", // File extension 37, // Minimum note index 108, // Maximum note index 128, // Pattern max. 128, // Order max. 1, // Only one order list 1, // Channel min 99, // Channel max 32, // Min tempo 255, // Max tempo 1, // Min Speed 31, // Max Speed 64, // Min pattern rows 64, // Max pattern rows 20, // Max mod name length 22, // Max sample name length 0, // Max sample filename length 0, // Max instrument name length 0, // Max instrument filename length 0, // Max comment line length 31, // SamplesMax 0, // instrumentMax mixLevelsCompatible, // defaultMixLevels SongFlag(0) | SONG_PT_MODE | SONG_AMIGALIMITS | SONG_ISAMIGA, // Supported song flags 0, // Max MIDI mapping directives 0, // No instrument envelopes false, // No notecut. false, // No noteoff. false, // No notefade. false, // No envelope release node false, // No song comments false, // Doesn't have "+++" pattern false, // Doesn't have "---" pattern true, // Has restart position (order) false, // Doesn't support plugins false, // No custom pattern time signatures false, // No pattern names false, // Doesn't have artist name false, // Doesn't have default resampling false, // Integer tempo " 0123456789ABCD?FF?E??????????????????????", // Supported Effects " ???????????????", // Supported Volume Column commands }; MPT_CONSTEXPR11_VAR CModSpecifications xm_ = { MOD_TYPE_XM, // Internal MODTYPE value "xm", // File extension 13, // Minimum note index 108, // Maximum note index 256, // Pattern max. 255, // Order max. 1, // Only one order list 1, // Channel min 32, // Channel max 32, // Min tempo 512, // Max tempo 1, // Min Speed 31, // Max Speed 1, // Min pattern rows 256, // Max pattern rows 20, // Max mod name length 22, // Max sample name length 0, // Max sample filename length 22, // Max instrument name length 0, // Max instrument filename length 0, // Max comment line length 128 * 16, // SamplesMax (actually 16 per instrument) 128, // instrumentMax mixLevelsCompatibleFT2, // defaultMixLevels SongFlag(0) | SONG_LINEARSLIDES, // Supported song flags 0, // Max MIDI mapping directives 12, // Envelope point count false, // No notecut. true, // Has noteoff. false, // No notefade. false, // No envelope release node false, // No song comments false, // Doesn't have "+++" pattern false, // Doesn't have "---" pattern true, // Has restart position (order) false, // Doesn't support plugins false, // No custom pattern time signatures false, // No pattern names false, // Doesn't have artist name false, // Doesn't have default resampling false, // Integer tempo " 0123456789ABCDRFFTE???GHK??XPL???????????", // Supported Effects " vpcdabuhlrg????", // Supported Volume Column commands }; // XM with MPT extensions MPT_CONSTEXPR11_VAR CModSpecifications xmEx_ = { MOD_TYPE_XM, // Internal MODTYPE value "xm", // File extension 13, // Minimum note index 108, // Maximum note index 256, // Pattern max. 255, // Order max. 1, // Only one order list 1, // Channel min 127, // Channel max 32, // Min tempo 512, // Max tempo 1, // Min Speed 31, // Max Speed 1, // Min pattern rows 1024, // Max pattern rows 20, // Max mod name length 22, // Max sample name length 0, // Max sample filename length 22, // Max instrument name length 0, // Max instrument filename length 0, // Max comment line length MAX_SAMPLES - 1, // SamplesMax (actually 32 per instrument(256 * 32 = 8192), but limited to MAX_SAMPLES = 4000) 255, // instrumentMax mixLevelsCompatibleFT2, // defaultMixLevels SongFlag(0) | SONG_LINEARSLIDES | SONG_EXFILTERRANGE, // Supported song flags 200, // Max MIDI mapping directives 12, // Envelope point count false, // No notecut. true, // Has noteoff. false, // No notefade. false, // No envelope release node true, // Has song comments false, // Doesn't have "+++" pattern false, // Doesn't have "---" pattern true, // Has restart position (order) true, // Supports plugins false, // No custom pattern time signatures true, // Pattern names true, // Has artist name false, // Doesn't have default resampling false, // Integer tempo " 0123456789ABCDRFFTE???GHK?YXPLZ\\?#???????", // Supported Effects " vpcdabuhlrg????", // Supported Volume Column commands }; MPT_CONSTEXPR11_VAR CModSpecifications s3m_ = { MOD_TYPE_S3M, // Internal MODTYPE value "s3m", // File extension 13, // Minimum note index 108, // Maximum note index 100, // Pattern max. 255, // Order max. 1, // Only one order list 1, // Channel min 32, // Channel max 33, // Min tempo 255, // Max tempo 1, // Min Speed 255, // Max Speed 64, // Min pattern rows 64, // Max pattern rows 27, // Max mod name length 27, // Max sample name length 12, // Max sample filename length 0, // Max instrument name length 0, // Max instrument filename length 0, // Max comment line length 99, // SamplesMax 0, // instrumentMax mixLevelsCompatible, // defaultMixLevels SongFlag(0) | SONG_FASTVOLSLIDES | SONG_AMIGALIMITS | SONG_S3MOLDVIBRATO, // Supported song flags 0, // Max MIDI mapping directives 0, // No instrument envelopes true, // Has notecut. false, // No noteoff. false, // No notefade. false, // No envelope release node false, // No song comments true, // Has "+++" pattern true, // Has "---" pattern false, // Doesn't have restart position (order) false, // Doesn't support plugins false, // No custom pattern time signatures false, // No pattern names false, // Doesn't have artist name false, // Doesn't have default resampling false, // Integer tempo " JFEGHLKRXODB?CQATI?SMNVW?U???????????????", // Supported Effects " vp?????????????", // Supported Volume Column commands }; // S3M with MPT extensions MPT_CONSTEXPR11_VAR CModSpecifications s3mEx_ = { MOD_TYPE_S3M, // Internal MODTYPE value "s3m", // File extension 13, // Minimum note index 108, // Maximum note index 100, // Pattern max. 255, // Order max. 1, // Only one order list 1, // Channel min 32, // Channel max 33, // Min tempo 255, // Max tempo 1, // Min Speed 255, // Max Speed 64, // Min pattern rows 64, // Max pattern rows 27, // Max mod name length 27, // Max sample name length 12, // Max sample filename length 0, // Max instrument name length 0, // Max instrument filename length 0, // Max comment line length 99, // SamplesMax 0, // instrumentMax mixLevelsCompatible, // defaultMixLevels SongFlag(0) | SONG_FASTVOLSLIDES | SONG_AMIGALIMITS, // Supported song flags 0, // Max MIDI mapping directives 0, // No instrument envelopes true, // Has notecut. false, // No noteoff. false, // No notefade. false, // No envelope release node false, // No song comments true, // Has "+++" pattern true, // Has "---" pattern false, // Doesn't have restart position (order) false, // Doesn't support plugins false, // No custom pattern time signatures false, // No pattern names false, // Doesn't have artist name false, // Doesn't have default resampling false, // Integer tempo " JFEGHLKRXODB?CQATI?SMNVW?UY?P?Z??????????", // Supported Effects " vp?????????????", // Supported Volume Column commands }; MPT_CONSTEXPR11_VAR CModSpecifications it_ = { MOD_TYPE_IT, // Internal MODTYPE value "it", // File extension 1, // Minimum note index 120, // Maximum note index 200, // Pattern max. 256, // Order max. 1, // Only one order list 1, // Channel min 64, // Channel max 32, // Min tempo 255, // Max tempo 1, // Min Speed 255, // Max Speed 1, // Min pattern rows 200, // Max pattern rows 25, // Max mod name length 25, // Max sample name length 12, // Max sample filename length 25, // Max instrument name length 12, // Max instrument filename length 75, // Max comment line length 99, // SamplesMax 99, // instrumentMax mixLevelsCompatible, // defaultMixLevels SongFlag(0) | SONG_LINEARSLIDES | SONG_ITOLDEFFECTS | SONG_ITCOMPATGXX, // Supported song flags 0, // Max MIDI mapping directives 25, // Envelope point count true, // Has notecut. true, // Has noteoff. true, // Has notefade. false, // No envelope release node true, // Has song comments true, // Has "+++" pattern true, // Has "--" pattern false, // Doesn't have restart position (order) false, // Doesn't support plugins false, // No custom pattern time signatures false, // No pattern names false, // Doesn't have artist name false, // Doesn't have default resampling false, // Integer tempo " JFEGHLKRXODB?CQATI?SMNVW?UY?P?Z??????????", // Supported Effects " vpcdab?h??gfe??", // Supported Volume Column commands }; MPT_CONSTEXPR11_VAR CModSpecifications itEx_ = { MOD_TYPE_IT, // Internal MODTYPE value "it", // File extension 1, // Minimum note index 120, // Maximum note index 240, // Pattern max. 256, // Order max. 1, // Only one order list 1, // Channel min 127, // Channel max 32, // Min tempo 512, // Max tempo 1, // Min Speed 255, // Max Speed 1, // Min pattern rows 1024, // Max pattern rows 25, // Max mod name length 25, // Max sample name length 12, // Max sample filename length 25, // Max instrument name length 12, // Max instrument filename length 75, // Max comment line length 3999, // SamplesMax 255, // instrumentMax mixLevelsCompatible, // defaultMixLevels SongFlag(0) | SONG_LINEARSLIDES | SONG_EXFILTERRANGE | SONG_ITOLDEFFECTS | SONG_ITCOMPATGXX, // Supported song flags 200, // Max MIDI mapping directives 25, // Envelope point count true, // Has notecut. true, // Has noteoff. true, // Has notefade. false, // No envelope release node true, // Has song comments true, // Has "+++" pattern true, // Has "---" pattern false, // Doesn't have restart position (order) true, // Supports plugins false, // No custom pattern time signatures true, // Pattern names true, // Has artist name false, // Doesn't have default resampling false, // Integer tempo " JFEGHLKRXODB?CQATI?SMNVW?UY?P?Z\\?#???????", // Supported Effects " vpcdab?h??gfe??", // Supported Volume Column commands }; const CModSpecifications *Collection[8] = { &mptm_, &mod_, &s3m_, &s3mEx_, &xm_, &xmEx_, &it_, &itEx_ }; const CModSpecifications & mptm = mptm_; const CModSpecifications & mod = mod_; const CModSpecifications & s3m = s3m_; const CModSpecifications & s3mEx = s3mEx_; const CModSpecifications & xm = xm_; const CModSpecifications & xmEx = xmEx_; const CModSpecifications & it = it_; const CModSpecifications & itEx = itEx_; } // namespace ModSpecs MODTYPE CModSpecifications::ExtensionToType(std::string ext) { if(ext == "") { return MOD_TYPE_NONE; } if(ext.length() > 0 && ext[0] == '.') { ext.erase(0, 1); } ext = mpt::ToLowerCaseAscii(ext); for(std::size_t i = 0; i < CountOf(ModSpecs::Collection); i++) { if(ext == ModSpecs::Collection[i]->fileExtension) { return ModSpecs::Collection[i]->internalType; } } return MOD_TYPE_NONE; } bool CModSpecifications::HasNote(ModCommand::NOTE note) const { if(note >= noteMin && note <= noteMax) return true; else if(ModCommand::IsSpecialNote(note)) { if(note == NOTE_NOTECUT) return hasNoteCut; else if(note == NOTE_KEYOFF) return hasNoteOff; else if(note == NOTE_FADE) return hasNoteFade; else return (internalType == MOD_TYPE_MPT); } else if(note == NOTE_NONE) return true; return false; } bool CModSpecifications::HasVolCommand(ModCommand::VOLCMD volcmd) const { if(volcmd >= MAX_VOLCMDS) return false; if(volcommands[volcmd] == '?') return false; return true; } bool CModSpecifications::HasCommand(ModCommand::COMMAND cmd) const { if(cmd >= MAX_EFFECTS) return false; if(commands[cmd] == '?') return false; return true; } char CModSpecifications::GetVolEffectLetter(ModCommand::VOLCMD volcmd) const { if(volcmd >= MAX_VOLCMDS) return '?'; return volcommands[volcmd]; } char CModSpecifications::GetEffectLetter(ModCommand::COMMAND cmd) const { if(cmd >= MAX_EFFECTS) return '?'; return commands[cmd]; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Load_dmf.cpp0000644000372100037210000010216113161656666020327 00000000000000/* * load_dmf.cpp * ------------ * Purpose: DMF module loader (X-Tracker by D-LUSiON). * Notes : If it wasn't already outdated when the tracker was released, this would be a rather interesting * and in some parts even sophisticated format - effect columns are separated by effect type, an easy to * understand BPM tempo mode, effect durations are always divided into a 256th row, vibrato effects are * specified by period length and the same 8-Bit granularity is used for both volume and panning. * Unluckily, this format does not offer any envelopes or multi-sample instruments, and bidi sample loops * are missing as well, so it was already well behind FT2 and IT back then. * Authors: Johannes Schultz (mostly based on DMF.TXT, DMF_EFFC.TXT, trial and error and some invaluable hints by Zatzen) * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" #include "ChunkReader.h" #include OPENMPT_NAMESPACE_BEGIN // DMF header struct DMFFileHeader { char signature[4]; // "DDMF" uint8 version; // 1 - 7 are beta versions, 8 is the official thing, 10 is xtracker32 char tracker[8]; // "XTRACKER" char songname[30]; char composer[20]; uint8 creationDay; uint8 creationMonth; uint8 creationYear; }; MPT_BINARY_STRUCT(DMFFileHeader, 66) struct DMFChunk { // 32-Bit chunk identifiers enum ChunkIdentifiers { idCMSG = MAGIC4LE('C','M','S','G'), // Song message idSEQU = MAGIC4LE('S','E','Q','U'), // Order list idPATT = MAGIC4LE('P','A','T','T'), // Patterns idSMPI = MAGIC4LE('S','M','P','I'), // Sample headers idSMPD = MAGIC4LE('S','M','P','D'), // Sample data idSMPJ = MAGIC4LE('S','M','P','J'), // Sample jump table (XTracker 32 only) idENDE = MAGIC4LE('E','N','D','E'), // Last four bytes of DMF file idSETT = MAGIC4LE('S','E','T','T'), // Probably contains GUI settings }; uint32le id; uint32le length; size_t GetLength() const { return length; } ChunkIdentifiers GetID() const { return static_cast(id.get()); } }; MPT_BINARY_STRUCT(DMFChunk, 8) // Order list struct DMFSequence { uint16le loopStart; uint16le loopEnd; // order list follows here ... }; MPT_BINARY_STRUCT(DMFSequence, 4) // Pattern header (global) struct DMFPatterns { uint16le numPatterns; // 1..1024 patterns uint8le numTracks; // 1..32 channels }; MPT_BINARY_STRUCT(DMFPatterns, 3) // Pattern header (for each pattern) struct DMFPatternHeader { uint8le numTracks; // 1..32 channels uint8le beat; // [hi|lo] -> hi = rows per beat, lo = reserved uint16le numRows; uint32le patternLength; // patttern data follows here ... }; MPT_BINARY_STRUCT(DMFPatternHeader, 8) // Sample header struct DMFSampleHeader { enum SampleFlags { // Sample flags smpLoop = 0x01, smp16Bit = 0x02, smpCompMask = 0x0C, smpComp1 = 0x04, // Compression type 1 smpComp2 = 0x08, // Compression type 2 (unused) smpComp3 = 0x0C, // Compression type 3 (ditto) smpLibrary = 0x80, // Sample is stored in a library }; uint32le length; uint32le loopStart; uint32le loopEnd; uint16le c3freq; // 1000..45000hz uint8le volume; // 0 = ignore uint8le flags; // Convert an DMFSampleHeader to OpenMPT's internal sample representation. void ConvertToMPT(ModSample &mptSmp) const { mptSmp.Initialize(); mptSmp.nLength = length; mptSmp.nSustainStart = loopStart; mptSmp.nSustainEnd = loopEnd; mptSmp.nC5Speed = c3freq; mptSmp.nGlobalVol = 64; if(volume) mptSmp.nVolume = volume + 1; else mptSmp.nVolume = 256; mptSmp.uFlags.set(SMP_NODEFAULTVOLUME, volume == 0); if((flags & smpLoop) != 0 && mptSmp.nSustainEnd > mptSmp.nSustainStart) { mptSmp.uFlags.set(CHN_SUSTAINLOOP); } if((flags & smp16Bit) != 0) { mptSmp.uFlags.set(CHN_16BIT); mptSmp.nLength /= 2; mptSmp.nSustainStart /= 2; mptSmp.nSustainEnd /= 2; } } }; MPT_BINARY_STRUCT(DMFSampleHeader, 16) // Sample header tail (between head and tail, there might be the library name of the sample, depending on the DMF version) struct DMFSampleHeaderTail { uint16le filler; uint32le crc32; }; MPT_BINARY_STRUCT(DMFSampleHeaderTail, 6) // Pattern translation memory struct DMFPatternSettings { struct ChannelState { ModCommand::NOTE noteBuffer; // Note buffer ModCommand::NOTE lastNote; // Last played note on channel uint8 vibratoType; // Last used vibrato type on channel uint8 tremoloType; // Last used tremolo type on channel uint8 highOffset; // Last used high offset on channel bool playDir; // Sample play direction... false = forward (default) ChannelState() { noteBuffer = lastNote = NOTE_NONE; vibratoType = 8; tremoloType = 4; highOffset = 6; playDir = false; } }; std::vector channels; // Memory for each channel's state bool realBPMmode; // true = BPM mode uint8 beat; // Rows per beat uint8 tempoTicks; // Tick mode param uint8 tempoBPM; // BPM mode param uint8 internalTicks; // Ticks per row in final pattern DMFPatternSettings(CHANNELINDEX numChannels) : channels(numChannels) { realBPMmode = false; beat = 0; tempoTicks = 32; tempoBPM = 120; internalTicks = 6; } }; // Convert portamento value (not very accurate due to X-Tracker's higher granularity, to say the least) static uint8 DMFporta2MPT(uint8 val, const uint8 internalTicks, const bool hasFine) { if(val == 0) return 0; else if((val <= 0x0F && hasFine) || internalTicks < 2) return (val | 0xF0); else return std::max(1, (val / (internalTicks - 1))); // no porta on first tick! } // Convert portamento / volume slide value (not very accurate due to X-Tracker's higher granularity, to say the least) static uint8 DMFslide2MPT(uint8 val, const uint8 internalTicks, const bool up) { val = std::max(1, val / 4); const bool isFine = (val < 0x0F) || (internalTicks < 2); if(!isFine) val = std::max(1, (val + internalTicks - 2) / (internalTicks - 1)); // no slides on first tick! "+ internalTicks - 2" for rounding precision if(up) return (isFine ? 0x0F : 0x00) | (val << 4); else return (isFine ? 0xF0 : 0x00) | (val & 0x0F); } // Calculate tremor on/off param static uint8 DMFtremor2MPT(uint8 val, const uint8 internalTicks) { uint8 ontime = (val >> 4); uint8 offtime = (val & 0x0F); ontime = static_cast(Clamp(ontime * internalTicks / 15, 1, 15)); offtime = static_cast(Clamp(offtime * internalTicks / 15, 1, 15)); return (ontime << 4) | offtime; } // Calculate delay parameter for note cuts / delays static uint8 DMFdelay2MPT(uint8 val, const uint8 internalTicks) { int newval = (int)val * (int)internalTicks / 255; Limit(newval, 0, 15); return (uint8)newval; } // Convert vibrato-style command parameters static uint8 DMFvibrato2MPT(uint8 val, const uint8 internalTicks) { // MPT: 1 vibrato period == 64 ticks... we have internalTicks ticks per row. // X-Tracker: Period length specified in rows! const int periodInTicks = MAX(1, (val >> 4)) * internalTicks; const uint8 matchingPeriod = (uint8)Clamp((128 / periodInTicks), 1, 15); return (matchingPeriod << 4) | MAX(1, (val & 0x0F)); } // Try using effect memory (zero paramer) to give the effect swapper some optimization hints. static void ApplyEffectMemory(const ModCommand *m, ROWINDEX row, CHANNELINDEX numChannels, uint8 effect, uint8 ¶m) { if(effect == CMD_NONE || param == 0) { return; } const bool isTonePortaEffect = (effect == CMD_PORTAMENTOUP || effect == CMD_PORTAMENTODOWN || effect == CMD_TONEPORTAMENTO); const bool isVolSlideEffect = (effect == CMD_VOLUMESLIDE || effect == CMD_TONEPORTAVOL || effect == CMD_VIBRATOVOL); while(row > 0) { m -= numChannels; row--; // First, keep some extra rules in mind for portamento, where effect memory is shared between various commands. bool isSame = (effect == m->command); if(isTonePortaEffect && (m->command == CMD_PORTAMENTOUP || m->command == CMD_PORTAMENTODOWN || m->command == CMD_TONEPORTAMENTO)) { if(m->param < 0xE0) { // Avoid effect param for fine slides, or else we could accidentally put this command in the volume column, where fine slides won't work! isSame = true; } else { return; } } else if(isVolSlideEffect && (m->command == CMD_VOLUMESLIDE || m->command == CMD_TONEPORTAVOL || m->command == CMD_VIBRATOVOL)) { isSame = true; } if(isTonePortaEffect && (m->volcmd == VOLCMD_PORTAUP || m->volcmd == VOLCMD_PORTADOWN || m->volcmd == VOLCMD_TONEPORTAMENTO) && m->vol != 0) { // Uuh... Don't even try return; } else if(isVolSlideEffect && (m->volcmd == VOLCMD_FINEVOLUP || m->volcmd == VOLCMD_FINEVOLDOWN || m->volcmd == VOLCMD_VOLSLIDEUP || m->volcmd == VOLCMD_VOLSLIDEDOWN) && m->vol != 0) { // Same! return; } if(isSame) { if(param != m->param && m->param != 0) { // No way to optimize this return; } else if(param == m->param) { // Yay! param = 0; return; } } } } static PATTERNINDEX ConvertDMFPattern(FileReader &file, DMFPatternSettings &settings, CSoundFile &sndFile) { // Pattern flags enum PatternFlags { // Global Track patGlobPack = 0x80, // Pack information for global track follows patGlobMask = 0x3F, // Mask for global effects // Note tracks patCounter = 0x80, // Pack information for current channel follows patInstr = 0x40, // Instrument number present patNote = 0x20, // Note present patVolume = 0x10, // Volume present patInsEff = 0x08, // Instrument effect present patNoteEff = 0x04, // Note effect present patVolEff = 0x02, // Volume effect stored }; file.Rewind(); DMFPatternHeader patHead; file.ReadStruct(patHead); const ROWINDEX numRows = Clamp(ROWINDEX(patHead.numRows), ROWINDEX(1), MAX_PATTERN_ROWS); const PATTERNINDEX pat = sndFile.Patterns.InsertAny(numRows); if(pat == PATTERNINDEX_INVALID) { return pat; } PatternRow m = sndFile.Patterns[pat].GetRow(0); const CHANNELINDEX numChannels = std::min(sndFile.GetNumChannels() - 1, patHead.numTracks); // When breaking to a pattern with less channels that the previous pattern, // all voices in the now unused channels are killed: for(CHANNELINDEX chn = numChannels + 1; chn < sndFile.GetNumChannels(); chn++) { m[chn].note = NOTE_NOTECUT; } // Initialize tempo stuff settings.beat = (patHead.beat >> 4); bool tempoChange = settings.realBPMmode; uint8 writeDelay = 0; // Counters for channel packing (including global track) std::vector channelCounter(numChannels + 1, 0); for(ROWINDEX row = 0; row < numRows; row++) { // Global track info counter reached 0 => read global track data if(channelCounter[0] == 0) { uint8 globalInfo = file.ReadUint8(); // 0x80: Packing counter (if not present, counter stays at 0) if((globalInfo & patGlobPack) != 0) { channelCounter[0] = file.ReadUint8(); } globalInfo &= patGlobMask; uint8 globalData = 0; if(globalInfo != 0) { globalData = file.ReadUint8(); } switch(globalInfo) { case 1: // Set Tick Frame Speed settings.realBPMmode = false; settings.tempoTicks = std::max(uint8(1), globalData); // Tempo in 1/4 rows per second settings.tempoBPM = 0; // Automatically updated by X-Tracker tempoChange = true; break; case 2: // Set BPM Speed (real BPM mode) if(globalData) // DATA = 0 doesn't do anything { settings.realBPMmode = true; settings.tempoBPM = globalData; // Tempo in real BPM (depends on rows per beat) if(settings.beat != 0) { settings.tempoTicks = (globalData * settings.beat * 15); // Automatically updated by X-Tracker } tempoChange = true; } break; case 3: // Set Beat settings.beat = (globalData >> 4); if(settings.beat != 0) { // Tempo changes only if we're in real BPM mode tempoChange = settings.realBPMmode; } else { // If beat is 0, change to tick speed mode, but keep current tempo settings.realBPMmode = false; } break; case 4: // Tick Delay writeDelay = globalData; break; case 5: // Set External Flag break; case 6: // Slide Speed Up if(globalData > 0) { uint8 &tempoData = (settings.realBPMmode) ? settings.tempoBPM : settings.tempoTicks; if(tempoData < 256 - globalData) { tempoData += globalData; } else { tempoData = 255; } tempoChange = true; } break; case 7: // Slide Speed Down if(globalData > 0) { uint8 &tempoData = (settings.realBPMmode) ? settings.tempoBPM : settings.tempoTicks; if(tempoData > 1 + globalData) { tempoData -= globalData; } else { tempoData = 1; } tempoChange = true; } break; } } else { channelCounter[0]--; } // These will eventually be written to the pattern int speed = 0, tempo = 0; if(tempoChange) { // Can't do anything if we're in BPM mode and there's no rows per beat set... if(!settings.realBPMmode || settings.beat) { // My approach to convert X-Tracker's "tick speed" (1/4 rows per second): // Tempo * 6 / Speed = Beats per Minute // => Tempo * 6 / (Speed * 60) = Beats per Second // => Tempo * 24 / (Speed * 60) = Rows per Second (4 rows per beat at tempo 6) // => Tempo = 60 * Rows per Second * Speed / 24 // For some reason, using settings.tempoTicks + 1 gives more accurate results than just settings.tempoTicks... (same problem in the old libmodplug DMF loader) // Original unoptimized formula: //const int tickspeed = (tempoRealBPMmode) ? MAX(1, (tempoData * beat * 4) / 60) : tempoData; const int tickspeed = (settings.realBPMmode) ? std::max(1, settings.tempoBPM * settings.beat * 2) : ((settings.tempoTicks + 1) * 30); // Try to find matching speed - try higher speeds first, so that effects like arpeggio and tremor work better. for(speed = 255; speed > 2; speed--) { // Original unoptimized formula: // tempo = 30 * tickspeed * speed / 48; tempo = tickspeed * speed / 48; if(tempo >= 32 && tempo <= 255) { break; } } Limit(tempo, 32, 255); settings.internalTicks = (uint8)speed; } else { tempoChange = false; } } m = sndFile.Patterns[pat].GetpModCommand(row, 1); // Reserve first channel for global effects for(CHANNELINDEX chn = 1; chn <= numChannels; chn++, m++) { // Track info counter reached 0 => read track data if(channelCounter[chn] == 0) { const uint8 channelInfo = file.ReadUint8(); //////////////////////////////////////////////////////////////// // 0x80: Packing counter (if not present, counter stays at 0) if((channelInfo & patCounter) != 0) { channelCounter[chn] = file.ReadUint8(); } //////////////////////////////////////////////////////////////// // 0x40: Instrument bool slideNote = true; // If there is no instrument number next to a note, the note is not retriggered! if((channelInfo & patInstr) != 0) { m->instr = file.ReadUint8(); if(m->instr != 0) { slideNote = false; } } //////////////////////////////////////////////////////////////// // 0x20: Note if((channelInfo & patNote) != 0) { m->note = file.ReadUint8(); if(m->note >= 1 && m->note <= 108) { m->note = static_cast(Clamp(m->note + 24, NOTE_MIN, NOTE_MAX)); settings.channels[chn].lastNote = m->note; } else if(m->note >= 129 && m->note <= 236) { // "Buffer notes" for portamento (and other effects?) that are actually not played, but just "queued"... m->note = static_cast(Clamp((m->note & 0x7F) + 24, NOTE_MIN, NOTE_MAX)); settings.channels[chn].noteBuffer = m->note; m->note = NOTE_NONE; } else if(m->note == 255) { m->note = NOTE_NOTECUT; } } // If there's just an instrument number, but no note, retrigger sample. if(m->note == NOTE_NONE && m->instr > 0) { m->note = settings.channels[chn].lastNote; m->instr = 0; } if(m->IsNote()) { settings.channels[chn].playDir = false; } uint8 effect1 = CMD_NONE, effect2 = CMD_NONE, effect3 = CMD_NONE; uint8 effectParam1 = 0, effectParam2 = 0, effectParam3 = 0; bool useMem2 = false, useMem3 = false; // Effect can use memory if necessary //////////////////////////////////////////////////////////////// // 0x10: Volume if((channelInfo & patVolume) != 0) { m->volcmd = VOLCMD_VOLUME; m->vol = (file.ReadUint8() + 2) / 4; // Should be + 3 instead of + 2, but volume 1 is silent in X-Tracker. } //////////////////////////////////////////////////////////////// // 0x08: Instrument effect if((channelInfo & patInsEff) != 0) { effect1 = file.ReadUint8(); effectParam1 = file.ReadUint8(); switch(effect1) { case 1: // Stop Sample m->note = NOTE_NOTECUT; effect1 = CMD_NONE; break; case 2: // Stop Sample Loop m->note = NOTE_KEYOFF; effect1 = CMD_NONE; break; case 3: // Instrument Volume Override (aka "Restart") m->note = settings.channels[chn].lastNote; settings.channels[chn].playDir = false; effect1 = CMD_NONE; break; case 4: // Sample Delay effectParam1 = DMFdelay2MPT(effectParam1, settings.internalTicks); if(effectParam1) { effect1 = CMD_S3MCMDEX; effectParam1 = 0xD0 | (effectParam1); } else { effect1 = CMD_NONE; } if(m->note == NOTE_NONE) { m->note = settings.channels[chn].lastNote; settings.channels[chn].playDir = false; } break; case 5: // Tremolo Retrig Sample (who invented those stupid effect names?) effectParam1 = MAX(1, DMFdelay2MPT(effectParam1, settings.internalTicks)); effect1 = CMD_RETRIG; settings.channels[chn].playDir = false; break; case 6: // Offset case 7: // Offset + 64k case 8: // Offset + 128k case 9: // Offset + 192k // Put high offset on previous row if(row > 0 && effect1 != settings.channels[chn].highOffset) { if(sndFile.Patterns[pat].WriteEffect(EffectWriter(CMD_S3MCMDEX, (0xA0 | (effect1 - 6))).Row(row - 1).Channel(chn).RetryPreviousRow())) { settings.channels[chn].highOffset = effect1; } } effect1 = CMD_OFFSET; if(m->note == NOTE_NONE) { // Offset without note does also work in DMF. m->note = settings.channels[chn].lastNote; } settings.channels[chn].playDir = false; break; case 10: // Invert Sample play direction ("Tekkno Invert") effect1 = CMD_S3MCMDEX; if(settings.channels[chn].playDir == false) effectParam1 = 0x9F; else effectParam1 = 0x9E; settings.channels[chn].playDir = !settings.channels[chn].playDir; break; default: effect1 = CMD_NONE; break; } } //////////////////////////////////////////////////////////////// // 0x04: Note effect if((channelInfo & patNoteEff) != 0) { effect2 = file.ReadUint8(); effectParam2 = file.ReadUint8(); switch(effect2) { case 1: // Note Finetune effect2 = static_cast(effectParam2 < 128 ? CMD_PORTAMENTOUP : CMD_PORTAMENTODOWN); if(effectParam2 > 128) effectParam2 = 255 - effectParam2 + 1; effectParam2 = 0xF0 | MIN(0x0F, effectParam2); // Well, this is not too accurate... break; case 2: // Note Delay (wtf is the difference to Sample Delay?) effectParam2 = DMFdelay2MPT(effectParam2, settings.internalTicks); if(effectParam2) { effect2 = CMD_S3MCMDEX; effectParam2 = 0xD0 | (effectParam2); } else { effect2 = CMD_NONE; } useMem2 = true; break; case 3: // Arpeggio effect2 = CMD_ARPEGGIO; useMem2 = true; break; case 4: // Portamento Up case 5: // Portamento Down effectParam2 = DMFporta2MPT(effectParam2, settings.internalTicks, true); effect2 = static_cast(effect2 == 4 ? CMD_PORTAMENTOUP : CMD_PORTAMENTODOWN); useMem2 = true; break; case 6: // Portamento to Note if(m->note == NOTE_NONE) { m->note = settings.channels[chn].noteBuffer; } effectParam2 = DMFporta2MPT(effectParam2, settings.internalTicks, false); effect2 = CMD_TONEPORTAMENTO; useMem2 = true; break; case 7: // Scratch to Note (neat! but we don't have such an effect...) m->note = static_cast(Clamp(effectParam2 + 25, NOTE_MIN, NOTE_MAX)); effect2 = CMD_TONEPORTAMENTO; effectParam2 = 0xFF; useMem2 = true; break; case 8: // Vibrato Sine case 9: // Vibrato Triangle (ramp down should be close enough) case 10: // Vibrato Square // Put vibrato type on previous row if(row > 0 && effect2 != settings.channels[chn].vibratoType) { if(sndFile.Patterns[pat].WriteEffect(EffectWriter(CMD_S3MCMDEX, (0x30 | (effect2 - 8))).Row(row - 1).Channel(chn).RetryPreviousRow())) { settings.channels[chn].vibratoType = effect2; } } effect2 = CMD_VIBRATO; effectParam2 = DMFvibrato2MPT(effectParam2, settings.internalTicks); useMem2 = true; break; case 11: // Note Tremolo effectParam2 = DMFtremor2MPT(effectParam2, settings.internalTicks); effect2 = CMD_TREMOR; useMem2 = true; break; case 12: // Note Cut effectParam2 = DMFdelay2MPT(effectParam2, settings.internalTicks); if(effectParam2) { effect2 = CMD_S3MCMDEX; effectParam2 = 0xC0 | (effectParam2); } else { effect2 = CMD_NONE; m->note = NOTE_NOTECUT; } useMem2 = true; break; default: effect2 = CMD_NONE; break; } } //////////////////////////////////////////////////////////////// // 0x02: Volume effect if((channelInfo & patVolEff) != 0) { effect3 = file.ReadUint8(); effectParam3 = file.ReadUint8(); switch(effect3) { case 1: // Volume Slide Up case 2: // Volume Slide Down effectParam3 = DMFslide2MPT(effectParam3, settings.internalTicks, (effect3 == 1)); effect3 = CMD_VOLUMESLIDE; useMem3 = true; break; case 3: // Volume Tremolo (actually this is Tremor) effectParam3 = DMFtremor2MPT(effectParam3, settings.internalTicks); effect3 = CMD_TREMOR; useMem3 = true; break; case 4: // Tremolo Sine case 5: // Tremolo Triangle (ramp down should be close enough) case 6: // Tremolo Square // Put tremolo type on previous row if(row > 0 && effect3 != settings.channels[chn].tremoloType) { if(sndFile.Patterns[pat].WriteEffect(EffectWriter(CMD_S3MCMDEX, (0x40 | (effect3 - 4))).Row(row - 1).Channel(chn).RetryPreviousRow())) { settings.channels[chn].tremoloType = effect3; } } effect3 = CMD_TREMOLO; effectParam3 = DMFvibrato2MPT(effectParam3, settings.internalTicks); useMem3 = true; break; case 7: // Set Balance effect3 = CMD_PANNING8; break; case 8: // Slide Balance Left case 9: // Slide Balance Right effectParam3 = DMFslide2MPT(effectParam3, settings.internalTicks, (effect3 == 8)); effect3 = CMD_PANNINGSLIDE; useMem3 = true; break; case 10: // Balance Vibrato Left/Right (always sine modulated) effect3 = CMD_PANBRELLO; effectParam3 = DMFvibrato2MPT(effectParam3, settings.internalTicks); useMem3 = true; break; default: effect3 = CMD_NONE; break; } } // Let's see if we can help the effect swapper by reducing some effect parameters to "continue" parameters. if(useMem2) { ApplyEffectMemory(m, row, sndFile.GetNumChannels(), effect2, effectParam2); } if(useMem3) { ApplyEffectMemory(m, row, sndFile.GetNumChannels(), effect3, effectParam3); } // I guess this is close enough to "not retriggering the note" if(slideNote && m->IsNote()) { if(effect2 == CMD_NONE) { effect2 = CMD_TONEPORTAMENTO; effectParam2 = 0xFF; } else if(effect3 == CMD_NONE && effect2 != CMD_TONEPORTAMENTO) // Tone portamentos normally go in effect #2 { effect3 = CMD_TONEPORTAMENTO; effectParam3 = 0xFF; } } // If one of the effects is unused, temporarily put volume commands in there if(m->volcmd == VOLCMD_VOLUME) { if(effect2 == CMD_NONE) { effect2 = CMD_VOLUME; effectParam2 = m->vol; m->volcmd = VOLCMD_NONE; } else if(effect3 == CMD_NONE) { effect3 = CMD_VOLUME; effectParam3 = m->vol; m->volcmd = VOLCMD_NONE; } } ModCommand::TwoRegularCommandsToMPT(effect2, effectParam2, effect3, effectParam3); if(m->volcmd == VOLCMD_NONE && effect2 != VOLCMD_NONE) { m->volcmd = effect2; m->vol = effectParam2; } // Prefer instrument effects over any other effects if(effect1 != CMD_NONE) { m->command = effect1; m->param = effectParam1; } else if(effect3 != CMD_NONE) { m->command = effect3; m->param = effectParam3; } } else { channelCounter[chn]--; } } // End for all channels // Now we can try to write tempo information. if(tempoChange) { tempoChange = false; sndFile.Patterns[pat].WriteEffect(EffectWriter(CMD_TEMPO, static_cast(tempo)).Row(row).Channel(0).RetryNextRow()); sndFile.Patterns[pat].WriteEffect(EffectWriter(CMD_SPEED, static_cast(speed)).Row(row).RetryNextRow()); } // Try to put delay effects somewhere as well if(writeDelay & 0xF0) { sndFile.Patterns[pat].WriteEffect(EffectWriter(CMD_S3MCMDEX, 0xE0 | (writeDelay >> 4)).Row(row).AllowMultiple()); } if(writeDelay & 0x0F) { const uint8 param = (writeDelay & 0x0F) * settings.internalTicks / 15; sndFile.Patterns[pat].WriteEffect(EffectWriter(CMD_S3MCMDEX, 0x60u | Clamp(param, uint8(1), uint8(15))).Row(row).AllowMultiple()); } writeDelay = 0; } // End for all rows return pat; } static bool ValidateHeader(const DMFFileHeader &fileHeader) { if(std::memcmp(fileHeader.signature, "DDMF", 4) || !fileHeader.version || fileHeader.version > 10) { return false; } return true; } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderDMF(MemoryFileReader file, const uint64 *pfilesize) { DMFFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return ProbeWantMoreData; } if(!ValidateHeader(fileHeader)) { return ProbeFailure; } MPT_UNREFERENCED_PARAMETER(pfilesize); return ProbeSuccess; } bool CSoundFile::ReadDMF(FileReader &file, ModLoadingFlags loadFlags) { file.Rewind(); DMFFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return false; } if(!ValidateHeader(fileHeader)) { return false; } if(loadFlags == onlyVerifyHeader) { return true; } InitializeGlobals(MOD_TYPE_DMF); mpt::String::Read(m_songName, fileHeader.songname); { std::string artist; mpt::String::Read(artist, fileHeader.composer); m_songArtist = mpt::ToUnicode(mpt::CharsetCP437, artist); } FileHistory mptHistory; MemsetZero(mptHistory); mptHistory.loadDate.tm_mday = Clamp(fileHeader.creationDay, uint8(1), uint8(31)); mptHistory.loadDate.tm_mon = Clamp(fileHeader.creationMonth, uint8(1), uint8(12)) - 1; mptHistory.loadDate.tm_year = fileHeader.creationYear; m_FileHistory.clear(); m_FileHistory.push_back(mptHistory); // Go through all chunks now ChunkReader chunkFile(file); ChunkReader::ChunkList chunks = chunkFile.ReadChunks(1); FileReader chunk; // Read order list DMFSequence seqHeader; chunk = chunks.GetChunk(DMFChunk::idSEQU); if(!chunk.ReadStruct(seqHeader)) { return false; } ReadOrderFromFile(Order(), chunk, (chunk.GetLength() - sizeof(DMFSequence)) / 2); // Read patterns chunk = chunks.GetChunk(DMFChunk::idPATT); if(chunk.IsValid() && (loadFlags & loadPatternData)) { DMFPatterns patHeader; chunk.ReadStruct(patHeader); m_nChannels = Clamp(patHeader.numTracks, 1, 32) + 1; // + 1 for global track (used for tempo stuff) std::vector patternChunks; patternChunks.reserve(patHeader.numPatterns); // First, find out where all of our patterns are... for(PATTERNINDEX pat = 0; pat < patHeader.numPatterns; pat++) { DMFPatternHeader header; chunk.ReadStruct(header); chunk.SkipBack(sizeof(header)); patternChunks.push_back(chunk.ReadChunk(sizeof(header) + header.patternLength)); } // Now go through the order list and load them. DMFPatternSettings settings(GetNumChannels()); Patterns.ResizeArray(Order().GetLength()); for(ORDERINDEX ord = 0; ord < Order().GetLength(); ord++) { // Create one pattern for each order item, as the same pattern can be played with different settings PATTERNINDEX pat = Order()[ord]; if(pat < patternChunks.size()) { pat = ConvertDMFPattern(patternChunks[pat], settings, *this); Order()[ord] = pat; // Loop end? if(pat != PATTERNINDEX_INVALID && ord == seqHeader.loopEnd && (seqHeader.loopStart > 0 || ord < Order().GetLastIndex())) { Patterns[pat].WriteEffect(EffectWriter(CMD_POSITIONJUMP, static_cast(seqHeader.loopStart)).Row(Patterns[pat].GetNumRows() - 1).RetryPreviousRow()); } } } } // Read song message chunk = chunks.GetChunk(DMFChunk::idCMSG); if(chunk.IsValid()) { // The song message seems to start at a 1 byte offset. // The skipped byte seems to always be 0. // This also matches how XT 1.03 itself displays the song message. chunk.Skip(1); m_songMessage.ReadFixedLineLength(chunk, chunk.GetLength() - 1, 40, 0); } // Read sample headers + data FileReader sampleDataChunk = chunks.GetChunk(DMFChunk::idSMPD); chunk = chunks.GetChunk(DMFChunk::idSMPI); m_nSamples = chunk.ReadUint8(); for(SAMPLEINDEX smp = 1; smp <= GetNumSamples(); smp++) { chunk.ReadSizedString(m_szNames[smp]); DMFSampleHeader sampleHeader; ModSample &sample = Samples[smp]; chunk.ReadStruct(sampleHeader); sampleHeader.ConvertToMPT(sample); if(fileHeader.version >= 8) { // Read library name in version 8 files chunk.ReadString(sample.filename, 8); } // We don't care for the checksum of the sample data... chunk.Skip(sizeof(DMFSampleHeaderTail)); // Now read the sample data from the data chunk FileReader sampleData = sampleDataChunk.ReadChunk(sampleDataChunk.ReadUint32LE()); if(sampleData.IsValid() && (loadFlags & loadSampleData)) { SampleIO( sample.uFlags[CHN_16BIT] ? SampleIO::_16bit : SampleIO::_8bit, SampleIO::mono, SampleIO::littleEndian, (sampleHeader.flags & DMFSampleHeader::smpCompMask) == DMFSampleHeader::smpComp1 ? SampleIO::DMF : SampleIO::signedPCM) .ReadSample(sample, sampleData); } } InitializeChannels(); m_SongFlags = SONG_LINEARSLIDES | SONG_ITCOMPATGXX; // this will be converted to IT format by MPT. SONG_ITOLDEFFECTS is not set because of tremor and vibrato. m_nDefaultSpeed = 6; m_nDefaultTempo.Set(120); m_nDefaultGlobalVolume = 256; m_nSamplePreAmp = m_nVSTiVolume = 48; return true; } /////////////////////////////////////////////////////////////////////// // DMF Compression struct DMFHNode { int16 left, right; uint8 value; }; struct DMFHTree { const uint8 *ibuf, *ibufmax; uint32 bitbuf; int bitnum; int lastnode, nodecount; DMFHNode nodes[256]; // DMF Huffman ReadBits uint8 DMFReadBits(int nbits) { if(bitnum < nbits) { if(ibuf < ibufmax) { bitbuf |= (((uint32)(*ibuf++)) << bitnum); bitnum += 8; } else { throw std::range_error("Truncated DMF sample block"); } } uint8 v = static_cast(bitbuf & ((1 << nbits) - 1)); bitbuf >>= nbits; bitnum -= nbits; return v; } // // tree: [8-bit value][12-bit index][12-bit index] = 32-bit // void DMFNewNode() { uint8 isleft, isright; int actnode; actnode = nodecount; if(actnode > 255) return; nodes[actnode].value = DMFReadBits(7); isleft = DMFReadBits(1); isright = DMFReadBits(1); actnode = lastnode; if(actnode > 255) return; nodecount++; lastnode = nodecount; if(isleft) { nodes[actnode].left = (int16)lastnode; DMFNewNode(); } else { nodes[actnode].left = -1; } lastnode = nodecount; if(isright) { nodes[actnode].right = (int16)lastnode; DMFNewNode(); } else { nodes[actnode].right = -1; } } }; uintptr_t DMFUnpack(uint8 *psample, const uint8 *ibuf, const uint8 *ibufmax, uint32 maxlen) { DMFHTree tree; MemsetZero(tree); tree.ibuf = ibuf; tree.ibufmax = ibufmax; tree.DMFNewNode(); uint8 value = 0, delta = 0; try { for(uint32 i = 0; i < maxlen; i++) { int actnode = 0; uint8 sign = tree.DMFReadBits(1); do { if(tree.DMFReadBits(1)) actnode = tree.nodes[actnode].right; else actnode = tree.nodes[actnode].left; if(actnode > 255) break; delta = tree.nodes[actnode].value; } while((tree.nodes[actnode].left >= 0) && (tree.nodes[actnode].right >= 0)); if(sign) delta ^= 0xFF; value += delta; psample[i] = value; } } catch(const std::range_error &) { //AddToLog(LogWarning, "Truncated DMF sample block"); } return tree.ibuf - ibuf; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Load_dtm.cpp0000644000372100037210000003641613164661650020346 00000000000000/* * Load_dtm.cpp * ------------ * Purpose: Digital Tracker / Digital Home Studio module Loader (DTM) * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" #include "ChunkReader.h" OPENMPT_NAMESPACE_BEGIN enum PatternFormats : uint32 { DTM_PT_PATTERN_FORMAT = 0, DTM_204_PATTERN_FORMAT = MAGIC4BE('2', '.', '0', '4'), DTM_206_PATTERN_FORMAT = MAGIC4BE('2', '.', '0', '6'), }; struct DTMFileHeader { char magic[4]; uint32be headerSize; uint16be type; // 0 = module uint8be stereoMode; // FF = panoramic stereo, 00 = old stereo uint8be bitDepth; // Typically 8, sometimes 16, but is not actually used anywhere? uint16be reserved; // Usually 0, but not in unknown title 1.dtm and unknown title 2.dtm uint16be speed; uint16be tempo; uint32be forcedSampleRate; // Seems to be ignored in newer files }; MPT_BINARY_STRUCT(DTMFileHeader, 22) // IFF-style Chunk struct DTMChunk { // 32-Bit chunk identifiers enum ChunkIdentifiers { idS_Q_ = MAGIC4BE('S', '.', 'Q', '.'), idPATT = MAGIC4BE('P', 'A', 'T', 'T'), idINST = MAGIC4BE('I', 'N', 'S', 'T'), idIENV = MAGIC4BE('I', 'E', 'N', 'V'), idDAPT = MAGIC4BE('D', 'A', 'P', 'T'), idDAIT = MAGIC4BE('D', 'A', 'I', 'T'), idTEXT = MAGIC4BE('T', 'E', 'X', 'T'), idPATN = MAGIC4BE('P', 'A', 'T', 'N'), idTRKN = MAGIC4BE('T', 'R', 'K', 'N'), idVERS = MAGIC4BE('V', 'E', 'R', 'S'), idSV19 = MAGIC4BE('S', 'V', '1', '9'), }; uint32be id; uint32be length; size_t GetLength() const { return length; } ChunkIdentifiers GetID() const { return static_cast(id.get()); } }; MPT_BINARY_STRUCT(DTMChunk, 8) struct DTMSample { uint32be reserved; // 0x204 for first sample, 0x208 for second, etc... uint32be length; // in bytes uint8be finetune; // -8....7 uint8be volume; // 0...64 uint32be loopStart; // in bytes uint32be loopLength; // ditto char name[22]; uint8be stereo; uint8be bitDepth; uint16be transpose; uint16be unknown; uint32be sampleRate; void ConvertToMPT(ModSample &mptSmp, uint32 forcedSampleRate, uint32 formatVersion) const { mptSmp.Initialize(MOD_TYPE_IT); mptSmp.nLength = length; mptSmp.nLoopStart = loopStart; mptSmp.nLoopEnd = mptSmp.nLoopStart + loopLength; // In revolution to come.dtm, the file header says samples rate is 24512 Hz, but samples say it's 50000 Hz // Digital Home Studio ignores the header setting in 2.04-/2.06-style modules mptSmp.nC5Speed = (formatVersion == DTM_PT_PATTERN_FORMAT && forcedSampleRate > 0) ? forcedSampleRate : sampleRate; int32 transposeAmount = MOD2XMFineTune(finetune); if(formatVersion == DTM_206_PATTERN_FORMAT && transpose > 0 && transpose != 48) { // Digital Home Studio applies this unconditionally, but some old songs sound wrong then (delirium.dtm). // Maybe this should not be applied for "real" Digital Tracker modules? transposeAmount += (48 - transpose) * 128; } mptSmp.Transpose(transposeAmount * (1.0 / (12.0 * 128.0))); mptSmp.nVolume = std::min(volume, 64u) * 4u; if(stereo & 1) { mptSmp.uFlags.set(CHN_STEREO); mptSmp.nLength /= 2u; mptSmp.nLoopStart /= 2u; mptSmp.nLoopEnd /= 2u; } if(bitDepth > 8) { mptSmp.uFlags.set(CHN_16BIT); mptSmp.nLength /= 2u; mptSmp.nLoopStart /= 2u; mptSmp.nLoopEnd /= 2u; } if(mptSmp.nLoopEnd > mptSmp.nLoopStart + 1) { mptSmp.uFlags.set(CHN_LOOP); } else { mptSmp.nLoopStart = mptSmp.nLoopEnd = 0; } } }; MPT_BINARY_STRUCT(DTMSample, 50) struct DTMInstrument { uint16be insNum; uint8be unknown1; uint8be envelope; // 0xFF = none uint8be sustain; // 0xFF = no sustain point uint16be fadeout; uint8be vibRate; uint8be vibDepth; uint8be modulationRate; uint8be modulationDepth; uint8be breathRate; uint8be breathDepth; uint8be volumeRate; uint8be volumeDepth; }; MPT_BINARY_STRUCT(DTMInstrument, 15) struct DTMEnvelope { struct DTMEnvPoint { uint8be value; uint8be tick; }; uint16be numPoints; DTMEnvPoint points[16]; }; MPT_BINARY_STRUCT(DTMEnvelope::DTMEnvPoint, 2) MPT_BINARY_STRUCT(DTMEnvelope, 34) struct DTMText { uint16be textType; // 0 = pattern, 1 = free, 2 = song uint32be textLength; uint16be tabWidth; uint16be reserved; uint16be oddLength; }; MPT_BINARY_STRUCT(DTMText, 12) static bool ValidateHeader(const DTMFileHeader &fileHeader) { if(std::memcmp(fileHeader.magic, "D.T.", 4) || fileHeader.headerSize < sizeof(fileHeader) - 8u || fileHeader.headerSize > 256 // Excessively long song title? || fileHeader.type != 0) { return false; } return true; } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderDTM(MemoryFileReader file, const uint64 *pfilesize) { DTMFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return ProbeWantMoreData; } if(!ValidateHeader(fileHeader)) { return ProbeFailure; } MPT_UNREFERENCED_PARAMETER(pfilesize); return ProbeSuccess; } bool CSoundFile::ReadDTM(FileReader &file, ModLoadingFlags loadFlags) { file.Rewind(); DTMFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return false; } if(!ValidateHeader(fileHeader)) { return false; } if(loadFlags == onlyVerifyHeader) { return true; } InitializeGlobals(MOD_TYPE_DTM); InitializeChannels(); m_SongFlags.set(SONG_ITCOMPATGXX | SONG_ITOLDEFFECTS); m_playBehaviour.reset(kITVibratoTremoloPanbrello); // Various files have a default speed or tempo of 0 if(fileHeader.tempo) m_nDefaultTempo.Set(fileHeader.tempo); if(fileHeader.speed) m_nDefaultSpeed = fileHeader.speed; if(fileHeader.stereoMode == 0) SetupMODPanning(true); file.ReadString(m_songName, fileHeader.headerSize - (sizeof(fileHeader) - 8u)); auto chunks = ChunkReader(file).ReadChunks(1); // Read order list if(FileReader chunk = chunks.GetChunk(DTMChunk::idS_Q_)) { uint16 ordLen = chunk.ReadUint16BE(); uint16 restartPos = chunk.ReadUint16BE(); chunk.Skip(4); // Reserved ReadOrderFromFile(Order(), chunk, ordLen); Order().SetRestartPos(restartPos); } else { return false; } // Read pattern properties uint32 patternFormat; if(FileReader chunk = chunks.GetChunk(DTMChunk::idPATT)) { m_nChannels = chunk.ReadUint16BE(); if(m_nChannels < 1 || m_nChannels > 32) { return false; } Patterns.ResizeArray(chunk.ReadUint16BE()); // Number of stored patterns, may be lower than highest pattern number patternFormat = chunk.ReadUint32BE(); if(patternFormat != DTM_PT_PATTERN_FORMAT && patternFormat != DTM_204_PATTERN_FORMAT && patternFormat != DTM_206_PATTERN_FORMAT) { return false; } } else { return false; } // Read global info if(FileReader chunk = chunks.GetChunk(DTMChunk::idSV19)) { chunk.Skip(2); // Ticks per quarter note, typically 24 uint32 fractionalTempo = chunk.ReadUint32BE(); m_nDefaultTempo = TEMPO(m_nDefaultTempo.GetInt() + fractionalTempo / 4294967296.0); uint16be panning[32]; chunk.ReadArray(panning); for(CHANNELINDEX chn = 0; chn < 32 && chn < GetNumChannels(); chn++) { // Panning is in range 0...180, 90 = center ChnSettings[chn].nPan = static_cast(128 + Util::muldivr(std::min(panning[chn], 180) - 90, 128, 90)); } chunk.Skip(146); uint16be volume[32]; if(chunk.ReadArray(volume)) { for(CHANNELINDEX chn = 0; chn < 32 && chn < GetNumChannels(); chn++) { // Volume is in range 0...128, 64 = normal ChnSettings[chn].nVolume = static_cast(std::min(volume[chn], 128) / 2); } m_nSamplePreAmp *= 2; // Compensate for channel volume range } } // Read song message if(FileReader chunk = chunks.GetChunk(DTMChunk::idTEXT)) { DTMText text; chunk.ReadStruct(text); if(text.oddLength == 0xFFFF) { chunk.Skip(1); } m_songMessage.Read(chunk, chunk.BytesLeft(), SongMessage::leCRLF); } // Read sample headers if(FileReader chunk = chunks.GetChunk(DTMChunk::idINST)) { uint16 numSamples = chunk.ReadUint16BE(); bool newSamples = (numSamples >= 0x8000); numSamples &= 0x7FFF; if(numSamples >= MAX_SAMPLES || !chunk.CanRead(numSamples * (sizeof(DTMSample) + (newSamples ? 2u : 0u)))) { return false; } m_nSamples = numSamples; for(SAMPLEINDEX smp = 1; smp <= numSamples; smp++) { SAMPLEINDEX realSample = newSamples ? (chunk.ReadUint16BE() + 1u) : smp; DTMSample dtmSample; chunk.ReadStruct(dtmSample); if(realSample < 1 || realSample >= MAX_SAMPLES) { continue; } m_nSamples = std::max(m_nSamples, realSample); ModSample &mptSmp = Samples[realSample]; dtmSample.ConvertToMPT(mptSmp, fileHeader.forcedSampleRate, patternFormat); mpt::String::Read(m_szNames[realSample], dtmSample.name); } if(chunk.ReadUint16BE() == 0x0004) { // Digital Home Studio instruments m_nInstruments = std::min(m_nSamples, MAX_INSTRUMENTS - 1); FileReader envChunk = chunks.GetChunk(DTMChunk::idIENV); while(chunk.CanRead(sizeof(DTMInstrument))) { DTMInstrument instr; chunk.ReadStruct(instr); if(instr.insNum < GetNumInstruments()) { Samples[instr.insNum + 1].nVibDepth = instr.vibDepth; Samples[instr.insNum + 1].nVibRate = instr.vibRate; Samples[instr.insNum + 1].nVibSweep = 255; ModInstrument *mptIns = AllocateInstrument(instr.insNum + 1, instr.insNum + 1); if(mptIns != nullptr) { InstrumentEnvelope &mptEnv = mptIns->VolEnv; mptIns->nFadeOut = std::min(instr.fadeout, 0xFFF); if(instr.envelope != 0xFF && envChunk.Seek(2 + sizeof(DTMEnvelope) * instr.envelope)) { DTMEnvelope env; envChunk.ReadStruct(env); mptEnv.dwFlags.set(ENV_ENABLED); mptEnv.resize(std::min({ env.numPoints, mpt::size(env.points), MAX_ENVPOINTS })); for(size_t i = 0; i < mptEnv.size(); i++) { mptEnv[i].value = std::min(64, env.points[i].value); mptEnv[i].tick = env.points[i].tick; } if(instr.sustain != 0xFF) { mptEnv.dwFlags.set(ENV_SUSTAIN); mptEnv.nSustainStart = mptEnv.nSustainEnd = instr.sustain; } if(!mptEnv.empty()) { mptEnv.dwFlags.set(ENV_LOOP); mptEnv.nLoopStart = mptEnv.nLoopEnd = static_cast(mptEnv.size() - 1); } } } } } } } // Read pattern data for(auto &chunk : chunks.GetAllChunks(DTMChunk::idDAPT)) { chunk.Skip(4); // FF FF FF FF PATTERNINDEX patNum = chunk.ReadUint16BE(); ROWINDEX numRows = chunk.ReadUint16BE(); if(patternFormat == DTM_206_PATTERN_FORMAT) { // The stored data is actually not row-based, but tick-based. numRows /= m_nDefaultSpeed; } if(!(loadFlags & loadPatternData) || patNum > 255 || !Patterns.Insert(patNum, numRows)) { continue; } if(patternFormat == DTM_206_PATTERN_FORMAT) { chunk.Skip(4); for(CHANNELINDEX chn = 0; chn < GetNumChannels(); chn++) { uint16 length = chunk.ReadUint16BE(); if(length % 2u) length++; FileReader rowChunk = chunk.ReadChunk(length); int tick = 0; std::div_t position = { 0, 0 }; while(rowChunk.CanRead(6) && static_cast(position.quot) < numRows) { ModCommand *m = Patterns[patNum].GetpModCommand(position.quot, chn); uint8 data[6]; rowChunk.ReadArray(data); if(data[0] > 0 && data[0] <= 96) { m->note = data[0] + NOTE_MIN + 12; if(position.rem) { m->command = CMD_MODCMDEX; m->param = 0xD0 | static_cast(std::min(position.rem, 15)); } } else if(data[0] & 0x80) { // Lower 7 bits contain note, probably intended for MIDI-like note-on/note-off events if(position.rem) { m->command = CMD_MODCMDEX; m->param = 0xC0 | static_cast(std::min(position.rem, 15)); } else { m->note = NOTE_NOTECUT; } } if(data[1]) { m->volcmd = VOLCMD_VOLUME; m->vol = std::min(data[1], uint8(64)); // Volume can go up to 255, but we do not support over-amplification at the moment. } if(data[2]) { m->instr = data[2]; } if(data[3] || data[4]) { m->command = data[3]; m->param = data[4]; ConvertModCommand(*m); #ifdef MODPLUG_TRACKER m->Convert(MOD_TYPE_MOD, MOD_TYPE_IT, *this); #endif } if(data[5] & 0x80) tick += (data[5] & 0x7F) * 0x100 + rowChunk.ReadUint8(); else tick += data[5]; position = std::div(tick, m_nDefaultSpeed); } } } else { ModCommand *m = Patterns[patNum].GetpModCommand(0, 0); for(ROWINDEX row = 0; row < numRows; row++) { for(CHANNELINDEX chn = 0; chn < GetNumChannels(); chn++, m++) { uint8 data[4]; chunk.ReadArray(data); if(patternFormat == DTM_204_PATTERN_FORMAT) { if(data[0] > 0 && data[0] < 0x80) { m->note = (data[0] >> 4) * 12 + (data[0] & 0x0F) + NOTE_MIN + 11; } uint8 vol = data[1] >> 2; if(vol) { m->volcmd = VOLCMD_VOLUME; m->vol = vol - 1u; } m->instr = ((data[1] & 0x03) << 4) | (data[2] >> 4); m->command = data[2] & 0x0F; m->param = data[3]; } else { ReadMODPatternEntry(data, *m); m->instr |= data[0] & 0x30; // Allow more than 31 instruments } ConvertModCommand(*m); // Fix commands without memory and slide nibble precedence switch(m->command) { case CMD_PORTAMENTOUP: case CMD_PORTAMENTODOWN: if(!m->param) { m->command = CMD_NONE; } break; case CMD_VOLUMESLIDE: case CMD_TONEPORTAVOL: case CMD_VIBRATOVOL: if(m->param & 0xF0) { m->param &= 0xF0; } else if(!m->param) { m->command = CMD_NONE; } break; default: break; } #ifdef MODPLUG_TRACKER m->Convert(MOD_TYPE_MOD, MOD_TYPE_IT, *this); #endif } } } } // Read pattern names if(FileReader chunk = chunks.GetChunk(DTMChunk::idPATN)) { PATTERNINDEX pat = 0; std::string name; while(chunk.CanRead(1) && pat < Patterns.Size()) { chunk.ReadNullString(name, 32); Patterns[pat].SetName(name); pat++; } } // Read channel names if(FileReader chunk = chunks.GetChunk(DTMChunk::idTRKN)) { CHANNELINDEX chn = 0; std::string name; while(chunk.CanRead(1) && chn < GetNumChannels()) { chunk.ReadNullString(name, 32); mpt::String::Copy(ChnSettings[chn].szName, name); chn++; } } // Read sample data for(auto &chunk : chunks.GetAllChunks(DTMChunk::idDAIT)) { PATTERNINDEX smp = chunk.ReadUint16BE() + 1; if(smp == 0 || smp > GetNumSamples() || !(loadFlags & loadSampleData)) { continue; } ModSample &mptSmp = Samples[smp]; SampleIO( mptSmp.uFlags[CHN_16BIT] ? SampleIO::_16bit : SampleIO::_8bit, mptSmp.uFlags[CHN_STEREO] ? SampleIO::stereoInterleaved: SampleIO::mono, SampleIO::bigEndian, SampleIO::signedPCM).ReadSample(mptSmp, chunk); } // Is this accurate? if(patternFormat == DTM_206_PATTERN_FORMAT) { m_madeWithTracker = MPT_USTRING("Digital Home Studio"); } else if(FileReader chunk = chunks.GetChunk(DTMChunk::idVERS)) { uint32 version = chunk.ReadUint32BE(); m_madeWithTracker = mpt::format(MPT_USTRING("Digital Tracker %1.%2"))(version >> 4, version & 0x0F); } else { m_madeWithTracker = MPT_USTRING("Digital Tracker"); } return true; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/IntMixer.h0000644000372100037210000003057713117471643020030 00000000000000/* * IntMixer.h * ---------- * Purpose: Fixed point mixer classes * Notes : (currently none) * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "Resampler.h" #include "MixerInterface.h" #include "Paula.h" OPENMPT_NAMESPACE_BEGIN template struct IntToIntTraits : public MixerTraits { typedef MixerTraits base_t; typedef typename base_t::input_t input_t; typedef typename base_t::output_t output_t; static MPT_CONSTEXPR11_FUN output_t Convert(const input_t x) { static_assert(std::numeric_limits::is_integer, "Input must be integer"); static_assert(std::numeric_limits::is_integer, "Output must be integer"); static_assert(sizeof(out) * 8 >= mixPrecision, "Mix precision is higher than output type can handle"); static_assert(sizeof(in) * 8 <= mixPrecision, "Mix precision is lower than input type"); return static_cast(x) * (1<<(mixPrecision - sizeof(in) * 8)); } }; typedef IntToIntTraits<2, 1, mixsample_t, int8, 16> Int8MToIntS; typedef IntToIntTraits<2, 1, mixsample_t, int16, 16> Int16MToIntS; typedef IntToIntTraits<2, 2, mixsample_t, int8, 16> Int8SToIntS; typedef IntToIntTraits<2, 2, mixsample_t, int16, 16> Int16SToIntS; ////////////////////////////////////////////////////////////////////////// // Interpolation templates template struct AmigaBlepInterpolation { SamplePosition subIncrement; Paula::State *paula; int numSteps; bool filter; MPT_FORCEINLINE void Start(ModChannel &chn, const CResampler &) { paula = &chn.paulaState; numSteps = paula->numSteps; filter = chn.dwFlags[CHN_AMIGAFILTER]; if(numSteps) subIncrement = chn.increment / paula->numSteps; } MPT_FORCEINLINE void End(const ModChannel &) { } MPT_FORCEINLINE void operator() (typename Traits::outbuf_t &outSample, const typename Traits::input_t * const MPT_RESTRICT inBuffer, const uint32 posLo) { SamplePosition pos(0, posLo); // First, process steps of full length (one Amiga clock interval) for(int step = numSteps; step > 0; step--) { typename Traits::output_t inSample = 0; int32 posInt = pos.GetInt() * Traits::numChannelsIn; for(int32 i = 0; i < Traits::numChannelsIn; i++) inSample += Traits::Convert(inBuffer[posInt + i]); paula->InputSample(static_cast(inSample / (4 * Traits::numChannelsIn))); paula->Clock(Paula::MINIMUM_INTERVAL); pos += subIncrement; } paula->remainder += paula->stepRemainder; // Now, process any remaining integer clock amount < MINIMUM_INTERVAL uint32 remainClocks = paula->remainder.GetInt(); if(remainClocks) { typename Traits::output_t inSample = 0; int32 posInt = pos.GetInt() * Traits::numChannelsIn; for(int32 i = 0; i < Traits::numChannelsIn; i++) inSample += Traits::Convert(inBuffer[posInt + i]); paula->InputSample(static_cast(inSample / (4 * Traits::numChannelsIn))); paula->Clock(remainClocks); paula->remainder.RemoveInt(); } auto out = paula->OutputSample(filter); for(unsigned int i = 0; i < Traits::numChannelsOut; i++) outSample[i] = out; } }; template struct LinearInterpolation { MPT_FORCEINLINE void Start(const ModChannel &, const CResampler &) { } MPT_FORCEINLINE void End(const ModChannel &) { } MPT_FORCEINLINE void operator() (typename Traits::outbuf_t &outSample, const typename Traits::input_t * const MPT_RESTRICT inBuffer, const uint32 posLo) { static_assert(Traits::numChannelsIn <= Traits::numChannelsOut, "Too many input channels"); const typename Traits::output_t fract = posLo >> 18u; for(int i = 0; i < Traits::numChannelsIn; i++) { typename Traits::output_t srcVol = Traits::Convert(inBuffer[i]); typename Traits::output_t destVol = Traits::Convert(inBuffer[i + Traits::numChannelsIn]); outSample[i] = srcVol + ((fract * (destVol - srcVol)) / 16384); } } }; template struct FastSincInterpolation { MPT_FORCEINLINE void Start(const ModChannel &, const CResampler &) { } MPT_FORCEINLINE void End(const ModChannel &) { } MPT_FORCEINLINE void operator() (typename Traits::outbuf_t &outSample, const typename Traits::input_t * const MPT_RESTRICT inBuffer, const uint32 posLo) { static_assert(Traits::numChannelsIn <= Traits::numChannelsOut, "Too many input channels"); const int16 *lut = CResampler::FastSincTable + ((posLo >> 22) & 0x3FC); for(int i = 0; i < Traits::numChannelsIn; i++) { outSample[i] = (lut[0] * Traits::Convert(inBuffer[i - Traits::numChannelsIn]) + lut[1] * Traits::Convert(inBuffer[i]) + lut[2] * Traits::Convert(inBuffer[i + Traits::numChannelsIn]) + lut[3] * Traits::Convert(inBuffer[i + 2 * Traits::numChannelsIn])) / 16384; } } }; template struct PolyphaseInterpolation { const SINC_TYPE *sinc; MPT_FORCEINLINE void Start(const ModChannel &chn, const CResampler &resampler) { #ifdef MODPLUG_TRACKER // Otherwise causes "warning C4100: 'resampler' : unreferenced formal parameter" // because all 3 tables are static members. // #pragma warning fails with this templated case for unknown reasons. MPT_UNREFERENCED_PARAMETER(resampler); #endif // MODPLUG_TRACKER sinc = (((chn.increment > SamplePosition(0x130000000ll)) || (chn.increment < SamplePosition(-0x130000000ll))) ? (((chn.increment > SamplePosition(0x180000000ll)) || (chn.increment < SamplePosition(-0x180000000ll))) ? resampler.gDownsample2x : resampler.gDownsample13x) : resampler.gKaiserSinc); } MPT_FORCEINLINE void End(const ModChannel &) { } MPT_FORCEINLINE void operator() (typename Traits::outbuf_t &outSample, const typename Traits::input_t * const MPT_RESTRICT inBuffer, const uint32 posLo) { static_assert(Traits::numChannelsIn <= Traits::numChannelsOut, "Too many input channels"); const SINC_TYPE *lut = sinc + ((posLo >> (32 - SINC_PHASES_BITS)) & SINC_MASK) * SINC_WIDTH; for(int i = 0; i < Traits::numChannelsIn; i++) { outSample[i] = (lut[0] * Traits::Convert(inBuffer[i - 3 * Traits::numChannelsIn]) + lut[1] * Traits::Convert(inBuffer[i - 2 * Traits::numChannelsIn]) + lut[2] * Traits::Convert(inBuffer[i - Traits::numChannelsIn]) + lut[3] * Traits::Convert(inBuffer[i]) + lut[4] * Traits::Convert(inBuffer[i + Traits::numChannelsIn]) + lut[5] * Traits::Convert(inBuffer[i + 2 * Traits::numChannelsIn]) + lut[6] * Traits::Convert(inBuffer[i + 3 * Traits::numChannelsIn]) + lut[7] * Traits::Convert(inBuffer[i + 4 * Traits::numChannelsIn])) / (1 << SINC_QUANTSHIFT); } } }; template struct FIRFilterInterpolation { const int16 *WFIRlut; MPT_FORCEINLINE void Start(const ModChannel &, const CResampler &resampler) { WFIRlut = resampler.m_WindowedFIR.lut; } MPT_FORCEINLINE void End(const ModChannel &) { } MPT_FORCEINLINE void operator() (typename Traits::outbuf_t &outSample, const typename Traits::input_t * const MPT_RESTRICT inBuffer, const uint32 posLo) { static_assert(Traits::numChannelsIn <= Traits::numChannelsOut, "Too many input channels"); const int16 * const lut = WFIRlut + ((((posLo >> 16) + WFIR_FRACHALVE) >> WFIR_FRACSHIFT) & WFIR_FRACMASK); for(int i = 0; i < Traits::numChannelsIn; i++) { typename Traits::output_t vol1 = (lut[0] * Traits::Convert(inBuffer[i - 3 * Traits::numChannelsIn])) + (lut[1] * Traits::Convert(inBuffer[i - 2 * Traits::numChannelsIn])) + (lut[2] * Traits::Convert(inBuffer[i - Traits::numChannelsIn])) + (lut[3] * Traits::Convert(inBuffer[i])); typename Traits::output_t vol2 = (lut[4] * Traits::Convert(inBuffer[i + 1 * Traits::numChannelsIn])) + (lut[5] * Traits::Convert(inBuffer[i + 2 * Traits::numChannelsIn])) + (lut[6] * Traits::Convert(inBuffer[i + 3 * Traits::numChannelsIn])) + (lut[7] * Traits::Convert(inBuffer[i + 4 * Traits::numChannelsIn])); outSample[i] = ((vol1 / 2) + (vol2 / 2)) / (1 << (WFIR_16BITSHIFT - 1)); } } }; ////////////////////////////////////////////////////////////////////////// // Mixing templates (add sample to stereo mix) template struct NoRamp { typename Traits::output_t lVol, rVol; MPT_FORCEINLINE void Start(const ModChannel &chn) { lVol = chn.leftVol; rVol = chn.rightVol; } MPT_FORCEINLINE void End(const ModChannel &) { } }; struct Ramp { int32 lRamp, rRamp; MPT_FORCEINLINE void Start(const ModChannel &chn) { lRamp = chn.rampLeftVol; rRamp = chn.rampRightVol; } MPT_FORCEINLINE void End(ModChannel &chn) { chn.rampLeftVol = lRamp; chn.leftVol = lRamp >> VOLUMERAMPPRECISION; chn.rampRightVol = rRamp; chn.rightVol = rRamp >> VOLUMERAMPPRECISION; } }; // Legacy optimization: If chn.nLeftVol == chn.nRightVol, save one multiplication instruction template struct MixMonoFastNoRamp : public NoRamp { typedef NoRamp base_t; MPT_FORCEINLINE void operator() (const typename Traits::outbuf_t &outSample, const ModChannel &, typename Traits::output_t * const MPT_RESTRICT outBuffer) { typename Traits::output_t vol = outSample[0] * base_t::lVol; for(int i = 0; i < Traits::numChannelsOut; i++) { outBuffer[i] += vol; } } }; template struct MixMonoNoRamp : public NoRamp { typedef NoRamp base_t; MPT_FORCEINLINE void operator() (const typename Traits::outbuf_t &outSample, const ModChannel &, typename Traits::output_t * const MPT_RESTRICT outBuffer) { outBuffer[0] += outSample[0] * base_t::lVol; outBuffer[1] += outSample[0] * base_t::rVol; } }; template struct MixMonoRamp : public Ramp { MPT_FORCEINLINE void operator() (const typename Traits::outbuf_t &outSample, const ModChannel &chn, typename Traits::output_t * const MPT_RESTRICT outBuffer) { lRamp += chn.leftRamp; rRamp += chn.rightRamp; outBuffer[0] += outSample[0] * (lRamp >> VOLUMERAMPPRECISION); outBuffer[1] += outSample[0] * (rRamp >> VOLUMERAMPPRECISION); } }; template struct MixStereoNoRamp : public NoRamp { typedef NoRamp base_t; MPT_FORCEINLINE void operator() (const typename Traits::outbuf_t &outSample, const ModChannel &, typename Traits::output_t * const MPT_RESTRICT outBuffer) { outBuffer[0] += outSample[0] * base_t::lVol; outBuffer[1] += outSample[1] * base_t::rVol; } }; template struct MixStereoRamp : public Ramp { MPT_FORCEINLINE void operator() (const typename Traits::outbuf_t &outSample, const ModChannel &chn, typename Traits::output_t * const MPT_RESTRICT outBuffer) { lRamp += chn.leftRamp; rRamp += chn.rightRamp; outBuffer[0] += outSample[0] * (lRamp >> VOLUMERAMPPRECISION); outBuffer[1] += outSample[1] * (rRamp >> VOLUMERAMPPRECISION); } }; ////////////////////////////////////////////////////////////////////////// // Filter templates template struct NoFilter { MPT_FORCEINLINE void Start(const ModChannel &) { } MPT_FORCEINLINE void End(const ModChannel &) { } MPT_FORCEINLINE void operator() (const typename Traits::outbuf_t &, const ModChannel &) { } }; // Resonant filter template struct ResonantFilter { // Filter history typename Traits::output_t fy[Traits::numChannelsIn][2]; MPT_FORCEINLINE void Start(const ModChannel &chn) { for(int i = 0; i < Traits::numChannelsIn; i++) { fy[i][0] = chn.nFilter_Y[i][0]; fy[i][1] = chn.nFilter_Y[i][1]; } } MPT_FORCEINLINE void End(ModChannel &chn) { for(int i = 0; i < Traits::numChannelsIn; i++) { chn.nFilter_Y[i][0] = fy[i][0]; chn.nFilter_Y[i][1] = fy[i][1]; } } // Filter values are clipped to double the input range #define ClipFilter(x) Clamp(x, int16_min * 2, int16_max * 2) MPT_FORCEINLINE void operator() (typename Traits::outbuf_t &outSample, const ModChannel &chn) { static_assert(Traits::numChannelsIn <= Traits::numChannelsOut, "Too many input channels"); for(int i = 0; i < Traits::numChannelsIn; i++) { typename Traits::output_t val = static_cast(( Util::mul32to64(outSample[i], chn.nFilter_A0) + Util::mul32to64(ClipFilter(fy[i][0]), chn.nFilter_B0) + Util::mul32to64(ClipFilter(fy[i][1]), chn.nFilter_B1) + (1 << (MIXING_FILTER_PRECISION - 1))) / (1 << MIXING_FILTER_PRECISION)); fy[i][1] = fy[i][0]; fy[i][0] = val - (outSample[i] & chn.nFilter_HP); outSample[i] = val; } } #undef ClipFilter }; OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/AudioCriticalSection.cpp0000644000372100037210000000236113127442605022650 00000000000000/* * AudioCriticalSection.cpp * ----------- * Purpose: Implementation of OpenMPT's critical section for access to CSoundFile. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "AudioCriticalSection.h" #if defined(MODPLUG_TRACKER) #include "../common/mptMutex.h" #endif OPENMPT_NAMESPACE_BEGIN #if defined(MODPLUG_TRACKER) CriticalSection::CriticalSection() : m_refGlobalMutex(Tracker::GetGlobalMutexRef()) , inSection(false) { Enter(); } CriticalSection::CriticalSection(CriticalSection &&other) : m_refGlobalMutex(other.m_refGlobalMutex) , inSection(other.inSection) { other.inSection = false; } CriticalSection::CriticalSection(InitialState state) : m_refGlobalMutex(Tracker::GetGlobalMutexRef()) , inSection(false) { if(state == InitialLocked) { Enter(); } } void CriticalSection::Enter() { if(!inSection) { inSection = true; m_refGlobalMutex.lock(); } } void CriticalSection::Leave() { if(inSection) { inSection = false; m_refGlobalMutex.unlock(); } } CriticalSection::~CriticalSection() { Leave(); } #else MPT_MSVC_WORKAROUND_LNK4221(AudioCriticalSection) #endif OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Load_sfx.cpp0000644000372100037210000002406513161656666020367 00000000000000/* * Load_sfx.cpp * ------------ * Purpose: SFX / MMS (SoundFX / MultiMedia Sound) module loader * Notes : Mostly based on the Soundtracker loader, some effect behavior is based on Flod's implementation. * Authors: Devin Acker * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" #include "Tables.h" OPENMPT_NAMESPACE_BEGIN // File Header struct SFXFileHeader { uint8be numOrders; uint8be restartPos; uint8be orderList[128]; }; MPT_BINARY_STRUCT(SFXFileHeader, 130) // Sample Header struct SFXSampleHeader { char name[22]; char dummy[2]; // Supposedly sample length, but almost always incorrect uint8be finetune; uint8be volume; uint16be loopStart; uint16be loopLength; // Convert an MOD sample header to OpenMPT's internal sample header. void ConvertToMPT(ModSample &mptSmp, uint32 length) const { mptSmp.Initialize(MOD_TYPE_MOD); mptSmp.nLength = length; mptSmp.nFineTune = MOD2XMFineTune(finetune); mptSmp.nVolume = 4u * std::min(volume, 64); SmpLength lStart = loopStart; SmpLength lLength = loopLength * 2u; if(mptSmp.nLength) { mptSmp.nLoopStart = lStart; mptSmp.nLoopEnd = lStart + lLength; if(mptSmp.nLoopStart >= mptSmp.nLength) { mptSmp.nLoopStart = mptSmp.nLength - 1; } if(mptSmp.nLoopEnd > mptSmp.nLength) { mptSmp.nLoopEnd = mptSmp.nLength; } if(mptSmp.nLoopStart > mptSmp.nLoopEnd || mptSmp.nLoopEnd < 4 || mptSmp.nLoopEnd - mptSmp.nLoopStart < 4) { mptSmp.nLoopStart = 0; mptSmp.nLoopEnd = 0; } if(mptSmp.nLoopEnd > mptSmp.nLoopStart) { mptSmp.uFlags.set(CHN_LOOP); } } } }; MPT_BINARY_STRUCT(SFXSampleHeader, 30) static uint8 ClampSlideParam(uint8 value, uint8 lowNote, uint8 highNote) { uint16 lowPeriod, highPeriod; if(lowNote < highNote && lowNote >= 36 + NOTE_MIN && highNote >= 36 + NOTE_MIN && lowNote < CountOf(ProTrackerPeriodTable) + 36 + NOTE_MIN && highNote < CountOf(ProTrackerPeriodTable) + 36 + NOTE_MIN) { lowPeriod = ProTrackerPeriodTable[lowNote - 36 - NOTE_MIN]; highPeriod = ProTrackerPeriodTable[highNote - 36 - NOTE_MIN]; // with a fixed speed of 6 ticks/row, and excluding the first row, // 1xx/2xx param has a max value of (low-high)/5 to avoid sliding too far return std::min(value, static_cast((lowPeriod - highPeriod) / 5)); } return 0; } static bool ValidateHeader(const SFXFileHeader &fileHeader) { if(fileHeader.numOrders > 128) { return false; } return true; } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderSFX(MemoryFileReader file, const uint64 *pfilesize) { SAMPLEINDEX numSamples = 0; if(numSamples == 0) { file.Rewind(); if(!file.CanRead(0x40)) { return ProbeWantMoreData; } if(file.Seek(0x3c) && file.ReadMagic("SONG")) { numSamples = 15; } } if(numSamples == 0) { file.Rewind(); if(!file.CanRead(0x80)) { return ProbeWantMoreData; } if(file.Seek(0x7c) && file.ReadMagic("SO31")) { numSamples = 31; } } if(numSamples == 0) { return ProbeFailure; } file.Rewind(); for(SAMPLEINDEX smp = 0; smp < numSamples; smp++) { if(file.ReadUint32BE() > 131072) { return ProbeFailure; } } file.Skip(4); if(!file.CanRead(2)) { return ProbeWantMoreData; } uint16 speed = file.ReadUint16BE(); if(speed < 178) { return ProbeFailure; } if(!file.CanRead(sizeof(SFXSampleHeader) * numSamples)) { return ProbeWantMoreData; } file.Skip(sizeof(SFXSampleHeader) * numSamples); SFXFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return ProbeWantMoreData; } if(!ValidateHeader(fileHeader)) { return ProbeFailure; } MPT_UNREFERENCED_PARAMETER(pfilesize); return ProbeSuccess; } bool CSoundFile::ReadSFX(FileReader &file, ModLoadingFlags loadFlags) { if(file.Seek(0x3C), file.ReadMagic("SONG")) { InitializeGlobals(MOD_TYPE_SFX); m_nSamples = 15; } else if(file.Seek(0x7C), file.ReadMagic("SO31")) { InitializeGlobals(MOD_TYPE_SFX); m_nSamples = 31; } else { return false; } uint32 sampleLen[31]; file.Rewind(); for(SAMPLEINDEX smp = 0; smp < m_nSamples; smp++) { sampleLen[smp] = file.ReadUint32BE(); if(sampleLen[smp] > 131072) return false; } m_nChannels = 4; m_nInstruments = 0; m_nDefaultSpeed = 6; m_nMinPeriod = 14 * 4; m_nMaxPeriod = 3424 * 4; m_nSamplePreAmp = 64; // Setup channel pan positions and volume SetupMODPanning(true); m_playBehaviour.set(kMODIgnorePanning); file.Skip(4); uint16 speed = file.ReadUint16BE(); if(speed < 178) return false; m_nDefaultTempo = TEMPO((14565.0 * 122.0) / speed); file.Skip(14); uint32 invalidChars = 0; for(SAMPLEINDEX smp = 1; smp <= m_nSamples; smp++) { SFXSampleHeader sampleHeader; file.ReadStruct(sampleHeader); sampleHeader.ConvertToMPT(Samples[smp], sampleLen[smp - 1]); // Get rid of weird characters in sample names. for(uint32 i = 0; i < CountOf(sampleHeader.name); i++) { if(sampleHeader.name[i] > 0 && sampleHeader.name[i] < ' ') { sampleHeader.name[i] = ' '; invalidChars++; } } if(invalidChars >= 128) return false; mpt::String::Read(m_szNames[smp], sampleHeader.name); } SFXFileHeader fileHeader; if(!file.ReadStruct(fileHeader)) { return false; } if(!ValidateHeader(fileHeader)) { return false; } if(loadFlags == onlyVerifyHeader) { return true; } PATTERNINDEX numPatterns = 0; for(ORDERINDEX ord = 0; ord < fileHeader.numOrders; ord++) { numPatterns = std::max(numPatterns, fileHeader.orderList[ord] + 1u); } if(fileHeader.restartPos < fileHeader.numOrders) Order().SetRestartPos(fileHeader.restartPos); else Order().SetRestartPos(0); ReadOrderFromArray(Order(), fileHeader.orderList, fileHeader.numOrders); // SFX v2 / MMS modules have 4 extra bytes here for some reason if(m_nSamples == 31) file.Skip(4); uint8 lastNote[4] = {0}; uint8 slideTo[4] = {0}; uint8 slideRate[4] = {0}; // Reading patterns if(loadFlags & loadPatternData) Patterns.ResizeArray(numPatterns); for(PATTERNINDEX pat = 0; pat < numPatterns; pat++) { if(!(loadFlags & loadPatternData) || !Patterns.Insert(pat, 64)) { file.Skip(64 * 4 * 4); continue; } for(ROWINDEX row = 0; row < 64; row++) { PatternRow rowBase = Patterns[pat].GetpModCommand(row, 0); for(CHANNELINDEX chn = 0; chn < 4; chn++) { ModCommand &m = rowBase[chn]; uint8 data[4]; file.ReadArray(data); if(data[0] == 0xFF) { lastNote[chn] = slideRate[chn] = 0; switch(data[1]) { case 0xFE: // STP (note cut) m.command = CMD_VOLUME; continue; case 0xFD: // PIC (null) continue; case 0xFC: // BRK (pattern break) m.command = CMD_PATTERNBREAK; continue; } } ReadMODPatternEntry(data, m); if(m.note != NOTE_NONE) { lastNote[chn] = m.note; slideRate[chn] = 0; } if(m.command || m.param) { switch(m.command) { case 0x1: // arpeggio m.command = CMD_ARPEGGIO; break; case 0x2: // portamento (like Ultimate Soundtracker) if(m.param & 0xF0) { m.command = CMD_PORTAMENTODOWN; m.param >>= 4; } else if(m.param & 0xF) { m.command = CMD_PORTAMENTOUP; m.param &= 0x0F; } else { m.command = m.param = 0; } break; case 0x3: // enable filter/LED // give precedence to 7xy/8xy slides if(slideRate[chn]) { m.command = m.param = 0; break; } m.command = CMD_MODCMDEX; m.param = 0; break; case 0x4: // disable filter/LED // give precedence to 7xy/8xy slides if(slideRate[chn]) { m.command = m.param = 0; break; } m.command = CMD_MODCMDEX; m.param = 1; break; case 0x5: // increase volume if(m.instr) { m.command = CMD_VOLUME; m.param = std::min(ModCommand::PARAM(0x3F), static_cast((Samples[m.instr].nVolume / 4u) + m.param)); // give precedence to 7xy/8xy slides (and move this to the volume column) if(slideRate[chn]) { m.volcmd = VOLCMD_VOLUME; m.vol = m.param; m.command = m.param = 0; break; } } else { m.command = m.param = 0; } break; case 0x6: // decrease volume if(m.instr) { m.command = CMD_VOLUME; if((Samples[m.instr].nVolume / 4u) >= m.param) m.param = static_cast(Samples[m.instr].nVolume / 4u) - m.param; else m.param = 0; // give precedence to 7xy/8xy slides (and move this to the volume column) if(slideRate[chn]) { m.volcmd = VOLCMD_VOLUME; m.vol = m.param; m.command = m.param = 0; break; } } else { m.command = m.param = 0; } break; case 0x7: // 7xy: slide down x semitones at speed y slideTo[chn] = lastNote[chn] - (m.param >> 4); m.command = CMD_PORTAMENTODOWN; slideRate[chn] = m.param & 0xF; m.param = ClampSlideParam(slideRate[chn], slideTo[chn], lastNote[chn]); break; case 0x8: // 8xy: slide up x semitones at speed y slideTo[chn] = lastNote[chn] + (m.param >> 4); m.command = CMD_PORTAMENTOUP; slideRate[chn] = m.param & 0xF; m.param = ClampSlideParam(slideRate[chn], lastNote[chn], slideTo[chn]); break; default: m.command = CMD_NONE; break; } } // continue 7xy/8xy slides if needed if(m.command == CMD_NONE && slideRate[chn]) { if(slideTo[chn]) { m.note = lastNote[chn] = slideTo[chn]; m.param = slideRate[chn]; slideTo[chn] = 0; } m.command = CMD_TONEPORTAMENTO; } } } } // Reading samples if(loadFlags & loadSampleData) { for(SAMPLEINDEX smp = 1; smp <= m_nSamples; smp++) if(Samples[smp].nLength) { SampleIO( SampleIO::_8bit, SampleIO::mono, SampleIO::littleEndian, SampleIO::signedPCM) .ReadSample(Samples[smp], file); } } return true; } OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Tables.h0000644000372100037210000000243413062355670017472 00000000000000/* * Tables.h * -------- * Purpose: Effect, interpolation, data and other pre-calculated tables. * Notes : (currently none) * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once OPENMPT_NAMESPACE_BEGIN extern const char NoteNamesSharp[12][4]; extern const char NoteNamesFlat[12][4]; extern const uint8 ImpulseTrackerPortaVolCmd[16]; extern const uint16 ProTrackerPeriodTable[6*12]; extern const uint16 ProTrackerTunedPeriods[16*12]; extern const uint8 ModEFxTable[16]; extern const uint16 FreqS3MTable[16]; extern const uint16 S3MFineTuneTable[16]; extern const int8 ModSinusTable[64]; extern const int8 ModRandomTable[64]; extern const int8 ITSinusTable[256]; extern const int8 retrigTable1[16]; extern const int8 retrigTable2[16]; extern const uint16 XMPeriodTable[104]; extern const uint32 XMLinearTable[768]; extern const int8 ft2VibratoTable[256]; extern const uint32 FineLinearSlideUpTable[16]; extern const uint32 FineLinearSlideDownTable[16]; extern const uint32 LinearSlideUpTable[256]; extern const uint32 LinearSlideDownTable[256]; extern const uint16 XMPanningTable[256]; extern const uint8 AutoVibratoIT2XM[8]; extern const uint8 AutoVibratoXM2IT[8]; OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Load_mod.cpp0000644000372100037210000021421613226232541020325 00000000000000/* * Load_mod.cpp * ------------ * Purpose: MOD / NST (ProTracker / NoiseTracker), M15 / STK (Ultimate Soundtracker / Soundtracker) and ST26 (SoundTracker 2.6 / Ice Tracker) module loader / saver * Notes : "2000 LOC for processing MOD files?!" you say? Well, this file also contains loaders for some formats that are almost identical to MOD, and extensive * heuristics for more or less broken MOD files and files saved with tons of different trackers, to allow for the most optimal playback. * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Loaders.h" #include "Tables.h" #ifndef MODPLUG_NO_FILESAVE #include "../common/mptFileIO.h" #endif #ifdef MPT_EXTERNAL_SAMPLES // For loading external data in Startrekker files #include "../common/mptPathString.h" #endif // MPT_EXTERNAL_SAMPLES OPENMPT_NAMESPACE_BEGIN void CSoundFile::ConvertModCommand(ModCommand &m) { switch(m.command) { case 0x00: if(m.param) m.command = CMD_ARPEGGIO; break; case 0x01: m.command = CMD_PORTAMENTOUP; break; case 0x02: m.command = CMD_PORTAMENTODOWN; break; case 0x03: m.command = CMD_TONEPORTAMENTO; break; case 0x04: m.command = CMD_VIBRATO; break; case 0x05: m.command = CMD_TONEPORTAVOL; break; case 0x06: m.command = CMD_VIBRATOVOL; break; case 0x07: m.command = CMD_TREMOLO; break; case 0x08: m.command = CMD_PANNING8; break; case 0x09: m.command = CMD_OFFSET; break; case 0x0A: m.command = CMD_VOLUMESLIDE; break; case 0x0B: m.command = CMD_POSITIONJUMP; break; case 0x0C: m.command = CMD_VOLUME; break; case 0x0D: m.command = CMD_PATTERNBREAK; m.param = ((m.param >> 4) * 10) + (m.param & 0x0F); break; case 0x0E: m.command = CMD_MODCMDEX; break; case 0x0F: // For a very long time, this code imported 0x20 as CMD_SPEED for MOD files, but this seems to contradict // pretty much the majority of other MOD player out there. // 0x20 is Speed: Impulse Tracker, Scream Tracker, old ModPlug // 0x20 is Tempo: ProTracker, XMPlay, Imago Orpheus, Cubic Player, ChibiTracker, BeRoTracker, DigiTrakker, DigiTrekker, Disorder Tracker 2, DMP, Extreme's Tracker, ... if(m.param < 0x20) m.command = CMD_SPEED; else m.command = CMD_TEMPO; break; // Extension for XM extended effects case 'G' - 55: m.command = CMD_GLOBALVOLUME; break; //16 case 'H' - 55: m.command = CMD_GLOBALVOLSLIDE; break; case 'K' - 55: m.command = CMD_KEYOFF; break; case 'L' - 55: m.command = CMD_SETENVPOSITION; break; case 'M' - 55: m.command = CMD_CHANNELVOLUME; break; // Wat. Luckily, MPT never allowed this to be entered in patterns... case 'N' - 55: m.command = CMD_CHANNELVOLSLIDE; break; // Ditto. case 'P' - 55: m.command = CMD_PANNINGSLIDE; break; case 'R' - 55: m.command = CMD_RETRIG; break; case 'T' - 55: m.command = CMD_TREMOR; break; case 'X' - 55: m.command = CMD_XFINEPORTAUPDOWN; break; case 'Y' - 55: m.command = CMD_PANBRELLO; break; //34 case 'Z' - 55: m.command = CMD_MIDI; break; //35 case '\\' - 56: m.command = CMD_SMOOTHMIDI; break; //rewbs.smoothVST: 36 - note: this is actually displayed as "-" in FT2, but seems to be doing nothing. //case ':' - 21: m.command = CMD_DELAYCUT; break; //37 case '#' + 3: m.command = CMD_XPARAM; break; //rewbs.XMfixes - Xm.param is 38 default: m.command = CMD_NONE; } } #ifndef MODPLUG_NO_FILESAVE void CSoundFile::ModSaveCommand(uint8 &command, uint8 ¶m, bool toXM, bool compatibilityExport) const { switch(command) { case CMD_NONE: command = param = 0; break; case CMD_ARPEGGIO: command = 0; break; case CMD_PORTAMENTOUP: if (GetType() & (MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_STM|MOD_TYPE_MPT)) { if ((param & 0xF0) == 0xE0) { command = 0x0E; param = ((param & 0x0F) >> 2) | 0x10; break; } else if ((param & 0xF0) == 0xF0) { command = 0x0E; param &= 0x0F; param |= 0x10; break; } } command = 0x01; break; case CMD_PORTAMENTODOWN: if(GetType() & (MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_STM|MOD_TYPE_MPT)) { if ((param & 0xF0) == 0xE0) { command = 0x0E; param= ((param & 0x0F) >> 2) | 0x20; break; } else if ((param & 0xF0) == 0xF0) { command = 0x0E; param &= 0x0F; param |= 0x20; break; } } command = 0x02; break; case CMD_TONEPORTAMENTO: command = 0x03; break; case CMD_VIBRATO: command = 0x04; break; case CMD_TONEPORTAVOL: command = 0x05; break; case CMD_VIBRATOVOL: command = 0x06; break; case CMD_TREMOLO: command = 0x07; break; case CMD_PANNING8: command = 0x08; if(m_nType & MOD_TYPE_S3M) { if(param <= 0x80) { param = MIN(param << 1, 0xFF); } else if(param == 0xA4) // surround { if(compatibilityExport || !toXM) { command = param = 0; } else { command = 'X' - 55; param = 91; } } } break; case CMD_OFFSET: command = 0x09; break; case CMD_VOLUMESLIDE: command = 0x0A; break; case CMD_POSITIONJUMP: command = 0x0B; break; case CMD_VOLUME: command = 0x0C; break; case CMD_PATTERNBREAK: command = 0x0D; param = ((param / 10) << 4) | (param % 10); break; case CMD_MODCMDEX: command = 0x0E; break; case CMD_SPEED: command = 0x0F; param = std::min(param, 0x1F); break; case CMD_TEMPO: command = 0x0F; param = std::max(param, 0x20); break; case CMD_GLOBALVOLUME: command = 'G' - 55; break; case CMD_GLOBALVOLSLIDE: command = 'H' - 55; break; case CMD_KEYOFF: command = 'K' - 55; break; case CMD_SETENVPOSITION: command = 'L' - 55; break; case CMD_PANNINGSLIDE: command = 'P' - 55; break; case CMD_RETRIG: command = 'R' - 55; break; case CMD_TREMOR: command = 'T' - 55; break; case CMD_XFINEPORTAUPDOWN: command = 'X' - 55; if(compatibilityExport && param >= 0x30) // X1x and X2x are legit, everything above are MPT extensions, which don't belong here. param = 0; // Don't set command to 0 to indicate that there *was* some X command here... break; case CMD_PANBRELLO: if(compatibilityExport) command = param = 0; else command = 'Y' - 55; break; case CMD_MIDI: if(compatibilityExport) command = param = 0; else command = 'Z' - 55; break; case CMD_SMOOTHMIDI: //rewbs.smoothVST: 36 if(compatibilityExport) command = param = 0; else command = '\\' - 56; break; case CMD_XPARAM: //rewbs.XMfixes - XParam is 38 if(compatibilityExport) command = param = 0; else command = '#' + 3; break; case CMD_S3MCMDEX: switch(param & 0xF0) { case 0x10: command = 0x0E; param = (param & 0x0F) | 0x30; break; case 0x20: command = 0x0E; param = (param & 0x0F) | 0x50; break; case 0x30: command = 0x0E; param = (param & 0x0F) | 0x40; break; case 0x40: command = 0x0E; param = (param & 0x0F) | 0x70; break; case 0x90: if(compatibilityExport) command = param = 0; else command = 'X' - 55; break; case 0xB0: command = 0x0E; param = (param & 0x0F) | 0x60; break; case 0xA0: case 0x50: case 0x70: case 0x60: command = param = 0; break; default: command = 0x0E; break; } break; default: command = param = 0; } // Don't even think about saving XM effects in MODs... if(command > 0x0F && !toXM) { command = param = 0; } } #endif // MODPLUG_NO_FILESAVE // File Header struct MODFileHeader { uint8be numOrders; uint8be restartPos; uint8be orderList[128]; }; MPT_BINARY_STRUCT(MODFileHeader, 130) // Sample Header struct MODSampleHeader { char name[22]; uint16be length; uint8be finetune; uint8be volume; uint16be loopStart; uint16be loopLength; // Convert an MOD sample header to OpenMPT's internal sample header. void ConvertToMPT(ModSample &mptSmp, bool is4Chn) const { mptSmp.Initialize(MOD_TYPE_MOD); mptSmp.nLength = length * 2; mptSmp.nFineTune = MOD2XMFineTune(finetune & 0x0F); mptSmp.nVolume = 4u * std::min(volume, 64); SmpLength lStart = loopStart * 2; SmpLength lLength = loopLength * 2; // See if loop start is incorrect as words, but correct as bytes (like in Soundtracker modules) if(lLength > 2 && (lStart + lLength > mptSmp.nLength) && (lStart / 2 + lLength <= mptSmp.nLength)) { lStart /= 2; } if(mptSmp.nLength == 2) { mptSmp.nLength = 0; } if(mptSmp.nLength) { mptSmp.nLoopStart = lStart; mptSmp.nLoopEnd = lStart + lLength; if(mptSmp.nLoopStart >= mptSmp.nLength) { mptSmp.nLoopStart = mptSmp.nLength - 1; } if(mptSmp.nLoopStart > mptSmp.nLoopEnd || mptSmp.nLoopEnd < 4 || mptSmp.nLoopEnd - mptSmp.nLoopStart < 4) { mptSmp.nLoopStart = 0; mptSmp.nLoopEnd = 0; } // Fix for most likely broken sample loops. This fixes super_sufm_-_new_life.mod (M.K.) which has a long sample which is looped from 0 to 4. // This module also has notes outside of the Amiga frequency range, so we cannot say that it should be played using ProTracker one-shot loops. // On the other hand, "Crew Generation" by Necros (6CHN) has a sample with a similar loop, which is supposed to be played. // To be able to correctly play both modules, we will draw a somewhat arbitrary line here and trust the loop points in MODs with more than // 4 channels, even if they are tiny and at the very beginning of the sample. if(mptSmp.nLoopEnd <= 8 && mptSmp.nLoopStart == 0 && mptSmp.nLength > mptSmp.nLoopEnd && is4Chn) { mptSmp.nLoopEnd = 0; } if(mptSmp.nLoopEnd > mptSmp.nLoopStart) { mptSmp.uFlags.set(CHN_LOOP); } } } // Convert OpenMPT's internal sample header to a MOD sample header. SmpLength ConvertToMOD(const ModSample &mptSmp) { SmpLength writeLength = mptSmp.pSample != nullptr ? mptSmp.nLength : 0; // If the sample size is odd, we have to add a padding byte, as all sample sizes in MODs are even. if((writeLength % 2u) != 0) { writeLength++; } LimitMax(writeLength, SmpLength(0x1FFFE)); length = static_cast(writeLength / 2u); if(mptSmp.RelativeTone < 0) { finetune = 0x08; } else if(mptSmp.RelativeTone > 0) { finetune = 0x07; } else { finetune = XM2MODFineTune(mptSmp.nFineTune); } volume = static_cast(mptSmp.nVolume / 4u); loopStart = 0; loopLength = 1; if(mptSmp.uFlags[CHN_LOOP] && (mptSmp.nLoopStart + 2u) < writeLength) { const SmpLength loopEnd = Clamp(mptSmp.nLoopEnd, (mptSmp.nLoopStart & ~1) + 2u, writeLength) & ~1; loopStart = static_cast(mptSmp.nLoopStart / 2u); loopLength = static_cast((loopEnd - (mptSmp.nLoopStart & ~1)) / 2u); } return writeLength; } // Compute a "rating" of this sample header by counting invalid header data to ultimately reject garbage files. uint32 GetInvalidByteScore() const { return ((volume > 64) ? 1 : 0) + ((finetune > 15) ? 1 : 0) + ((loopStart > length * 2) ? 1 : 0); } // Suggested threshold for rejecting invalid files based on cumulated score returned by GetInvalidByteScore static const uint32 INVALID_BYTE_THRESHOLD = 40; // This threshold is used for files where the file magic only gives a // fragile result which alone would lead to too many false positives. // In particular, the files from Inconexia demo by Iguana // (https://www.pouet.net/prod.php?which=830) which have 3 \0 bytes in // the file magic tend to cause misdetection of random files. static const uint32 INVALID_BYTE_FRAGILE_THRESHOLD = 1; // Retrieve the internal sample format flags for this sample. static SampleIO GetSampleFormat() { return SampleIO( SampleIO::_8bit, SampleIO::mono, SampleIO::bigEndian, SampleIO::signedPCM); } }; MPT_BINARY_STRUCT(MODSampleHeader, 30) // Synthesized StarTrekker instruments struct AMInstrument { char am[2]; // "AM" char zero[4]; uint16be startLevel; // Start level uint16be attack1Level; // Attack 1 level uint16be attack1Speed; // Attack 1 speed uint16be attack2Level; // Attack 2 level uint16be attack2Speed; // Attack 2 speed uint16be sustainLevel; // Sustain level uint16be decaySpeed; // Decay speed uint16be sustainTime; // Sustain time uint16be nt; // ? uint16be releaseSpeed; // Release speed uint16be waveform; // Waveform int16be pitchFall; // Pitch fall uint16be vibAmp; // Vibrato amplitude uint16be vibSpeed; // Vibrato speed uint16be octave; // Base frequency void ConvertToMPT(ModSample &sample, ModInstrument &ins, mpt::fast_prng &rng) const { sample.nLength = waveform == 3 ? 1024 : 32; sample.nLoopStart = 0; sample.nLoopEnd = sample.nLength; sample.uFlags.set(CHN_LOOP); sample.nVolume = 256; // prelude.mod has volume 0 in sample header sample.nVibDepth = mpt::saturate_cast(vibAmp * 2); sample.nVibRate = static_cast(vibSpeed); sample.nVibType = VIB_SINE; sample.RelativeTone = static_cast(-12 * octave); if(sample.AllocateSample()) { for(SmpLength i = 0; i < sample.nLength; i++) { switch(waveform) { default: case 0: sample.pSample8[i] = ModSinusTable[i * 2]; break; // Sine case 1: sample.pSample8[i] = static_cast(-128 + i * 8); break; // Saw case 2: sample.pSample8[i] = i < 16 ? -128 : 127; break; // Square case 3: sample.pSample8[i] = mpt::random(rng); break; // Noise } } } InstrumentEnvelope &volEnv = ins.VolEnv; volEnv.dwFlags.set(ENV_ENABLED); volEnv.reserve(6); volEnv.push_back(0, static_cast(startLevel / 4)); const struct { uint16 level, speed; } points[] = { { startLevel, 0 }, { attack1Level, attack1Speed }, { attack2Level, attack2Speed }, { sustainLevel, decaySpeed }, { sustainLevel, sustainTime }, { 0, releaseSpeed } }; for(uint8 i = 1; i < CountOf(points); i++) { int duration = std::min(points[i].speed, uint16(256)); // Sustain time is already in ticks, no need to compute the segment duration. if(i != 4) { if(duration == 0) { volEnv.dwFlags.set(ENV_LOOP); volEnv.nLoopStart = volEnv.nLoopEnd = static_cast(volEnv.size() - 1); break; } // Startrekker increments / decrements the envelope level by the stage speed // until it reaches the next stage level. int a, b; if(points[i].level > points[i - 1].level) { a = points[i].level - points[i - 1].level; b = 256 - points[i - 1].level; } else { a = points[i - 1].level - points[i].level; b = points[i - 1].level; } // Release time is again special. if(i == 5) b = 256; else if(b == 0) b = 1; duration = std::max((256 * a) / (duration * b), 1); } if(duration > 0) { volEnv.push_back(volEnv.back().tick + static_cast(duration), static_cast(points[i].level / 4)); } } if(pitchFall) { InstrumentEnvelope &pitchEnv = ins.PitchEnv; pitchEnv.dwFlags.set(ENV_ENABLED); pitchEnv.reserve(2); pitchEnv.push_back(0, ENVELOPE_MID); pitchEnv.push_back(static_cast(1024 / abs(pitchFall)), pitchFall > 0 ? ENVELOPE_MIN : ENVELOPE_MAX); } } }; MPT_BINARY_STRUCT(AMInstrument, 36) struct PT36IffChunk { // IFF chunk names enum ChunkIdentifiers { idVERS = MAGIC4BE('V','E','R','S'), idINFO = MAGIC4BE('I','N','F','O'), idCMNT = MAGIC4BE('C','M','N','T'), idPTDT = MAGIC4BE('P','T','D','T'), }; uint32be signature; // IFF chunk name uint32be chunksize; // chunk size without header }; MPT_BINARY_STRUCT(PT36IffChunk, 8) struct PT36InfoChunk { char name[32]; uint16be numSamples; uint16be numOrders; uint16be numPatterns; uint16be volume; uint16be tempo; uint16be flags; uint16be dateDay; uint16be dateMonth; uint16be dateYear; uint16be dateHour; uint16be dateMinute; uint16be dateSecond; uint16be playtimeHour; uint16be playtimeMinute; uint16be playtimeSecond; uint16be playtimeMsecond; }; MPT_BINARY_STRUCT(PT36InfoChunk, 64) // Check if header magic equals a given string. static bool IsMagic(const char *magic1, const char *magic2) { return std::memcmp(magic1, magic2, 4) == 0; } static uint32 ReadSample(FileReader &file, MODSampleHeader &sampleHeader, ModSample &sample, char (&sampleName)[MAX_SAMPLENAME], bool is4Chn) { file.ReadStruct(sampleHeader); sampleHeader.ConvertToMPT(sample, is4Chn); mpt::String::Read(sampleName, sampleHeader.name); // Get rid of weird characters in sample names. for(auto &c : sampleName) { if(c > 0 && c < ' ') { c = ' '; } } // Check for invalid values return sampleHeader.GetInvalidByteScore(); } // Parse the order list to determine how many patterns are used in the file. static PATTERNINDEX GetNumPatterns(FileReader &file, ModSequence &Order, ORDERINDEX numOrders, SmpLength totalSampleLen, CHANNELINDEX &numChannels, bool checkForWOW) { PATTERNINDEX numPatterns = 0; // Total number of patterns in file (determined by going through the whole order list) with pattern number < 128 PATTERNINDEX officialPatterns = 0; // Number of patterns only found in the "official" part of the order list (i.e. order positions < claimed order length) PATTERNINDEX numPatternsIllegal = 0; // Total number of patterns in file, also counting in "invalid" pattern indexes >= 128 for(ORDERINDEX ord = 0; ord < 128; ord++) { PATTERNINDEX pat = Order[ord]; if(pat < 128 && numPatterns <= pat) { numPatterns = pat + 1; if(ord < numOrders) { officialPatterns = numPatterns; } } if(pat >= numPatternsIllegal) { numPatternsIllegal = pat + 1; } } // Remove the garbage patterns past the official order end now that we don't need them anymore. Order.resize(numOrders); const size_t patternStartOffset = file.GetPosition(); const size_t sizeWithoutPatterns = totalSampleLen + patternStartOffset; if(checkForWOW && sizeWithoutPatterns + numPatterns * 8 * 256 == file.GetLength()) { // Check if this is a Mod's Grave WOW file... Never seen one of those, but apparently they *do* exist. // WOW files should use the M.K. magic but are actually 8CHN files. numChannels = 8; } else if(numPatterns != officialPatterns && numChannels == 4 && !checkForWOW) { // Fix SoundTracker modules where "hidden" patterns should be ignored. // razor-1911.mod (MD5 b75f0f471b0ae400185585ca05bf7fe8, SHA1 4de31af234229faec00f1e85e1e8f78f405d454b) // and captain_fizz.mod (MD5 55bd89fe5a8e345df65438dbfc2df94e, SHA1 9e0e8b7dc67939885435ea8d3ff4be7704207a43) // seem to have the "correct" file size when only taking the "official" patterns into account, // but they only play correctly when also loading the inofficial patterns. // On the other hand, the SoundTracker module // wolf1.mod (MD5 a4983d7a432d324ce8261b019257f4ed, SHA1 aa6b399d02546bcb6baf9ec56a8081730dea3f44), // wolf3.mod (MD5 af60840815aa9eef43820a7a04417fa6, SHA1 24d6c2e38894f78f6c5c6a4b693a016af8fa037b) // and jean_baudlot_-_bad_dudes_vs_dragonninja-dragonf.mod (MD5 fa48e0f805b36bdc1833f6b82d22d936, SHA1 39f2f8319f4847fe928b9d88eee19d79310b9f91) // only play correctly if we ignore the hidden patterns. // Hence, we have a peek at the first hidden pattern and check if it contains a lot of illegal data. // If that is the case, we assume it's part of the sample data and only consider the "official" patterns. file.Seek(patternStartOffset + officialPatterns * 1024); int illegalBytes = 0; for(int i = 0; i < 256; i++) { uint8 data[4]; file.ReadArray(data); if(data[0] & 0xE0) { illegalBytes++; if(illegalBytes > 64) { numPatterns = officialPatterns; break; } } } file.Seek(patternStartOffset); } #ifdef _DEBUG // Check if the "hidden" patterns in the order list are actually real, i.e. if they are saved in the file. // OpenMPT did this check in the past, but no other tracker appears to do this. // Interestingly, (broken) variants of the ProTracker modules // "killing butterfly" (MD5 bd676358b1dbb40d40f25435e845cf6b, SHA1 9df4ae21214ff753802756b616a0cafaeced8021), // "quartex" by Reflex (MD5 35526bef0fb21cb96394838d94c14bab, SHA1 116756c68c7b6598dcfbad75a043477fcc54c96c), // seem to have the "correct" file size when only taking the "official" patterns into account, but they only play // correctly when also loading the inofficial patterns. // See also the above check for ambiguities with SoundTracker modules. // Keep this assertion in the code to find potential other broken MODs. if(numPatterns != officialPatterns && sizeWithoutPatterns + officialPatterns * numChannels * 256 == file.GetLength()) { MPT_ASSERT(false); //numPatterns = officialPatterns; } else #endif if(numPatternsIllegal > numPatterns && sizeWithoutPatterns + numPatternsIllegal * numChannels * 256 == file.GetLength()) { // Even those illegal pattern indexes (> 128) appear to be valid... What a weird file! // e.g. NIETNU.MOD, where the end of the order list is filled with FF rather than 00, and the file actually contains 256 patterns. numPatterns = numPatternsIllegal; } else if(numPatternsIllegal >= 0xFF) { // Patterns FE and FF are used with S3M semantics (e.g. some MODs written with old OpenMPT versions) Order.Replace(0xFE, Order.GetIgnoreIndex()); Order.Replace(0xFF, Order.GetInvalidPatIndex()); } return numPatterns; } void CSoundFile::ReadMODPatternEntry(FileReader &file, ModCommand &m) { uint8 data[4]; file.ReadArray(data); ReadMODPatternEntry(data, m); } void CSoundFile::ReadMODPatternEntry(const uint8 (&data)[4], ModCommand &m) { // Read Period uint16 period = (((static_cast(data[0]) & 0x0F) << 8) | data[1]); m.note = NOTE_NONE; if(period > 0 && period != 0xFFF) { m.note = 6 * 12 + 35 + NOTE_MIN; for(int i = 0; i < 6 * 12; i++) { if(period >= ProTrackerPeriodTable[i]) { if(period != ProTrackerPeriodTable[i] && i != 0) { uint16 p1 = ProTrackerPeriodTable[i - 1]; uint16 p2 = ProTrackerPeriodTable[i]; if(p1 - period < (period - p2)) { m.note = static_cast(i + 35 + NOTE_MIN); break; } } m.note = static_cast(i + 36 + NOTE_MIN); break; } } } // Read Instrument m.instr = (data[2] >> 4) | (data[0] & 0x10); // Read Effect m.command = data[2] & 0x0F; m.param = data[3]; } struct MODMagicResult { const MPT_UCHAR_TYPE *madeWithTracker = nullptr; uint32 invalidByteThreshold = MODSampleHeader::INVALID_BYTE_THRESHOLD; CHANNELINDEX numChannels = 0; bool isNoiseTracker = false; bool isStartrekker = false; bool isGenericMultiChannel = false; bool setMODVBlankTiming = false; }; static bool CheckMODMagic(const char magic[4], MODMagicResult &result) { if(IsMagic(magic, "M.K.") // ProTracker and compatible || IsMagic(magic, "M!K!") // ProTracker (>64 patterns) || IsMagic(magic, "PATT") // ProTracker 3.6 || IsMagic(magic, "NSMS") // kingdomofpleasure.mod by bee hunter || IsMagic(magic, "LARD")) // judgement_day_gvine.mod by 4-mat { result.madeWithTracker = MPT_ULITERAL("Generic ProTracker or compatible"); result.numChannels = 4; } else if(IsMagic(magic, "M&K!") // "His Master's Noise" musicdisk || IsMagic(magic, "FEST") // "His Master's Noise" musicdisk || IsMagic(magic, "N.T.")) { result.madeWithTracker = MPT_ULITERAL("NoiseTracker"); result.isNoiseTracker = true; result.numChannels = 4; } else if(IsMagic(magic, "OKTA") || IsMagic(magic, "OCTA")) { // Oktalyzer result.madeWithTracker = MPT_ULITERAL("Oktalyzer"); result.numChannels = 8; } else if(IsMagic(magic, "CD81") || IsMagic(magic, "CD61")) { // Octalyser on Atari STe/Falcon result.madeWithTracker = MPT_ULITERAL("Octalyser (Atari)"); result.numChannels = magic[2] - '0'; } else if(IsMagic(magic, "M\0\0\0") || IsMagic(magic, "8\0\0\0")) { // Inconexia demo by Iguana, delta samples (https://www.pouet.net/prod.php?which=830) result.madeWithTracker = MPT_ULITERAL("Inconexia demo (delta samples)"); result.invalidByteThreshold = MODSampleHeader::INVALID_BYTE_FRAGILE_THRESHOLD; result.numChannels = (magic[0] == '8') ? 8 : 4; } else if(!memcmp(magic, "FA0", 3) && magic[3] >= '4' && magic[3] <= '8') { // Digital Tracker on Atari Falcon result.madeWithTracker = MPT_ULITERAL("Digital Tracker"); result.numChannels = magic[3] - '0'; } else if((!memcmp(magic, "FLT", 3) || !memcmp(magic, "EXO", 3)) && magic[3] >= '4' && magic[3] <= '9') { // FLTx / EXOx - Startrekker by Exolon / Fairlight result.madeWithTracker = MPT_ULITERAL("Startrekker"); result.isStartrekker = true; result.setMODVBlankTiming = true; result.numChannels = magic[3] - '0'; } else if(magic[0] >= '1' && magic[0] <= '9' && !memcmp(magic + 1, "CHN", 3)) { // xCHN - Many trackers result.madeWithTracker = MPT_ULITERAL("Generic MOD-compatible Tracker"); result.isGenericMultiChannel = true; result.numChannels = magic[0] - '0'; } else if(magic[0] >= '1' && magic[0] <= '9' && magic[1]>='0' && magic[1] <= '9' && (!memcmp(magic + 2, "CH", 2) || !memcmp(magic + 2, "CN", 2))) { // xxCN / xxCH - Many trackers result.madeWithTracker = MPT_ULITERAL("Generic MOD-compatible Tracker"); result.isGenericMultiChannel = true; result.numChannels = (magic[0] - '0') * 10 + magic[1] - '0'; } else if(!memcmp(magic, "TDZ", 3) && magic[3] >= '4' && magic[3] <= '9') { // TDZx - TakeTracker result.madeWithTracker = MPT_ULITERAL("TakeTracker"); result.numChannels = magic[3] - '0'; } else { return false; } return true; } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderMOD(MemoryFileReader file, const uint64 *pfilesize) { if(!file.CanRead(1080 + 4)) { return ProbeWantMoreData; } file.Seek(1080); char magic[4]; file.ReadArray(magic); MODMagicResult modMagicResult; if(!CheckMODMagic(magic, modMagicResult)) { return ProbeFailure; } file.Seek(20); uint32 invalidBytes = 0; for(SAMPLEINDEX smp = 1; smp <= 31; smp++) { MODSampleHeader sampleHeader; file.ReadStruct(sampleHeader); invalidBytes += sampleHeader.GetInvalidByteScore(); } if(invalidBytes > modMagicResult.invalidByteThreshold) { return ProbeFailure; } MPT_UNREFERENCED_PARAMETER(pfilesize); return ProbeSuccess; } bool CSoundFile::ReadMod(FileReader &file, ModLoadingFlags loadFlags) { char magic[4]; if(!file.Seek(1080) || !file.ReadArray(magic)) { return false; } InitializeGlobals(MOD_TYPE_MOD); MODMagicResult modMagicResult; if(!CheckMODMagic(magic, modMagicResult) || modMagicResult.numChannels < 1 || modMagicResult.numChannels > MAX_BASECHANNELS) { return false; } if(loadFlags == onlyVerifyHeader) { return true; } m_nChannels = modMagicResult.numChannels; if(modMagicResult.madeWithTracker) { m_madeWithTracker = modMagicResult.madeWithTracker; } bool isNoiseTracker = modMagicResult.isNoiseTracker; bool isStartrekker = modMagicResult.isStartrekker; bool isGenericMultiChannel = modMagicResult.isGenericMultiChannel; bool isInconexia = IsMagic(magic, "M\0\0\0") || IsMagic(magic, "8\0\0\0"); if(modMagicResult.setMODVBlankTiming) { m_playBehaviour.set(kMODVBlankTiming); } // Startrekker 8 channel mod (needs special treatment, see below) const bool isFLT8 = isStartrekker && m_nChannels == 8; // Only apply VBlank tests to M.K. (ProTracker) modules. const bool isMdKd = IsMagic(magic, "M.K."); // Adjust finetune values for modules saved with "His Master's Noisetracker" const bool isHMNT = IsMagic(magic, "M&K!") || IsMagic(magic, "FEST"); // Reading song title file.Seek(0); file.ReadString(m_songName, 20); // Load Sample Headers SmpLength totalSampleLen = 0; m_nSamples = 31; uint32 invalidBytes = 0; for(SAMPLEINDEX smp = 1; smp <= 31; smp++) { MODSampleHeader sampleHeader; invalidBytes += ReadSample(file, sampleHeader, Samples[smp], m_szNames[smp], m_nChannels == 4); totalSampleLen += Samples[smp].nLength; if(isHMNT) { Samples[smp].nFineTune = -static_cast(sampleHeader.finetune << 3); } else if(Samples[smp].nLength > 65535) { isNoiseTracker = false; } } // If there is too much binary garbage in the sample headers, reject the file. if(invalidBytes > modMagicResult.invalidByteThreshold) { return false; } // Read order information MODFileHeader fileHeader; file.ReadStruct(fileHeader); file.Skip(4); // Magic bytes (we already parsed these) ReadOrderFromArray(Order(), fileHeader.orderList); ORDERINDEX realOrders = fileHeader.numOrders; if(realOrders > 128) { // beatwave.mod by Sidewinder claims to have 129 orders. (MD5: 8a029ac498d453beb929db9a73c3c6b4, SHA1: f7b76fb9f477b07a2e78eb10d8624f0df262cde7 - the version from ModArchive, not ModLand) realOrders = 128; } else if(realOrders == 0) { // Is this necessary? realOrders = 128; while(realOrders > 1 && Order()[realOrders - 1] == 0) { realOrders--; } } // Get number of patterns (including some order list sanity checks) PATTERNINDEX numPatterns = GetNumPatterns(file, Order(), realOrders, totalSampleLen, m_nChannels, isMdKd); if(isMdKd && GetNumChannels() == 8) { // M.K. with 8 channels = Grave Composer m_madeWithTracker = MPT_USTRING("Mod's Grave"); } if(isFLT8) { // FLT8 has only even order items, so divide by two. for(auto &pat : Order()) { pat /= 2u; } } // Restart position sanity checks realOrders--; Order().SetRestartPos(fileHeader.restartPos); // (Ultimate) Soundtracker didn't have a restart position, but instead stored a default tempo in this value. // The default value for this is 0x78 (120 BPM). This is probably the reason why some M.K. modules // have this weird restart position. I think I've read somewhere that NoiseTracker actually writes 0x78 there. // M.K. files that have restart pos == 0x78: action's batman by DJ Uno, VALLEY.MOD, WormsTDC.MOD, ZWARTZ.MOD // Files that have an order list longer than 0x78 with restart pos = 0x78: my_shoe_is_barking.mod, papermix.mod // - in both cases it does not appear like the restart position should be used. MPT_ASSERT(fileHeader.restartPos != 0x78 || fileHeader.restartPos + 1u >= realOrders); if(fileHeader.restartPos > realOrders || (fileHeader.restartPos == 0x78 && m_nChannels == 4)) { Order().SetRestartPos(0); } m_nDefaultSpeed = 6; m_nDefaultTempo.Set(125); m_nMinPeriod = 14 * 4; m_nMaxPeriod = 3424 * 4; // Prevent clipping based on number of channels... If all channels are playing at full volume, "256 / #channels" // is the maximum possible sample pre-amp without getting distortion (Compatible mix levels given). // The more channels we have, the less likely it is that all of them are used at the same time, though, so cap at 32... m_nSamplePreAmp = Clamp(256 / m_nChannels, 32, 128); m_SongFlags.reset(); // SONG_ISAMIGA will be set conditionally // Setup channel pan positions and volume SetupMODPanning(); // Before loading patterns, apply some heuristics: // - Scan patterns to check if file could be a NoiseTracker file in disguise. // In this case, the parameter of Dxx commands needs to be ignored. // - Use the same code to find notes that would be out-of-range on Amiga. // - Detect 7-bit panning. bool onlyAmigaNotes = true; bool fix7BitPanning = false; uint8 maxPanning = 0; // For detecting 8xx-as-sync if(!isNoiseTracker) { bool leftPanning = false, extendedPanning = false; // For detecting 800-880 panning isNoiseTracker = isMdKd; for(PATTERNINDEX pat = 0; pat < numPatterns; pat++) { uint16 patternBreaks = 0; for(uint32 i = 0; i < 256; i++) { ModCommand m; ReadMODPatternEntry(file, m); if(!m.IsAmigaNote()) { isNoiseTracker = onlyAmigaNotes = false; } if((m.command > 0x06 && m.command < 0x0A) || (m.command == 0x0E && m.param > 0x01) || (m.command == 0x0F && m.param > 0x1F) || (m.command == 0x0D && ++patternBreaks > 1)) { isNoiseTracker = false; } if(m.command == 0x08) { maxPanning = std::max(maxPanning, m.param); if(m.param < 0x80) leftPanning = true; else if(m.param > 0x8F && m.param != 0xA4) extendedPanning = true; } else if(m.command == 0x0E && (m.param & 0xF0) == 0x80) { maxPanning = std::max(maxPanning, m.param << 4); } } } fix7BitPanning = leftPanning && !extendedPanning; } file.Seek(1084); const CHANNELINDEX readChannels = (isFLT8 ? 4 : m_nChannels); // 4 channels per pattern in FLT8 format. if(isFLT8) numPatterns++; // as one logical pattern consists of two real patterns in FLT8 format, the highest pattern number has to be increased by one. bool hasTempoCommands = false, definitelyCIA = false; // for detecting VBlank MODs // Heuristic for rejecting E0x commands that are most likely not intended to actually toggle the Amiga LED filter, like in naen_leijasi_ptk.mod by ilmarque bool filterState = false; int filterTransitions = 0; // Reading patterns Patterns.ResizeArray(numPatterns); for(PATTERNINDEX pat = 0; pat < numPatterns; pat++) { ModCommand *rowBase = nullptr; if(isFLT8) { // FLT8: Only create "even" patterns and either write to channel 1 to 4 (even patterns) or 5 to 8 (odd patterns). PATTERNINDEX actualPattern = pat / 2u; if((pat % 2u) == 0 && !Patterns.Insert(actualPattern, 64)) { break; } rowBase = Patterns[actualPattern].GetpModCommand(0, (pat % 2u) == 0 ? 0 : 4); } else { if(!Patterns.Insert(pat, 64)) { break; } rowBase = Patterns[pat].GetpModCommand(0, 0); } if(rowBase == nullptr || !(loadFlags & loadPatternData)) { break; } // For detecting PT1x mode std::vector lastInstrument(GetNumChannels(), 0); std::vector instrWithoutNoteCount(GetNumChannels(), 0); for(ROWINDEX row = 0; row < 64; row++, rowBase += m_nChannels) { // If we have more than one Fxx command on this row and one can be interpreted as speed // and the other as tempo, we can be rather sure that it is not a VBlank mod. bool hasSpeedOnRow = false, hasTempoOnRow = false; for(CHANNELINDEX chn = 0; chn < readChannels; chn++) { ModCommand &m = rowBase[chn]; ReadMODPatternEntry(file, m); if(m.command || m.param) { // No support for Startrekker assembly macros if(isStartrekker && m.command == 0x0E) { m.command = CMD_NONE; m.param = 0; } ConvertModCommand(m); } // Perform some checks for our heuristics... if(m.command == CMD_TEMPO) { hasTempoOnRow = true; if(m.param < 100) hasTempoCommands = true; } else if(m.command == CMD_SPEED) { hasSpeedOnRow = true; } else if(m.command == CMD_PATTERNBREAK && isNoiseTracker) { m.param = 0; } else if(m.command == CMD_PANNING8 && fix7BitPanning) { // Fix MODs with 7-bit + surround panning if(m.param == 0xA4) { m.command = CMD_S3MCMDEX; m.param = 0x91; } else { m.param = mpt::saturate_cast(m.param * 2); } } else if(m.command == CMD_MODCMDEX && m.param < 0x10) { // Count LED filter transitions bool newState = !(m.param & 0x01); if(newState != filterState) { filterState = newState; filterTransitions++; } } if(m.note == NOTE_NONE && m.instr > 0 && !isFLT8) { if(lastInstrument[chn] > 0 && lastInstrument[chn] != m.instr) { // Arbitrary threshold for enabling sample swapping: 4 consecutive "sample swaps" in one pattern. if(++instrWithoutNoteCount[chn] >= 4) { m_playBehaviour.set(kMODSampleSwap); } } } else if(m.note != NOTE_NONE) { instrWithoutNoteCount[chn] = 0; } if(m.instr != 0) { lastInstrument[chn] = m.instr; } } if(hasSpeedOnRow && hasTempoOnRow) definitelyCIA = true; } } if(onlyAmigaNotes && (IsMagic(magic, "M.K.") || IsMagic(magic, "M!K!") || IsMagic(magic, "PATT"))) { // M.K. files that don't exceed the Amiga note limit (fixes mod.mothergoose) m_SongFlags.set(SONG_AMIGALIMITS); // Need this for professionaltracker.mod by h0ffman (SHA1: 9a7c52cbad73ed2a198ee3fa18d3704ea9f546ff) m_SongFlags.set(SONG_PT_MODE); m_playBehaviour.set(kMODSampleSwap); m_playBehaviour.set(kMODOutOfRangeNoteDelay); m_playBehaviour.set(kMODTempoOnSecondTick); // Arbitrary threshold for deciding that 8xx effects are only used as sync markers if(maxPanning < 0x20) { m_playBehaviour.set(kMODIgnorePanning); if(fileHeader.restartPos != 0x7F) { // Don't enable these hacks for ScreamTracker modules (restart position = 0x7F), to fix e.g. sample 10 in BASIC001.MOD (SHA1: 11298a5620e677beaa50bd4ed00c3710b75c81af) // Note: restart position = 0x7F can also be found in ProTracker modules, e.g. professionaltracker.mod by h0ffman m_playBehaviour.set(kMODOneShotLoops); } } } else if(!onlyAmigaNotes && fileHeader.restartPos == 0x7F && isMdKd && fileHeader.restartPos + 1u >= realOrders) { m_madeWithTracker = MPT_USTRING("ScreamTracker"); } if(onlyAmigaNotes && !isGenericMultiChannel && filterTransitions < 7) { m_SongFlags.set(SONG_ISAMIGA); } if(isInconexia) { m_playBehaviour.set(kMODIgnorePanning); } // Reading samples if(loadFlags & loadSampleData) { file.Seek(1084 + (readChannels * 64 * 4) * numPatterns); for(SAMPLEINDEX smp = 1; smp <= 31; smp++) { ModSample &sample = Samples[smp]; if(sample.nLength) { SampleIO::Encoding encoding = SampleIO::signedPCM; if(isInconexia) encoding = SampleIO::deltaPCM; else if(file.ReadMagic("ADPCM")) encoding = SampleIO::ADPCM; SampleIO sampleIO( SampleIO::_8bit, SampleIO::mono, SampleIO::littleEndian, encoding); // Fix sample 6 in MOD.shorttune2, which has a replen longer than the sample itself. // ProTracker reads beyond the end of the sample when playing. Normally samples are // adjacent in PT's memory, so we simply read into the next sample in the file. FileReader::off_t nextSample = file.GetPosition() + sampleIO.CalculateEncodedSize(sample.nLength); if(isMdKd && onlyAmigaNotes) sample.nLength = std::max(sample.nLength, sample.nLoopEnd); sampleIO.ReadSample(sample, file); file.Seek(nextSample); } } } #if defined(MPT_EXTERNAL_SAMPLES) || defined(MPT_BUILD_FUZZER) // Detect Startrekker files with external synth instruments. // Note: Synthesized AM samples may overwrite existing samples (e.g. sample 1 in fa.worse face.mod), // hence they are loaded here after all regular samples have been loaded. if((loadFlags & loadSampleData) && isStartrekker) { #ifdef MPT_EXTERNAL_SAMPLES InputFile amFile; FileReader amData; mpt::PathString filename = file.GetFileName(); if(!filename.empty()) { // Find instrument definition file const mpt::PathString exts[] = { MPT_PATHSTRING(".nt"), MPT_PATHSTRING(".NT"), MPT_PATHSTRING(".as"), MPT_PATHSTRING(".AS") }; for(const auto &ext : exts) { mpt::PathString infoName = filename + ext; char stMagic[16]; if(infoName.IsFile() && amFile.Open(infoName) && (amData = GetFileReader(amFile)).IsValid() && amData.ReadArray(stMagic)) { if(!memcmp(stMagic, "ST1.2 ModuleINFO", 16)) m_madeWithTracker = MPT_USTRING("Startrekker 1.2"); else if(!memcmp(stMagic, "ST1.3 ModuleINFO", 16)) m_madeWithTracker = MPT_USTRING("Startrekker 1.3"); else if(!memcmp(stMagic, "AudioSculpture10", 16)) m_madeWithTracker = MPT_USTRING("AudioSculpture 1.0"); else continue; if(amData.Seek(144)) { // Looks like a valid instrument definition file! m_nInstruments = 31; break; } } } } #elif defined(MPT_BUILD_FUZZER) // For fuzzing this part of the code, just take random data from patterns FileReader amData = file.GetChunkAt(1084, 31 * 120); m_nInstruments = 31; #endif for(SAMPLEINDEX smp = 1; smp <= m_nInstruments; smp++) { // For Startrekker AM synthesis, we need instrument envelopes. ModInstrument *ins = AllocateInstrument(smp, smp); if(ins == nullptr) { break; } mpt::String::Copy(ins->name, m_szNames[smp]); AMInstrument am; // Allow partial reads for fa.worse face.mod if(amData.ReadStructPartial(am) && !memcmp(am.am, "AM", 2) && am.waveform < 4) { am.ConvertToMPT(Samples[smp], *ins, AccessPRNG()); } // This extra padding is probably present to have identical block sizes for AM and FM instruments. amData.Skip(120 - sizeof(AMInstrument)); } } #endif // MPT_EXTERNAL_SAMPLES || MPT_BUILD_FUZZER // Fix VBlank MODs. Arbitrary threshold: 10 minutes. // Basically, this just converts all tempo commands into speed commands // for MODs which are supposed to have VBlank timing (instead of CIA timing). // There is no perfect way to do this, since both MOD types look the same, // but the most reliable way is to simply check for extremely long songs // (as this would indicate that e.g. a F30 command was really meant to set // the ticks per row to 48, and not the tempo to 48 BPM). // In the pattern loader above, a second condition is used: Only tempo commands // below 100 BPM are taken into account. Furthermore, only M.K. (ProTracker) // modules are checked. if(isMdKd && hasTempoCommands && !definitelyCIA) { const double songTime = GetSongTime(); if(songTime >= 600.0) { m_playBehaviour.set(kMODVBlankTiming); if(GetLength(eNoAdjust, GetLengthTarget(songTime)).front().targetReached) { // This just makes things worse, song is at least as long as in CIA mode (e.g. in "Stary Hallway" by Neurodancer) // Obviously we should keep using CIA timing then... m_playBehaviour.reset(kMODVBlankTiming); } else { m_madeWithTracker = MPT_USTRING("ProTracker (VBlank)"); } } } return true; } // Check if a name string is valid (i.e. doesn't contain binary garbage data) template static uint32 CountInvalidChars(const char (&name)[N]) { uint32 invalidChars = 0; for(int8 c : name) // char can be signed or unsigned { // Check for any Extended ASCII and control characters if(c != 0 && c < ' ') invalidChars++; } return invalidChars; } // We'll have to do some heuristic checks to find out whether this is an old Ultimate Soundtracker module // or if it was made with the newer Soundtracker versions. // Thanks for Fraggie for this information! (https://www.un4seen.com/forum/?topic=14471.msg100829#msg100829) enum STVersions { UST1_00, // Ultimate Soundtracker 1.0-1.21 (K. Obarski) UST1_80, // Ultimate Soundtracker 1.8-2.0 (K. Obarski) ST2_00_Exterminator, // SoundTracker 2.0 (The Exterminator), D.O.C. Sountracker II (Unknown/D.O.C.) ST_III, // Defjam Soundtracker III (Il Scuro/Defjam), Alpha Flight SoundTracker IV (Alpha Flight), D.O.C. SoundTracker IV (Unknown/D.O.C.), D.O.C. SoundTracker VI (Unknown/D.O.C.) ST_IX, // D.O.C. SoundTracker IX (Unknown/D.O.C.) MST1_00, // Master Soundtracker 1.0 (Tip/The New Masters) ST2_00, // SoundTracker 2.0, 2.1, 2.2 (Unknown/D.O.C.) }; struct M15FileHeaders { char songname[20]; MODSampleHeader sampleHeaders[15]; MODFileHeader fileHeader; }; MPT_BINARY_STRUCT(M15FileHeaders, 20 + 15 * 30 + 130) typedef uint8 M15PatternData[64][4][4]; static bool ValidateHeader(const M15FileHeaders &fileHeaders) { // In theory, sample and song names should only ever contain printable ASCII chars and null. // However, there are quite a few SoundTracker modules in the wild with random // characters. To still be able to distguish them from other formats, we just reject // files with *too* many bogus characters. Arbitrary threshold: 48 bogus characters in total // or more than 5 invalid characters just in the title alone. uint32 invalidChars = CountInvalidChars(fileHeaders.songname); if(invalidChars > 5) { return false; } SmpLength totalSampleLen = 0; uint8 allVolumes = 0; for(SAMPLEINDEX smp = 0; smp < 15; smp++) { const MODSampleHeader &sampleHeader = fileHeaders.sampleHeaders[smp]; invalidChars += CountInvalidChars(sampleHeader.name); // Sanity checks - invalid character count adjusted for ata.mod (MD5 937b79b54026fa73a1a4d3597c26eace, SHA1 3322ca62258adb9e0ae8e9afe6e0c29d39add874) if(invalidChars > 48 || sampleHeader.volume > 64 || sampleHeader.finetune != 0 || sampleHeader.length > 32768) { return false; } totalSampleLen += sampleHeader.length; allVolumes |= sampleHeader.volume; } // Reject any files with no (or only silent) samples at all, as this might just be a random binary file (e.g. ID3 tags with tons of padding) if(totalSampleLen == 0 || allVolumes == 0) { return false; } // Sanity check: No more than 128 positions. ST's GUI limits tempo to [1, 220]. // There are some mods with a tempo of 0 (explora3-death.mod) though, so ignore the lower limit. if(fileHeaders.fileHeader.numOrders > 128 || fileHeaders.fileHeader.restartPos > 220) { return false; } uint8 maxPattern = *std::max_element(std::begin(fileHeaders.fileHeader.orderList), std::end(fileHeaders.fileHeader.orderList)); // Sanity check: 64 patterns max. if(maxPattern > 63) { return false; } // No playable song, and lots of null values => most likely a sparse binary file but not a module if(fileHeaders.fileHeader.restartPos == 0 && fileHeaders.fileHeader.numOrders == 0 && maxPattern == 0) { return false; } return true; } static uint32 CountIllegalM15PatternBytes(const M15PatternData &patternData) { uint32 illegalBytes = 0; for(uint8 row = 0; row < 64; ++row) { for(uint8 channel = 0; channel < 4; ++channel) { if(patternData[row][channel][0] & 0xF0u) { illegalBytes++; } } } return illegalBytes; } template static bool ValidateFirstM15Pattern(TFileReader &file) { M15PatternData patternData; if(!file.ReadArray(patternData)) { return false; } file.SkipBack(sizeof(patternData)); uint32 invalidBytes = CountIllegalM15PatternBytes(patternData); // [threshold for all patterns combined] / [max patterns] * [margin, do not reject too much] if(invalidBytes > 512 / 64 * 2) { return false; } return true; } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderM15(MemoryFileReader file, const uint64 *pfilesize) { M15FileHeaders fileHeaders; if(!file.ReadStruct(fileHeaders)) { return ProbeWantMoreData; } if(!ValidateHeader(fileHeaders)) { return ProbeFailure; } if(!file.CanRead(sizeof(M15PatternData))) { return ProbeWantMoreData; } if(!ValidateFirstM15Pattern(file)) { return ProbeFailure; } MPT_UNREFERENCED_PARAMETER(pfilesize); return ProbeSuccess; } bool CSoundFile::ReadM15(FileReader &file, ModLoadingFlags loadFlags) { file.Rewind(); M15FileHeaders fileHeaders; if(!file.ReadStruct(fileHeaders)) { return false; } if(!ValidateHeader(fileHeaders)) { return false; } if(!ValidateFirstM15Pattern(file)) { return false; } char songname[20]; std::memcpy(songname, fileHeaders.songname, 20); InitializeGlobals(MOD_TYPE_MOD); m_playBehaviour.reset(kMODOneShotLoops); m_playBehaviour.set(kMODIgnorePanning); m_playBehaviour.set(kMODSampleSwap); // untested m_nChannels = 4; STVersions minVersion = UST1_00; bool hasDiskNames = true; SmpLength totalSampleLen = 0; m_nSamples = 15; file.Seek(20); for(SAMPLEINDEX smp = 1; smp <= 15; smp++) { MODSampleHeader sampleHeader; ReadSample(file, sampleHeader, Samples[smp], m_szNames[smp], true); totalSampleLen += Samples[smp].nLength; if(m_szNames[smp][0] && ((memcmp(m_szNames[smp], "st-", 3) && memcmp(m_szNames[smp], "ST-", 3)) || m_szNames[smp][5] != ':')) { // Ultimate Soundtracker 1.8 and D.O.C. SoundTracker IX always have sample names containing disk names. hasDiskNames = false; } // Loop start is always in bytes, not words, so don't trust the auto-fix magic in the sample header conversion (fixes loop of "st-01:asia" in mod.drag 10) if(sampleHeader.loopLength > 1) { Samples[smp].nLoopStart = sampleHeader.loopStart; Samples[smp].nLoopEnd = sampleHeader.loopStart + sampleHeader.loopLength * 2; Samples[smp].SanitizeLoops(); } // UST only handles samples up to 9999 bytes. Master Soundtracker 1.0 and SoundTracker 2.0 introduce 32KB samples. if(sampleHeader.length > 4999 || sampleHeader.loopStart > 9999) minVersion = std::max(minVersion, MST1_00); } MODFileHeader fileHeader; file.ReadStruct(fileHeader); ReadOrderFromArray(Order(), fileHeader.orderList); PATTERNINDEX numPatterns = GetNumPatterns(file, Order(), fileHeader.numOrders, totalSampleLen, m_nChannels, false); // Most likely just a file with lots of NULs at the start if(fileHeader.restartPos == 0 && fileHeader.numOrders == 0 && numPatterns <= 1) { return false; } // Let's see if the file is too small (including some overhead for broken files like sll7.mod or ghostbus.mod) if(file.BytesLeft() + 65536 < numPatterns * 64u * 4u * 4u + totalSampleLen) return false; if(loadFlags == onlyVerifyHeader) return true; // Now we can be pretty sure that this is a valid Soundtracker file. Set up default song settings. // explora3-death.mod has a tempo of 0 if(!fileHeader.restartPos) fileHeader.restartPos = 0x78; // jjk55 by Jesper Kyd has a weird tempo set, but it needs to be ignored. if(!memcmp(songname, "jjk55", 6)) fileHeader.restartPos = 0x78; // Sample 7 in echoing.mod won't "loop" correctly if we don't convert the VBlank tempo. m_nDefaultTempo.Set(fileHeader.restartPos * 25 / 24); if(fileHeader.restartPos != 0x78) { // Convert to CIA timing //m_nDefaultTempo = TEMPO(((709378.92 / 50.0) * 125.0) / ((240 - fileHeader.restartPos) * 122.0)); m_nDefaultTempo.Set((709379 / ((240 - fileHeader.restartPos) * 122)) * 125 / 50); if(minVersion > UST1_80) { // D.O.C. SoundTracker IX re-introduced the variable tempo after some other versions dropped it. minVersion = std::max(minVersion, hasDiskNames ? ST_IX : MST1_00); } else { // Ultimate Soundtracker 1.8 adds variable tempo minVersion = std::max(minVersion, hasDiskNames ? UST1_80 : ST2_00_Exterminator); } } m_nMinPeriod = 113 * 4; m_nMaxPeriod = 856 * 4; m_nSamplePreAmp = 64; m_SongFlags.set(SONG_PT_MODE); mpt::String::Read(m_songName, songname); // Setup channel pan positions and volume SetupMODPanning(); FileReader::off_t patOffset = file.GetPosition(); // Scan patterns to identify Ultimate Soundtracker modules. uint32 illegalBytes = 0; for(PATTERNINDEX pat = 0; pat < numPatterns; pat++) { bool patternInUse = std::find(Order().cbegin(), Order().cend(), pat) != Order().cend(); uint8 numDxx = 0; uint8 emptyCmds = 0; M15PatternData patternData; file.ReadArray(patternData); if(patternInUse) { illegalBytes += CountIllegalM15PatternBytes(patternData); // Reject files that contain a lot of illegal pattern data. // STK.the final remix (MD5 5ff13cdbd77211d1103be7051a7d89c9, SHA1 e94dba82a5da00a4758ba0c207eb17e3a89c3aa3) // has one illegal byte, so we only reject after an arbitrary threshold has been passed. // This also allows to play some rather damaged files like // crockets.mod (MD5 995ed9f44cab995a0eeb19deb52e2a8b, SHA1 6c79983c3b7d55c9bc110b625eaa07ce9d75f369) // but naturally we cannot recover the broken data. // We only check patterns that are actually being used in the order list, because some bad rips of the // "operation wolf" soundtrack have 15 patterns for several songs, but the last few patterns are just garbage. // Apart from those hidden patterns, the files play fine. // Example: operation wolf - wolf1.mod (MD5 739acdbdacd247fbefcac7bc2d8abe6b, SHA1 e6b4813daacbf95f41ce9ec3b22520a2ae07eed8) if(illegalBytes > 512) return false; } for(ROWINDEX row = 0; row < 64; row++) { for(CHANNELINDEX chn = 0; chn < 4; chn++) { const uint8 (&data)[4] = patternData[row][chn]; const uint8 eff = data[2] & 0x0F, param = data[3]; // Check for empty space between the last Dxx command and the beginning of another pattern if(emptyCmds != 0 && !memcmp(data, "\0\0\0\0", 4)) { emptyCmds++; if(emptyCmds > 32) { // Since there is a lot of empty space after the last Dxx command, // we assume it's supposed to be a pattern break effect. minVersion = ST2_00; } } else { emptyCmds = 0; } switch(eff) { case 1: case 2: if(param > 0x1F && minVersion == UST1_80) { // If a 1xx / 2xx effect has a parameter greater than 0x20, it is assumed to be UST. minVersion = hasDiskNames ? UST1_80 : UST1_00; } else if(eff == 1 && param > 0 && param < 0x03) { // This doesn't look like an arpeggio. minVersion = std::max(minVersion, ST2_00_Exterminator); } else if(eff == 1 && (param == 0x37 || param == 0x47) && minVersion <= ST2_00_Exterminator) { // This suspiciously looks like an arpeggio. // Catch sleepwalk.mod by Karsten Obarski, which has a default tempo of 125 rather than 120 in the header, so gets mis-identified as a later tracker version. minVersion = hasDiskNames ? UST1_80 : UST1_00; } break; case 0x0B: minVersion = ST2_00; break; case 0x0C: case 0x0D: case 0x0E: minVersion = std::max(minVersion, ST2_00_Exterminator); if(eff == 0x0D) { emptyCmds = 1; if(param == 0 && row == 0) { // Fix a possible tracking mistake in Blood Money title - who wants to do a pattern break on the first row anyway? break; } numDxx++; } break; case 0x0F: minVersion = std::max(minVersion, ST_III); break; } } } if(numDxx > 0 && numDxx < 3) { // Not many Dxx commands in one pattern means they were probably pattern breaks minVersion = ST2_00; } } file.Seek(patOffset); // Reading patterns if(loadFlags & loadPatternData) Patterns.ResizeArray(numPatterns); for(PATTERNINDEX pat = 0; pat < numPatterns; pat++) { M15PatternData patternData; file.ReadArray(patternData); if(!(loadFlags & loadPatternData) || !Patterns.Insert(pat, 64)) { continue; } uint8 autoSlide[4] = { 0, 0, 0, 0 }; for(ROWINDEX row = 0; row < 64; row++) { PatternRow rowBase = Patterns[pat].GetpModCommand(row, 0); for(CHANNELINDEX chn = 0; chn < 4; chn++) { ModCommand &m = rowBase[chn]; ReadMODPatternEntry(patternData[row][chn], m); if(!m.param || m.command == 0x0E) { autoSlide[chn] = 0; } if(m.command || m.param) { if(autoSlide[chn] != 0) { if(autoSlide[chn] & 0xF0) { m.volcmd = VOLCMD_VOLSLIDEUP; m.vol = autoSlide[chn] >> 4; } else { m.volcmd = VOLCMD_VOLSLIDEDOWN; m.vol = autoSlide[chn] & 0x0F; } } if(m.command == 0x0D) { if(minVersion != ST2_00) { // Dxy is volume slide in some Soundtracker versions, D00 is a pattern break in the latest versions. m.command = 0x0A; } else { m.param = 0; } } else if(m.command == 0x0C) { // Volume is sent as-is to the chip, which ignores the highest bit. m.param &= 0x7F; } else if(m.command == 0x0E && (m.param > 0x01 || minVersion < ST_IX)) { // Import auto-slides as normal slides and fake them using volume column slides. m.command = 0x0A; autoSlide[chn] = m.param; } else if(m.command == 0x0F) { // Only the low nibble is evaluated in Soundtracker. m.param &= 0x0F; } if(minVersion <= UST1_80) { // UST effects switch(m.command) { case 0: // jackdance.mod by Karsten Obarski has 0xy arpeggios... if(m.param < 0x03) { m.command = CMD_NONE; } else { m.command = CMD_ARPEGGIO; } break; case 1: m.command = CMD_ARPEGGIO; break; case 2: if(m.param & 0x0F) { m.command = CMD_PORTAMENTOUP; m.param &= 0x0F; } else if(m.param >> 4) { m.command = CMD_PORTAMENTODOWN; m.param >>= 4; } break; default: m.command = CMD_NONE; break; } } else { ConvertModCommand(m); } } else { autoSlide[chn] = 0; } } } } switch(minVersion) { case UST1_00: m_madeWithTracker = MPT_USTRING("Ultimate Soundtracker 1.0-1.21"); break; case UST1_80: m_madeWithTracker = MPT_USTRING("Ultimate Soundtracker 1.8-2.0"); break; case ST2_00_Exterminator: m_madeWithTracker = MPT_USTRING("SoundTracker 2.0 / D.O.C. SoundTracker II"); break; case ST_III: m_madeWithTracker = MPT_USTRING("Defjam Soundtracker III / Alpha Flight SoundTracker IV / D.O.C. SoundTracker IV / VI"); break; case ST_IX: m_madeWithTracker = MPT_USTRING("D.O.C. SoundTracker IX"); break; case MST1_00: m_madeWithTracker = MPT_USTRING("Master Soundtracker 1.0"); break; case ST2_00: m_madeWithTracker = MPT_USTRING("SoundTracker 2.0 / 2.1 / 2.2"); break; } // Reading samples if(loadFlags & loadSampleData) { for(SAMPLEINDEX smp = 1; smp <= 15; smp++) { // Looped samples in (Ultimate) Soundtracker seem to ignore all sample data before the actual loop start. // This avoids the clicks in the first sample of pretend.mod by Karsten Obarski. file.Skip(Samples[smp].nLoopStart); Samples[smp].nLength -= Samples[smp].nLoopStart; Samples[smp].nLoopEnd -= Samples[smp].nLoopStart; Samples[smp].nLoopStart = 0; MODSampleHeader::GetSampleFormat().ReadSample(Samples[smp], file); } } return true; } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderICE(MemoryFileReader file, const uint64 *pfilesize) { if(!file.CanRead(1464 + 4)) { return ProbeWantMoreData; } file.Seek(1464); char magic[4]; file.ReadArray(magic); if(!IsMagic(magic, "MTN\0") && !IsMagic(magic, "IT10")) { return ProbeFailure; } file.Seek(20); uint32 invalidBytes = 0; for(SAMPLEINDEX smp = 1; smp <= 31; smp++) { MODSampleHeader sampleHeader; if(!file.ReadStruct(sampleHeader)) { return ProbeWantMoreData; } invalidBytes += sampleHeader.GetInvalidByteScore(); } if(invalidBytes > MODSampleHeader::INVALID_BYTE_THRESHOLD) { return ProbeFailure; } const uint8 numOrders = file.ReadUint8(); const uint8 numTracks = file.ReadUint8(); if(numOrders > 128) { return ProbeFailure; } uint8 tracks[128 * 4]; file.ReadArray(tracks); for(auto track : tracks) { if(track > numTracks) { return ProbeFailure; } } MPT_UNREFERENCED_PARAMETER(pfilesize); return ProbeSuccess; } // SoundTracker 2.6 / Ice Tracker variation of the MOD format // The only real difference to other SoundTracker formats is the way patterns are stored: // Every pattern consists of four independent, re-usable tracks. bool CSoundFile::ReadICE(FileReader &file, ModLoadingFlags loadFlags) { char magic[4]; if(!file.Seek(1464) || !file.ReadArray(magic)) { return false; } InitializeGlobals(MOD_TYPE_MOD); m_playBehaviour.reset(kMODOneShotLoops); m_playBehaviour.set(kMODIgnorePanning); m_playBehaviour.set(kMODSampleSwap); // untested if(IsMagic(magic, "MTN\0")) { m_madeWithTracker = MPT_USTRING("SoundTracker 2.6"); } else if(IsMagic(magic, "IT10")) { m_madeWithTracker = MPT_USTRING("Ice Tracker 1.0 / 1.1"); } else { return false; } // Reading song title file.Seek(0); file.ReadString(m_songName, 20); // Load Samples m_nSamples = 31; uint32 invalidBytes = 0; for(SAMPLEINDEX smp = 1; smp <= 31; smp++) { MODSampleHeader sampleHeader; invalidBytes += ReadSample(file, sampleHeader, Samples[smp], m_szNames[smp], true); } if(invalidBytes > MODSampleHeader::INVALID_BYTE_THRESHOLD) { return false; } const uint8 numOrders = file.ReadUint8(); const uint8 numTracks = file.ReadUint8(); if(numOrders > 128) { return false; } uint8 tracks[128 * 4]; file.ReadArray(tracks); for(auto track : tracks) { if(track > numTracks) { return false; } } if(loadFlags == onlyVerifyHeader) { return true; } // Now we can be pretty sure that this is a valid MOD file. Set up default song settings. m_nChannels = 4; m_nInstruments = 0; m_nDefaultSpeed = 6; m_nDefaultTempo.Set(125); m_nMinPeriod = 14 * 4; m_nMaxPeriod = 3424 * 4; m_nSamplePreAmp = 64; m_SongFlags.set(SONG_PT_MODE); // Setup channel pan positions and volume SetupMODPanning(); // Reading patterns Order().resize(numOrders); uint8 speed[2] = { 0, 0 }, speedPos = 0; Patterns.ResizeArray(numOrders); for(PATTERNINDEX pat = 0; pat < numOrders; pat++) { Order()[pat] = pat; if(!Patterns.Insert(pat, 64)) continue; for(CHANNELINDEX chn = 0; chn < 4; chn++) { file.Seek(1468 + tracks[pat * 4 + chn] * 64u * 4u); ModCommand *m = Patterns[pat].GetpModCommand(0, chn); for(ROWINDEX row = 0; row < 64; row++, m += 4) { ReadMODPatternEntry(file, *m); if((m->command || m->param) && !(m->command == 0x0E && m->param >= 0x10) // Exx only sets filter && !(m->command >= 0x05 && m->command <= 0x09)) // These don't exist in ST2.6 { ConvertModCommand(*m); } else { m->command = CMD_NONE; } } } // Handle speed command with both nibbles set - this enables auto-swing (alternates between the two nibbles) auto m = Patterns[pat].begin(); for(ROWINDEX row = 0; row < 64; row++) { for(CHANNELINDEX chn = 0; chn < 4; chn++, m++) { if(m->command == CMD_SPEED || m->command == CMD_TEMPO) { m->command = CMD_SPEED; speedPos = 0; if(m->param & 0xF0) { if((m->param >> 4) != (m->param & 0x0F) && (m->param & 0x0F) != 0) { // Both nibbles set speed[0] = m->param >> 4; speed[1] = m->param & 0x0F; speedPos = 1; } m->param >>= 4; } } } if(speedPos) { Patterns[pat].WriteEffect(EffectWriter(CMD_SPEED, speed[speedPos - 1]).Row(row)); speedPos++; if(speedPos == 3) speedPos = 1; } } } // Reading samples if(loadFlags & loadSampleData) { file.Seek(1468 + numTracks * 64u * 4u); for(SAMPLEINDEX smp = 1; smp <= 31; smp++) if(Samples[smp].nLength) { SampleIO( SampleIO::_8bit, SampleIO::mono, SampleIO::littleEndian, SampleIO::signedPCM) .ReadSample(Samples[smp], file); } } return true; } struct PT36Header { char magicFORM[4]; // "FORM" uint8be dummy1[4]; char magicMODL[4]; // "MODL" }; MPT_BINARY_STRUCT(PT36Header, 12) static bool ValidateHeader(const PT36Header &fileHeader) { if(std::memcmp(fileHeader.magicFORM, "FORM", 4)) { return false; } if(std::memcmp(fileHeader.magicMODL, "MODL", 4)) { return false; } return true; } CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderPT36(MemoryFileReader file, const uint64 *pfilesize) { PT36Header fileHeader; if(!file.ReadStruct(fileHeader)) { return ProbeWantMoreData; } if(!ValidateHeader(fileHeader)) { return ProbeFailure; } MPT_UNREFERENCED_PARAMETER(pfilesize); return ProbeSuccess; } // ProTracker 3.6 version of the MOD format // Basically just a normal ProTracker mod with different magic, wrapped in an IFF file. // The "PTDT" chunk is passed to the normal MOD loader. bool CSoundFile::ReadPT36(FileReader &file, ModLoadingFlags loadFlags) { file.Rewind(); PT36Header fileHeader; if(!file.ReadStruct(fileHeader)) { return false; } if(!ValidateHeader(fileHeader)) { return false; } bool ok = false, infoOk = false; FileReader commentChunk; mpt::ustring version; PT36InfoChunk info; MemsetZero(info); // Go through IFF chunks... PT36IffChunk iffHead; if(!file.ReadStruct(iffHead)) { return false; } // First chunk includes "MODL" magic in size iffHead.chunksize -= 4; do { // All chunk sizes include chunk header iffHead.chunksize -= 8; if(loadFlags == onlyVerifyHeader && iffHead.signature == PT36IffChunk::idPTDT) { return true; } FileReader chunk = file.ReadChunk(iffHead.chunksize); if(!chunk.IsValid()) { break; } switch(iffHead.signature) { case PT36IffChunk::idVERS: chunk.Skip(4); if(chunk.ReadMagic("PT") && iffHead.chunksize > 6) { chunk.ReadString(version, mpt::CharsetISO8859_1, iffHead.chunksize - 6); } break; case PT36IffChunk::idINFO: infoOk = chunk.ReadStruct(info); break; case PT36IffChunk::idCMNT: commentChunk = chunk; break; case PT36IffChunk::idPTDT: ok = ReadMod(chunk, loadFlags); break; } } while(file.ReadStruct(iffHead)); if(version.empty()) { version = MPT_USTRING("3.6"); } // both an info chunk and a module are required if(ok && infoOk) { bool vblank = (info.flags & 0x100) == 0; m_playBehaviour.set(kMODVBlankTiming, vblank); if(info.volume != 0) m_nSamplePreAmp = std::min(64, info.volume); if(info.tempo != 0 && !vblank) m_nDefaultTempo.Set(info.tempo); if(info.name[0]) mpt::String::Read(m_songName, info.name); if(IsInRange(info.dateMonth, 1, 12) && IsInRange(info.dateDay, 1, 31) && IsInRange(info.dateHour, 0, 23) && IsInRange(info.dateMinute, 0, 59) && IsInRange(info.dateSecond, 0, 59)) { FileHistory mptHistory; MemsetZero(mptHistory.loadDate); mptHistory.loadDate.tm_year = info.dateYear; mptHistory.loadDate.tm_mon = info.dateMonth - 1; mptHistory.loadDate.tm_mday = info.dateDay; mptHistory.loadDate.tm_hour = info.dateHour; mptHistory.loadDate.tm_min = info.dateMinute; mptHistory.loadDate.tm_sec = info.dateSecond; m_FileHistory.push_back(mptHistory); } } if(ok) { if(commentChunk.IsValid()) { std::string author; commentChunk.ReadString(author, 32); if(author != "UNNAMED AUTHOR") m_songArtist = mpt::ToUnicode(mpt::CharsetISO8859_1, author); if(!commentChunk.NoBytesLeft()) { m_songMessage.ReadFixedLineLength(commentChunk, commentChunk.BytesLeft(), 40, 0); } } m_madeWithTracker = MPT_USTRING("ProTracker ") + version; } m_SongFlags.set(SONG_PT_MODE); m_playBehaviour.set(kMODIgnorePanning); m_playBehaviour.set(kMODOneShotLoops); m_playBehaviour.set(kMODSampleSwap); return ok; } #ifndef MODPLUG_NO_FILESAVE bool CSoundFile::SaveMod(const mpt::PathString &filename) const { FILE *f; if(m_nChannels == 0 || filename.empty()) return false; if((f = mpt_fopen(filename, "wb")) == nullptr) return false; // Write song title { char name[20]; mpt::String::Write(name, m_songName); fwrite(name, 20, 1, f); } std::vector sampleLength(32, 0); std::vector sampleSource(32, 0); if(GetNumInstruments()) { INSTRUMENTINDEX lastIns = std::min(INSTRUMENTINDEX(31), GetNumInstruments()); for(INSTRUMENTINDEX ins = 1; ins <= lastIns; ins++) if (Instruments[ins]) { // Find some valid sample associated with this instrument. for(size_t i = 0; i < CountOf(Instruments[ins]->Keyboard); i++) { if(Instruments[ins]->Keyboard[i] > 0 && Instruments[ins]->Keyboard[i] <= GetNumSamples()) { sampleSource[ins] = Instruments[ins]->Keyboard[i]; break; } } } } else { for(SAMPLEINDEX i = 1; i <= 31; i++) { sampleSource[i] = i; } } // Write sample headers for(SAMPLEINDEX smp = 1; smp <= 31; smp++) { MODSampleHeader sampleHeader; mpt::String::Write(sampleHeader.name, m_szNames[sampleSource[smp]]); sampleLength[smp] = sampleHeader.ConvertToMOD(sampleSource[smp] <= GetNumSamples() ? GetSample(sampleSource[smp]) : ModSample(MOD_TYPE_MOD)); fwrite(&sampleHeader, sizeof(sampleHeader), 1, f); } // Write order list MODFileHeader fileHeader; MemsetZero(fileHeader); PATTERNINDEX writePatterns = 0; uint8 writtenOrders = 0; for(ORDERINDEX ord = 0; ord < Order().GetLength() && writtenOrders < 128; ord++) { // Ignore +++ and --- patterns in order list, as well as high patterns (MOD officially only supports up to 128 patterns) if(ord == Order().GetRestartPos()) { fileHeader.restartPos = writtenOrders; } if(Order()[ord] < 128) { fileHeader.orderList[writtenOrders++] = static_cast(Order()[ord]); if(writePatterns <= Order()[ord]) { writePatterns = Order()[ord] + 1; } } } fileHeader.numOrders = writtenOrders; fwrite(&fileHeader, sizeof(fileHeader), 1, f); // Write magic bytes char modMagic[4]; CHANNELINDEX writeChannels = std::min(CHANNELINDEX(99), GetNumChannels()); if(writeChannels == 4) { // ProTracker may not load files with more than 64 patterns correctly if we do not specify the M!K! magic. if(writePatterns <= 64) memcpy(modMagic, "M.K.", 4); else memcpy(modMagic, "M!K!", 4); } else if(writeChannels < 10) { memcpy(modMagic, "0CHN", 4); modMagic[0] += static_cast(writeChannels); } else { memcpy(modMagic, "00CH", 4); modMagic[0] += static_cast(writeChannels / 10u); modMagic[1] += static_cast(writeChannels % 10u); } fwrite(modMagic, 4, 1, f); // Write patterns std::vector events; for(PATTERNINDEX pat = 0; pat < writePatterns; pat++) { if(!Patterns.IsValidPat(pat)) { // Invent empty pattern events.assign(writeChannels * 64 * 4, 0); fwrite(events.data(), events.size(), 1, f); continue; } for(ROWINDEX row = 0; row < 64; row++) { if(row >= Patterns[pat].GetNumRows()) { // Invent empty row events.assign(writeChannels * 4, 0); fwrite(events.data(), events.size(), 1, f); continue; } PatternRow rowBase = Patterns[pat].GetRow(row); events.resize(writeChannels * 4); size_t eventByte = 0; for(CHANNELINDEX chn = 0; chn < writeChannels; chn++) { ModCommand &m = rowBase[chn]; uint8 command = m.command, param = m.param; ModSaveCommand(command, param, false, true); if(m.volcmd == VOLCMD_VOLUME && !command && !param) { // Maybe we can save some volume commands... command = 0x0C; param = MIN(m.vol, 64); } uint16 period = 0; // Convert note to period if(m.note >= 36 + NOTE_MIN && m.note < CountOf(ProTrackerPeriodTable) + 36 + NOTE_MIN) { period = ProTrackerPeriodTable[m.note - 36 - NOTE_MIN]; } uint8 instr = (m.instr <= 31) ? m.instr : 0; events[eventByte++] = ((period >> 8) & 0x0F) | (instr & 0x10); events[eventByte++] = period & 0xFF; events[eventByte++] = ((instr & 0x0F) << 4) | (command & 0x0F); events[eventByte++] = param; } fwrite(events.data(), eventByte, 1, f); } } //Check for unsaved patterns for(PATTERNINDEX pat = writePatterns; pat < Patterns.Size(); pat++) { if(Patterns.IsValidPat(pat)) { AddToLog("Warning: This track contains at least one pattern after the highest pattern number referred to in the sequence. Such patterns are not saved in the MOD format."); break; } } // Writing samples for(SAMPLEINDEX smp = 1; smp <= 31; smp++) { if(sampleLength[smp] == 0) { continue; } const ModSample &sample = Samples[sampleSource[smp]]; const long sampleStart = ftell(f); const size_t writtenBytes = MODSampleHeader::GetSampleFormat().WriteSample(f, sample, sampleLength[smp]); const int8 silence[] = { 0, 0 }; // Write padding byte if the sample size is odd. if((writtenBytes % 2u) != 0) { fwrite(silence, 1, 1, f); } if(!sample.uFlags[CHN_LOOP] && writtenBytes >= 2) { // First two bytes of oneshot samples have to be 0 due to PT's one-shot loop const long sampleEnd = ftell(f); fseek(f, sampleStart, SEEK_SET); fwrite(&silence, 2, 1, f); fseek(f, sampleEnd, SEEK_SET); } } fclose(f); return true; } #endif // MODPLUG_NO_FILESAVE OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/soundlib/Tables.cpp0000644000372100037210000012117213176340505020023 00000000000000/* * Tables.cpp * ---------- * Purpose: Effect, interpolation, data and other pre-calculated tables. * Notes : (currently none) * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Tables.h" #include #include "Sndfile.h" #include "Resampler.h" #include "WindowedFIR.h" OPENMPT_NAMESPACE_BEGIN ///////////////////////////////////////////////////////////////////////////// // Note Name Tables const char NoteNamesSharp[12][4] = { "C-", "C#", "D-", "D#", "E-", "F-", "F#", "G-", "G#", "A-", "A#", "B-" }; const char NoteNamesFlat[12][4] = { "C-", "Db", "D-", "Eb", "E-", "F-", "Gb", "G-", "Ab", "A-", "Bb", "B-" }; /////////////////////////////////////////////////////////// // File Formats Information (name, extension, etc) struct ModFormatInfo { MODTYPE format; // MOD_TYPE_XXXX const MPT_UCHAR_TYPE *name; // "ProTracker" const char *extension; // "mod" }; // remember to also update libopenmpt/foo_openmpt.cpp (all other plugins read these dynamically) static constexpr ModFormatInfo modFormatInfo[] = { { MOD_TYPE_MOD, MPT_ULITERAL("ProTracker"), "mod" }, { MOD_TYPE_S3M, MPT_ULITERAL("ScreamTracker 3"), "s3m" }, { MOD_TYPE_XM, MPT_ULITERAL("FastTracker II"), "xm" }, { MOD_TYPE_IT, MPT_ULITERAL("Impulse Tracker"), "it" }, #ifdef MPT_EXTERNAL_SAMPLES { MOD_TYPE_IT, MPT_ULITERAL("Impulse Tracker Project"), "itp" }, #endif { MOD_TYPE_MPT, MPT_ULITERAL("OpenMPT"), "mptm" }, { MOD_TYPE_STM, MPT_ULITERAL("ScreamTracker 2"), "stm" }, { MOD_TYPE_MOD, MPT_ULITERAL("ProTracker"), "pt36" }, { MOD_TYPE_MOD, MPT_ULITERAL("NoiseTracker"), "nst" }, { MOD_TYPE_MOD, MPT_ULITERAL("Soundtracker"), "m15" }, { MOD_TYPE_MOD, MPT_ULITERAL("Soundtracker"), "stk" }, { MOD_TYPE_MOD, MPT_ULITERAL("SoundTracker 2.6"), "st26" }, { MOD_TYPE_MOD, MPT_ULITERAL("Ice Tracker"), "ice" }, { MOD_TYPE_MOD, MPT_ULITERAL("Mod's Grave"), "wow" }, { MOD_TYPE_ULT, MPT_ULITERAL("UltraTracker"), "ult" }, { MOD_TYPE_669, MPT_ULITERAL("Composer 669 / UNIS 669"), "669" }, { MOD_TYPE_MTM, MPT_ULITERAL("MultiTracker"), "mtm" }, { MOD_TYPE_MED, MPT_ULITERAL("OctaMed"), "med" }, { MOD_TYPE_FAR, MPT_ULITERAL("Farandole Composer"), "far" }, { MOD_TYPE_MDL, MPT_ULITERAL("Digitrakker"), "mdl" }, { MOD_TYPE_AMS, MPT_ULITERAL("Extreme's Tracker"), "ams" }, { MOD_TYPE_AMS2, MPT_ULITERAL("Velvet Studio"), "ams" }, { MOD_TYPE_DSM, MPT_ULITERAL("DSIK Format"), "dsm" }, { MOD_TYPE_AMF, MPT_ULITERAL("DSMI"), "amf" }, { MOD_TYPE_AMF0, MPT_ULITERAL("ASYLUM"), "amf" }, { MOD_TYPE_OKT, MPT_ULITERAL("Oktalyzer"), "okt" }, { MOD_TYPE_DMF, MPT_ULITERAL("X-Tracker"), "dmf" }, { MOD_TYPE_PTM, MPT_ULITERAL("PolyTracker"), "ptm" }, { MOD_TYPE_PSM, MPT_ULITERAL("Epic Megagames MASI"), "psm" }, { MOD_TYPE_MT2, MPT_ULITERAL("MadTracker 2"), "mt2" }, { MOD_TYPE_DBM, MPT_ULITERAL("DigiBooster Pro"), "dbm" }, { MOD_TYPE_DIGI, MPT_ULITERAL("DigiBooster"), "digi" }, { MOD_TYPE_IMF, MPT_ULITERAL("Imago Orpheus"), "imf" }, { MOD_TYPE_J2B, MPT_ULITERAL("Galaxy Sound System"), "j2b" }, { MOD_TYPE_PLM, MPT_ULITERAL("Disorder Tracker 2"), "plm" }, { MOD_TYPE_SFX, MPT_ULITERAL("SoundFX"), "sfx" }, { MOD_TYPE_SFX, MPT_ULITERAL("SoundFX"), "sfx2" }, { MOD_TYPE_SFX, MPT_ULITERAL("MultiMedia Sound"), "mms" }, { MOD_TYPE_STP, MPT_ULITERAL("Soundtracker Pro II"), "stp" }, { MOD_TYPE_DTM, MPT_ULITERAL("Digital Tracker"), "dtm" }, #ifndef NO_ARCHIVE_SUPPORT // Compressed modules { MOD_TYPE_MOD, MPT_ULITERAL("ProTracker"), "mdz" }, { MOD_TYPE_MOD, MPT_ULITERAL("ProTracker"), "mdr" }, { MOD_TYPE_S3M, MPT_ULITERAL("ScreamTracker 3"), "s3z" }, { MOD_TYPE_XM, MPT_ULITERAL("FastTracker II"), "xmz" }, { MOD_TYPE_IT, MPT_ULITERAL("Impulse Tracker"), "itz" }, { MOD_TYPE_MPT, MPT_ULITERAL("OpenMPT"), "mptmz" }, #endif }; struct ModContainerInfo { MODCONTAINERTYPE format; // MOD_CONTAINERTYPE_XXXX const MPT_UCHAR_TYPE *name; // "Unreal Music" const char *extension; // "umx" }; // remember to also update libopenmpt/libopenmpt_foobar2000.cpp (all other plugins read these dynamically) static constexpr ModContainerInfo modContainerInfo[] = { // Container formats { MOD_CONTAINERTYPE_GDM, MPT_ULITERAL("General Digital Music"), "gdm" }, { MOD_CONTAINERTYPE_UMX, MPT_ULITERAL("Unreal Music"), "umx" }, { MOD_CONTAINERTYPE_MO3, MPT_ULITERAL("Un4seen MO3"), "mo3" }, { MOD_CONTAINERTYPE_XPK, MPT_ULITERAL("XPK packed"), "xpk" }, { MOD_CONTAINERTYPE_PP20, MPT_ULITERAL("PowerPack PP20"), "ppm" }, { MOD_CONTAINERTYPE_MMCMP, MPT_ULITERAL("Music Module Compressor"), "mmcmp" } #ifdef MODPLUG_TRACKER , { MOD_CONTAINERTYPE_WAV, MPT_ULITERAL("Wave"), "wav" }, { MOD_CONTAINERTYPE_UAX, MPT_ULITERAL("Unreal Sounds"), "uax" } #endif }; #ifdef MODPLUG_TRACKER static constexpr ModFormatInfo otherFormatInfo[] = { { MOD_TYPE_MID, MPT_ULITERAL("MIDI"), "mid" }, { MOD_TYPE_MID, MPT_ULITERAL("MIDI"), "rmi" }, { MOD_TYPE_MID, MPT_ULITERAL("MIDI"), "smf" } }; #endif struct ModCharsetInfo { MODTYPE type; mpt::Charset charset; }; static constexpr ModCharsetInfo ModCharsetInfos[] = { // Amiga { MOD_TYPE_OKT , mpt::CharsetISO8859_1 }, { MOD_TYPE_DBM , mpt::CharsetISO8859_1 }, { MOD_TYPE_DIGI, mpt::CharsetISO8859_1 }, { MOD_TYPE_SFX , mpt::CharsetISO8859_1 }, { MOD_TYPE_STP, mpt::CharsetISO8859_1 }, // Amiga // DOS { MOD_TYPE_MOD , mpt::CharsetISO8859_1 }, { MOD_TYPE_MED , mpt::CharsetISO8859_1 }, // Atari { MOD_TYPE_DTM , mpt::CharsetISO8859_1 }, // DOS { MOD_TYPE_S3M , mpt::CharsetCP437 }, { MOD_TYPE_XM , mpt::CharsetCP437 }, { MOD_TYPE_MTM , mpt::CharsetCP437 }, { MOD_TYPE_IT , mpt::CharsetCP437 }, { MOD_TYPE_669 , mpt::CharsetCP437 }, { MOD_TYPE_STM , mpt::CharsetCP437 }, { MOD_TYPE_FAR , mpt::CharsetCP437 }, { MOD_TYPE_AMF , mpt::CharsetCP437 }, { MOD_TYPE_AMF0, mpt::CharsetCP437 }, { MOD_TYPE_MDL , mpt::CharsetCP437 }, { MOD_TYPE_DMF , mpt::CharsetCP437 }, { MOD_TYPE_PTM , mpt::CharsetCP437 }, { MOD_TYPE_PSM , mpt::CharsetCP437 }, { MOD_TYPE_J2B , mpt::CharsetCP437 }, { MOD_TYPE_IMF , mpt::CharsetCP437 }, { MOD_TYPE_ULT , mpt::CharsetCP437 }, { MOD_TYPE_AMS , mpt::CharsetCP437 }, { MOD_TYPE_AMS2, mpt::CharsetCP437 }, { MOD_TYPE_DSM , mpt::CharsetCP437 }, // Windows { MOD_TYPE_MT2 , mpt::CharsetWindows1252}, { MOD_TYPE_MPT , mpt::CharsetWindows1252}, // random stuff { MOD_TYPE_MID , mpt::CharsetASCII }, }; mpt::Charset CSoundFile::GetCharsetFromModType(MODTYPE modType) { // This is just a rough heuristic. // It could be improved by adjusting the charset according to the tracker that had been used to save the file. for(const auto &charsetInfo : ModCharsetInfos) { if(charsetInfo.type == modType) { return charsetInfo.charset; } } // fallback return mpt::CharsetASCII; } std::vector CSoundFile::GetSupportedExtensions(bool otherFormats) { std::vector exts; for(const auto &formatInfo : modFormatInfo) { // Avoid dupes in list if(exts.empty() || strcmp(formatInfo.extension, exts.back())) { exts.push_back(formatInfo.extension); } } for(const auto &containerInfo : modContainerInfo) { // Avoid dupes in list if(exts.empty() || strcmp(containerInfo.extension, exts.back())) { exts.push_back(containerInfo.extension); } } #ifdef MODPLUG_TRACKER if(otherFormats) { for(const auto &formatInfo : otherFormatInfo) { exts.push_back(formatInfo.extension); } } #else MPT_UNREFERENCED_PARAMETER(otherFormats); #endif return exts; } static bool IsEqualExtension(const char *a, const char *b) { std::size_t lena = std::strlen(a); std::size_t lenb = std::strlen(b); if(lena != lenb) { return false; } return mpt::CompareNoCaseAscii(a, b, lena) == 0; } bool CSoundFile::IsExtensionSupported(const char *ext) { if(ext == nullptr || ext[0] == 0) { return false; } for(const auto &formatInfo : modFormatInfo) { if(IsEqualExtension(ext, formatInfo.extension)) { return true; } } for(const auto &containerInfo : modContainerInfo) { if(IsEqualExtension(ext, containerInfo.extension)) { return true; } } return false; } mpt::ustring CSoundFile::ModTypeToString(MODTYPE modtype) { for(const auto &formatInfo : modFormatInfo) { if(formatInfo.format & modtype) { return mpt::ToUnicode(mpt::CharsetUTF8, formatInfo.extension); } } return mpt::ustring(); } mpt::ustring CSoundFile::ModContainerTypeToString(MODCONTAINERTYPE containertype) { for(const auto &containerInfo : modContainerInfo) { if(containerInfo.format == containertype) { return mpt::ToUnicode(mpt::CharsetUTF8, containerInfo.extension); } } return mpt::ustring(); } mpt::ustring CSoundFile::ModTypeToTracker(MODTYPE modtype) { std::set retvals; mpt::ustring retval; if(modtype == MOD_TYPE_MOD) { // special case MOD return MPT_USTRING("Generic Amiga / PC MOD file"); } for(const auto &formatInfo : modFormatInfo) { if(formatInfo.format & modtype) { mpt::ustring name = formatInfo.name; if(retvals.find(name) == retvals.end()) { retvals.insert(name); if(!retval.empty()) { retval += MPT_USTRING(" / "); } retval += name; } } } return retval; } mpt::ustring CSoundFile::ModContainerTypeToTracker(MODCONTAINERTYPE containertype) { std::set retvals; mpt::ustring retval; for(const auto &containerInfo : modContainerInfo) { if(containerInfo.format == containertype) { mpt::ustring name = containerInfo.name; if(retvals.find(name) == retvals.end()) { retvals.insert(name); if(!retval.empty()) { retval += MPT_USTRING(" / "); } retval += name; } } } return retval; } /////////////////////////////////////////////////////////////////////// const uint8 ImpulseTrackerPortaVolCmd[16] = { 0x00, 0x01, 0x04, 0x08, 0x10, 0x20, 0x40, 0x60, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; // Period table for Protracker octaves 0-5: const uint16 ProTrackerPeriodTable[6*12] = { 1712,1616,1524,1440,1356,1280,1208,1140,1076,1016,960,907, 856,808,762,720,678,640,604,570,538,508,480,453, 428,404,381,360,339,320,302,285,269,254,240,226, 214,202,190,180,170,160,151,143,135,127,120,113, 107,101,95,90,85,80,75,71,67,63,60,56, 53,50,47,45,42,40,37,35,33,31,30,28 }; const uint16 ProTrackerTunedPeriods[16*12] = { 1712,1616,1524,1440,1356,1280,1208,1140,1076,1016,960,907, 1700,1604,1514,1430,1348,1274,1202,1134,1070,1010,954,900, 1688,1592,1504,1418,1340,1264,1194,1126,1064,1004,948,894, 1676,1582,1492,1408,1330,1256,1184,1118,1056,996,940,888, 1664,1570,1482,1398,1320,1246,1176,1110,1048,990,934,882, 1652,1558,1472,1388,1310,1238,1168,1102,1040,982,926,874, 1640,1548,1460,1378,1302,1228,1160,1094,1032,974,920,868, 1628,1536,1450,1368,1292,1220,1150,1086,1026,968,914,862, 1814,1712,1616,1524,1440,1356,1280,1208,1140,1076,1016,960, 1800,1700,1604,1514,1430,1350,1272,1202,1134,1070,1010,954, 1788,1688,1592,1504,1418,1340,1264,1194,1126,1064,1004,948, 1774,1676,1582,1492,1408,1330,1256,1184,1118,1056,996,940, 1762,1664,1570,1482,1398,1320,1246,1176,1110,1048,988,934, 1750,1652,1558,1472,1388,1310,1238,1168,1102,1040,982,926, 1736,1640,1548,1460,1378,1302,1228,1160,1094,1032,974,920, 1724,1628,1536,1450,1368,1292,1220,1150,1086,1026,968,914 }; // Table for Invert Loop and Funk Repeat effects (EFx, .MOD only) const uint8 ModEFxTable[16] = { 0, 5, 6, 7, 8, 10, 11, 13, 16, 19, 22, 26, 32, 43, 64, 128 }; // S3M C-4 periods const uint16 FreqS3MTable[16] = { 1712,1616,1524,1440,1356,1280, 1208,1140,1076,1016,960,907, 0,0,0,0 }; // S3M FineTune frequencies const uint16 S3MFineTuneTable[16] = { 7895,7941,7985,8046,8107,8169,8232,8280, 8363,8413,8463,8529,8581,8651,8723,8757, // 8363*2^((i-8)/(12*8)) }; // Sinus table const int8 ModSinusTable[64] = { 0,12,25,37,49,60,71,81,90,98,106,112,117,122,125,126, 127,126,125,122,117,112,106,98,90,81,71,60,49,37,25,12, 0,-12,-25,-37,-49,-60,-71,-81,-90,-98,-106,-112,-117,-122,-125,-126, -127,-126,-125,-122,-117,-112,-106,-98,-90,-81,-71,-60,-49,-37,-25,-12 }; // Random wave table const int8 ModRandomTable[64] = { 98,-127,-43,88,102,41,-65,-94,125,20,-71,-86,-70,-32,-16,-96, 17,72,107,-5,116,-69,-62,-40,10,-61,65,109,-18,-38,-13,-76, -23,88,21,-94,8,106,21,-112,6,109,20,-88,-30,9,-127,118, 42,-34,89,-4,-51,-72,21,-29,112,123,84,-101,-92,98,-54,-95 }; // Impulse Tracker sinus table (ITTECH.TXT) const int8 ITSinusTable[256] = { 0, 2, 3, 5, 6, 8, 9, 11, 12, 14, 16, 17, 19, 20, 22, 23, 24, 26, 27, 29, 30, 32, 33, 34, 36, 37, 38, 39, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 59, 60, 60, 61, 61, 62, 62, 62, 63, 63, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 63, 63, 63, 62, 62, 62, 61, 61, 60, 60, 59, 59, 58, 57, 56, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 39, 38, 37, 36, 34, 33, 32, 30, 29, 27, 26, 24, 23, 22, 20, 19, 17, 16, 14, 12, 11, 9, 8, 6, 5, 3, 2, 0, -2, -3, -5, -6, -8, -9,-11,-12,-14,-16,-17,-19,-20,-22,-23, -24,-26,-27,-29,-30,-32,-33,-34,-36,-37,-38,-39,-41,-42,-43,-44, -45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-56,-57,-58,-59, -59,-60,-60,-61,-61,-62,-62,-62,-63,-63,-63,-64,-64,-64,-64,-64, -64,-64,-64,-64,-64,-64,-63,-63,-63,-62,-62,-62,-61,-61,-60,-60, -59,-59,-58,-57,-56,-56,-55,-54,-53,-52,-51,-50,-49,-48,-47,-46, -45,-44,-43,-42,-41,-39,-38,-37,-36,-34,-33,-32,-30,-29,-27,-26, -24,-23,-22,-20,-19,-17,-16,-14,-12,-11, -9, -8, -6, -5, -3, -2, }; // volume fade tables for Retrig Note: const int8 retrigTable1[16] = { 0, 0, 0, 0, 0, 0, 10, 8, 0, 0, 0, 0, 0, 0, 24, 32 }; const int8 retrigTable2[16] = { 0, -1, -2, -4, -8, -16, 0, 0, 0, 1, 2, 4, 8, 16, 0, 0 }; const uint16 XMPeriodTable[104] = { 907,900,894,887,881,875,868,862,856,850,844,838,832,826,820,814, 808,802,796,791,785,779,774,768,762,757,752,746,741,736,730,725, 720,715,709,704,699,694,689,684,678,675,670,665,660,655,651,646, 640,636,632,628,623,619,614,610,604,601,597,592,588,584,580,575, 570,567,563,559,555,551,547,543,538,535,532,528,524,520,516,513, 508,505,502,498,494,491,487,484,480,477,474,470,467,463,460,457, 453,450,447,443,440,437,434,431 }; // floor(8363 * 64 * 2**(-n/768)) // 768 = 64 period steps for 12 notes // Table is for highest possible octave const uint32 XMLinearTable[768] = { 535232,534749,534266,533784,533303,532822,532341,531861, 531381,530902,530423,529944,529466,528988,528511,528034, 527558,527082,526607,526131,525657,525183,524709,524236, 523763,523290,522818,522346,521875,521404,520934,520464, 519994,519525,519057,518588,518121,517653,517186,516720, 516253,515788,515322,514858,514393,513929,513465,513002, 512539,512077,511615,511154,510692,510232,509771,509312, 508852,508393,507934,507476,507018,506561,506104,505647, 505191,504735,504280,503825,503371,502917,502463,502010, 501557,501104,500652,500201,499749,499298,498848,498398, 497948,497499,497050,496602,496154,495706,495259,494812, 494366,493920,493474,493029,492585,492140,491696,491253, 490809,490367,489924,489482,489041,488600,488159,487718, 487278,486839,486400,485961,485522,485084,484647,484210, 483773,483336,482900,482465,482029,481595,481160,480726, 480292,479859,479426,478994,478562,478130,477699,477268, 476837,476407,475977,475548,475119,474690,474262,473834, 473407,472979,472553,472126,471701,471275,470850,470425, 470001,469577,469153,468730,468307,467884,467462,467041, 466619,466198,465778,465358,464938,464518,464099,463681, 463262,462844,462427,462010,461593,461177,460760,460345, 459930,459515,459100,458686,458272,457859,457446,457033, 456621,456209,455797,455386,454975,454565,454155,453745, 453336,452927,452518,452110,451702,451294,450887,450481, 450074,449668,449262,448857,448452,448048,447644,447240, 446836,446433,446030,445628,445226,444824,444423,444022, 443622,443221,442821,442422,442023,441624,441226,440828, 440430,440033,439636,439239,438843,438447,438051,437656, 437261,436867,436473,436079,435686,435293,434900,434508, 434116,433724,433333,432942,432551,432161,431771,431382, 430992,430604,430215,429827,429439,429052,428665,428278, 427892,427506,427120,426735,426350,425965,425581,425197, 424813,424430,424047,423665,423283,422901,422519,422138, 421757,421377,420997,420617,420237,419858,419479,419101, 418723,418345,417968,417591,417214,416838,416462,416086, 415711,415336,414961,414586,414212,413839,413465,413092, 412720,412347,411975,411604,411232,410862,410491,410121, 409751,409381,409012,408643,408274,407906,407538,407170, 406803,406436,406069,405703,405337,404971,404606,404241, 403876,403512,403148,402784,402421,402058,401695,401333, 400970,400609,400247,399886,399525,399165,398805,398445, 398086,397727,397368,397009,396651,396293,395936,395579, 395222,394865,394509,394153,393798,393442,393087,392733, 392378,392024,391671,391317,390964,390612,390259,389907, 389556,389204,388853,388502,388152,387802,387452,387102, 386753,386404,386056,385707,385359,385012,384664,384317, 383971,383624,383278,382932,382587,382242,381897,381552, 381208,380864,380521,380177,379834,379492,379149,378807, 378466,378124,377783,377442,377102,376762,376422,376082, 375743,375404,375065,374727,374389,374051,373714,373377, 373040,372703,372367,372031,371695,371360,371025,370690, 370356,370022,369688,369355,369021,368688,368356,368023, 367691,367360,367028,366697,366366,366036,365706,365376, 365046,364717,364388,364059,363731,363403,363075,362747, 362420,362093,361766,361440,361114,360788,360463,360137, 359813,359488,359164,358840,358516,358193,357869,357547, 357224,356902,356580,356258,355937,355616,355295,354974, 354654,354334,354014,353695,353376,353057,352739,352420, 352103,351785,351468,351150,350834,350517,350201,349885, 349569,349254,348939,348624,348310,347995,347682,347368, 347055,346741,346429,346116,345804,345492,345180,344869, 344558,344247,343936,343626,343316,343006,342697,342388, 342079,341770,341462,341154,340846,340539,340231,339924, 339618,339311,339005,338700,338394,338089,337784,337479, 337175,336870,336566,336263,335959,335656,335354,335051, 334749,334447,334145,333844,333542,333242,332941,332641, 332341,332041,331741,331442,331143,330844,330546,330247, 329950,329652,329355,329057,328761,328464,328168,327872, 327576,327280,326985,326690,326395,326101,325807,325513, 325219,324926,324633,324340,324047,323755,323463,323171, 322879,322588,322297,322006,321716,321426,321136,320846, 320557,320267,319978,319690,319401,319113,318825,318538, 318250,317963,317676,317390,317103,316817,316532,316246, 315961,315676,315391,315106,314822,314538,314254,313971, 313688,313405,313122,312839,312557,312275,311994,311712, 311431,311150,310869,310589,310309,310029,309749,309470, 309190,308911,308633,308354,308076,307798,307521,307243, 306966,306689,306412,306136,305860,305584,305308,305033, 304758,304483,304208,303934,303659,303385,303112,302838, 302565,302292,302019,301747,301475,301203,300931,300660, 300388,300117,299847,299576,299306,299036,298766,298497, 298227,297958,297689,297421,297153,296884,296617,296349, 296082,295815,295548,295281,295015,294749,294483,294217, 293952,293686,293421,293157,292892,292628,292364,292100, 291837,291574,291311,291048,290785,290523,290261,289999, 289737,289476,289215,288954,288693,288433,288173,287913, 287653,287393,287134,286875,286616,286358,286099,285841, 285583,285326,285068,284811,284554,284298,284041,283785, 283529,283273,283017,282762,282507,282252,281998,281743, 281489,281235,280981,280728,280475,280222,279969,279716, 279464,279212,278960,278708,278457,278206,277955,277704, 277453,277203,276953,276703,276453,276204,275955,275706, 275457,275209,274960,274712,274465,274217,273970,273722, 273476,273229,272982,272736,272490,272244,271999,271753, 271508,271263,271018,270774,270530,270286,270042,269798, 269555,269312,269069,268826,268583,268341,268099,267857 }; const int8 ft2VibratoTable[256] = { 0,-2,-3,-5,-6,-8,-9,-11,-12,-14,-16,-17,-19,-20,-22,-23, -24,-26,-27,-29,-30,-32,-33,-34,-36,-37,-38,-39,-41,-42, -43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56, -56,-57,-58,-59,-59,-60,-60,-61,-61,-62,-62,-62,-63,-63, -63,-64,-64,-64,-64,-64,-64,-64,-64,-64,-64,-64,-63,-63, -63,-62,-62,-62,-61,-61,-60,-60,-59,-59,-58,-57,-56,-56, -55,-54,-53,-52,-51,-50,-49,-48,-47,-46,-45,-44,-43,-42, -41,-39,-38,-37,-36,-34,-33,-32,-30,-29,-27,-26,-24,-23, -22,-20,-19,-17,-16,-14,-12,-11,-9,-8,-6,-5,-3,-2,0, 2,3,5,6,8,9,11,12,14,16,17,19,20,22,23,24,26,27,29,30, 32,33,34,36,37,38,39,41,42,43,44,45,46,47,48,49,50,51, 52,53,54,55,56,56,57,58,59,59,60,60,61,61,62,62,62,63, 63,63,64,64,64,64,64,64,64,64,64,64,64,63,63,63,62,62, 62,61,61,60,60,59,59,58,57,56,56,55,54,53,52,51,50,49, 48,47,46,45,44,43,42,41,39,38,37,36,34,33,32,30,29,27, 26,24,23,22,20,19,17,16,14,12,11,9,8,6,5,3,2 }; // round(65536 * 2**(n/768)) // 768 = 64 extra-fine finetune steps for 12 notes // Table content is in 16.16 format const uint32 FineLinearSlideUpTable[16] = { 65536, 65595, 65654, 65714, 65773, 65832, 65892, 65951, 66011, 66071, 66130, 66190, 66250, 66309, 66369, 66429 }; // round(65536 * 2**(-n/768)) // 768 = 64 extra-fine finetune steps for 12 notes // Table content is in 16.16 format // Note that there are a few errors in this table (typos?), but well, this table comes straight from Impulse Tracker's source... // Entry 0 (65535) should be 65536 (this value is unused and most likely stored this way so that it fits in a 16-bit integer) // Entry 11 (64888) should be 64889 - rounding error? // Entry 15 (64645) should be 64655 - typo? const uint32 FineLinearSlideDownTable[16] = { 65535, 65477, 65418, 65359, 65300, 65241, 65182, 65123, 65065, 65006, 64947, 64888, 64830, 64772, 64713, 64645 }; // round(65536 * 2**(n/192)) // 192 = 16 finetune steps for 12 notes // Table content is in 16.16 format const uint32 LinearSlideUpTable[256] = { 65536, 65773, 66011, 66250, 66489, 66730, 66971, 67213, 67456, 67700, 67945, 68191, 68438, 68685, 68933, 69183, 69433, 69684, 69936, 70189, 70443, 70698, 70953, 71210, 71468, 71726, 71985, 72246, 72507, 72769, 73032, 73297, 73562, 73828, 74095, 74363, 74632, 74902, 75172, 75444, 75717, 75991, 76266, 76542, 76819, 77096, 77375, 77655, 77936, 78218, 78501, 78785, 79069, 79355, 79642, 79930, 80220, 80510, 80801, 81093, 81386, 81681, 81976, 82273, 82570, 82869, 83169, 83469, 83771, 84074, 84378, 84683, 84990, 85297, 85606, 85915, 86226, 86538, 86851, 87165, 87480, 87796, 88114, 88433, 88752, 89073, 89396, 89719, 90043, 90369, 90696, 91024, 91353, 91684, 92015, 92348, 92682, 93017, 93354, 93691, 94030, 94370, 94711, 95054, 95398, 95743, 96089, 96436, 96785, 97135, 97487, 97839, 98193, 98548, 98905, 99262, 99621, 99982, 100343, 100706, 101070, 101436, 101803, 102171, 102540, 102911, 103283, 103657, 104032, 104408, 104786, 105165, 105545, 105927, 106310, 106694, 107080, 107468, 107856, 108246, 108638, 109031, 109425, 109821, 110218, 110617, 111017, 111418, 111821, 112226, 112631, 113039, 113448, 113858, 114270, 114683, 115098, 115514, 115932, 116351, 116772, 117194, 117618, 118043, 118470, 118899, 119329, 119760, 120194, 120628, 121065, 121502, 121942, 122383, 122825, 123270, 123715, 124163, 124612, 125063, 125515, 125969, 126425, 126882, 127341, 127801, 128263, 128727, 129193, 129660, 130129, 130600, 131072, 131546, 132022, 132499, 132978, 133459, 133942, 134427, 134913, 135401, 135890, 136382, 136875, 137370, 137867, 138366, 138866, 139368, 139872, 140378, 140886, 141395, 141907, 142420, 142935, 143452, 143971, 144491, 145014, 145539, 146065, 146593, 147123, 147655, 148189, 148725, 149263, 149803, 150345, 150889, 151434, 151982, 152532, 153083, 153637, 154193, 154750, 155310, 155872, 156435, 157001, 157569, 158139, 158711, 159285, 159861, 160439, 161019, 161602, 162186, 162773, 163361, 163952, 164545 }; // round(65536 * 2**(-n/192)) // 192 = 16 finetune steps for 12 notes // Table content is in 16.16 format const uint32 LinearSlideDownTable[256] = { 65536, 65300, 65065, 64830, 64596, 64364, 64132, 63901, 63670, 63441, 63212, 62984, 62757, 62531, 62306, 62081, 61858, 61635, 61413, 61191, 60971, 60751, 60532, 60314, 60097, 59880, 59664, 59449, 59235, 59022, 58809, 58597, 58386, 58176, 57966, 57757, 57549, 57341, 57135, 56929, 56724, 56519, 56316, 56113, 55911, 55709, 55508, 55308, 55109, 54910, 54713, 54515, 54319, 54123, 53928, 53734, 53540, 53347, 53155, 52963, 52773, 52582, 52393, 52204, 52016, 51829, 51642, 51456, 51270, 51085, 50901, 50718, 50535, 50353, 50172, 49991, 49811, 49631, 49452, 49274, 49097, 48920, 48743, 48568, 48393, 48218, 48044, 47871, 47699, 47527, 47356, 47185, 47015, 46846, 46677, 46509, 46341, 46174, 46008, 45842, 45677, 45512, 45348, 45185, 45022, 44859, 44698, 44537, 44376, 44216, 44057, 43898, 43740, 43582, 43425, 43269, 43113, 42958, 42803, 42649, 42495, 42342, 42189, 42037, 41886, 41735, 41584, 41434, 41285, 41136, 40988, 40840, 40693, 40547, 40400, 40255, 40110, 39965, 39821, 39678, 39535, 39392, 39250, 39109, 38968, 38828, 38688, 38548, 38409, 38271, 38133, 37996, 37859, 37722, 37586, 37451, 37316, 37181, 37047, 36914, 36781, 36648, 36516, 36385, 36254, 36123, 35993, 35863, 35734, 35605, 35477, 35349, 35221, 35095, 34968, 34842, 34716, 34591, 34467, 34343, 34219, 34095, 33973, 33850, 33728, 33607, 33486, 33365, 33245, 33125, 33005, 32887, 32768, 32650, 32532, 32415, 32298, 32182, 32066, 31950, 31835, 31720, 31606, 31492, 31379, 31266, 31153, 31041, 30929, 30817, 30706, 30596, 30485, 30376, 30266, 30157, 30048, 29940, 29832, 29725, 29618, 29511, 29405, 29299, 29193, 29088, 28983, 28879, 28774, 28671, 28567, 28464, 28362, 28260, 28158, 28056, 27955, 27855, 27754, 27654, 27554, 27455, 27356, 27258, 27159, 27062, 26964, 26867, 26770, 26674, 26577, 26482, 26386, 26291, 26196, 26102 }; // FT2's square root panning law LUT. // Formula to generate this table: round(65536 * sqrt(n / 256)) const uint16 XMPanningTable[256] = { 0, 4096, 5793, 7094, 8192, 9159, 10033, 10837, 11585, 12288, 12953, 13585, 14189, 14768, 15326, 15864, 16384, 16888, 17378, 17854, 18318, 18770, 19212, 19644, 20066, 20480, 20886, 21283, 21674, 22058, 22435, 22806, 23170, 23530, 23884, 24232, 24576, 24915, 25249, 25580, 25905, 26227, 26545, 26859, 27170, 27477, 27780, 28081, 28378, 28672, 28963, 29251, 29537, 29819, 30099, 30377, 30652, 30924, 31194, 31462, 31727, 31991, 32252, 32511, 32768, 33023, 33276, 33527, 33776, 34024, 34270, 34514, 34756, 34996, 35235, 35472, 35708, 35942, 36175, 36406, 36636, 36864, 37091, 37316, 37540, 37763, 37985, 38205, 38424, 38642, 38858, 39073, 39287, 39500, 39712, 39923, 40132, 40341, 40548, 40755, 40960, 41164, 41368, 41570, 41771, 41972, 42171, 42369, 42567, 42763, 42959, 43154, 43348, 43541, 43733, 43925, 44115, 44305, 44494, 44682, 44869, 45056, 45242, 45427, 45611, 45795, 45977, 46160, 46341, 46522, 46702, 46881, 47059, 47237, 47415, 47591, 47767, 47942, 48117, 48291, 48465, 48637, 48809, 48981, 49152, 49322, 49492, 49661, 49830, 49998, 50166, 50332, 50499, 50665, 50830, 50995, 51159, 51323, 51486, 51649, 51811, 51972, 52134, 52294, 52454, 52614, 52773, 52932, 53090, 53248, 53405, 53562, 53719, 53874, 54030, 54185, 54340, 54494, 54647, 54801, 54954, 55106, 55258, 55410, 55561, 55712, 55862, 56012, 56162, 56311, 56459, 56608, 56756, 56903, 57051, 57198, 57344, 57490, 57636, 57781, 57926, 58071, 58215, 58359, 58503, 58646, 58789, 58931, 59073, 59215, 59357, 59498, 59639, 59779, 59919, 60059, 60199, 60338, 60477, 60615, 60753, 60891, 61029, 61166, 61303, 61440, 61576, 61712, 61848, 61984, 62119, 62254, 62388, 62523, 62657, 62790, 62924, 63057, 63190, 63323, 63455, 63587, 63719, 63850, 63982, 64113, 64243, 64374, 64504, 64634, 64763, 64893, 65022, 65151, 65279, 65408, }; // IT Vibrato -> OpenMPT/XM VibratoType const uint8 AutoVibratoIT2XM[8] = { VIB_SINE, VIB_RAMP_DOWN, VIB_SQUARE, VIB_RANDOM, VIB_RAMP_UP, 0, 0, 0 }; // OpenMPT/XM VibratoType -> IT Vibrato const uint8 AutoVibratoXM2IT[8] = { 0, 2, 4, 1, 3, 0, 0, 0 }; // Reversed sinc coefficients for 4x256 taps polyphase FIR resampling filter (SchismTracker's lutgen.c should generate a very similar table, but it's more precise) const int16 CResampler::FastSincTable[256*4] = { // Cubic Spline 0, 16384, 0, 0, -31, 16383, 32, 0, -63, 16381, 65, 0, -93, 16378, 100, -1, -124, 16374, 135, -1, -153, 16368, 172, -3, -183, 16361, 209, -4, -211, 16353, 247, -5, -240, 16344, 287, -7, -268, 16334, 327, -9, -295, 16322, 368, -12, -322, 16310, 410, -14, -348, 16296, 453, -17, -374, 16281, 497, -20, -400, 16265, 541, -23, -425, 16248, 587, -26, -450, 16230, 634, -30, -474, 16210, 681, -33, -497, 16190, 729, -37, -521, 16168, 778, -41, -543, 16145, 828, -46, -566, 16121, 878, -50, -588, 16097, 930, -55, -609, 16071, 982, -60, -630, 16044, 1035, -65, -651, 16016, 1089, -70, -671, 15987, 1144, -75, -691, 15957, 1199, -81, -710, 15926, 1255, -87, -729, 15894, 1312, -93, -748, 15861, 1370, -99, -766, 15827, 1428, -105, -784, 15792, 1488, -112, -801, 15756, 1547, -118, -818, 15719, 1608, -125, -834, 15681, 1669, -132, -850, 15642, 1731, -139, -866, 15602, 1794, -146, -881, 15561, 1857, -153, -896, 15520, 1921, -161, -911, 15477, 1986, -168, -925, 15434, 2051, -176, -939, 15390, 2117, -184, -952, 15344, 2184, -192, -965, 15298, 2251, -200, -978, 15251, 2319, -208, -990, 15204, 2387, -216, -1002, 15155, 2456, -225, -1014, 15106, 2526, -234, -1025, 15055, 2596, -242, -1036, 15004, 2666, -251, -1046, 14952, 2738, -260, -1056, 14899, 2810, -269, -1066, 14846, 2882, -278, -1075, 14792, 2955, -287, -1084, 14737, 3028, -296, -1093, 14681, 3102, -306, -1102, 14624, 3177, -315, -1110, 14567, 3252, -325, -1118, 14509, 3327, -334, -1125, 14450, 3403, -344, -1132, 14390, 3480, -354, -1139, 14330, 3556, -364, -1145, 14269, 3634, -374, -1152, 14208, 3712, -384, -1157, 14145, 3790, -394, -1163, 14082, 3868, -404, -1168, 14018, 3947, -414, -1173, 13954, 4027, -424, -1178, 13889, 4107, -434, -1182, 13823, 4187, -445, -1186, 13757, 4268, -455, -1190, 13690, 4349, -465, -1193, 13623, 4430, -476, -1196, 13555, 4512, -486, -1199, 13486, 4594, -497, -1202, 13417, 4676, -507, -1204, 13347, 4759, -518, -1206, 13276, 4842, -528, -1208, 13205, 4926, -539, -1210, 13134, 5010, -550, -1211, 13061, 5094, -560, -1212, 12989, 5178, -571, -1212, 12915, 5262, -581, -1213, 12842, 5347, -592, -1213, 12767, 5432, -603, -1213, 12693, 5518, -613, -1213, 12617, 5603, -624, -1212, 12542, 5689, -635, -1211, 12466, 5775, -645, -1210, 12389, 5862, -656, -1209, 12312, 5948, -667, -1208, 12234, 6035, -677, -1206, 12156, 6122, -688, -1204, 12078, 6209, -698, -1202, 11999, 6296, -709, -1200, 11920, 6384, -720, -1197, 11840, 6471, -730, -1194, 11760, 6559, -740, -1191, 11679, 6647, -751, -1188, 11598, 6735, -761, -1184, 11517, 6823, -772, -1181, 11436, 6911, -782, -1177, 11354, 6999, -792, -1173, 11271, 7088, -802, -1168, 11189, 7176, -812, -1164, 11106, 7265, -822, -1159, 11022, 7354, -832, -1155, 10939, 7442, -842, -1150, 10855, 7531, -852, -1144, 10771, 7620, -862, -1139, 10686, 7709, -872, -1134, 10602, 7798, -882, -1128, 10516, 7886, -891, -1122, 10431, 7975, -901, -1116, 10346, 8064, -910, -1110, 10260, 8153, -919, -1103, 10174, 8242, -929, -1097, 10088, 8331, -938, -1090, 10001, 8420, -947, -1083, 9915, 8508, -956, -1076, 9828, 8597, -965, -1069, 9741, 8686, -973, -1062, 9654, 8774, -982, -1054, 9566, 8863, -991, -1047, 9479, 8951, -999, -1039, 9391, 9039, -1007, -1031, 9303, 9127, -1015, -1024, 9216, 9216, -1024, -1015, 9127, 9303, -1031, -1007, 9039, 9391, -1039, -999, 8951, 9479, -1047, -991, 8863, 9566, -1054, -982, 8774, 9654, -1062, -973, 8686, 9741, -1069, -965, 8597, 9828, -1076, -956, 8508, 9915, -1083, -947, 8420, 10001, -1090, -938, 8331, 10088, -1097, -929, 8242, 10174, -1103, -919, 8153, 10260, -1110, -910, 8064, 10346, -1116, -901, 7975, 10431, -1122, -891, 7886, 10516, -1128, -882, 7798, 10602, -1134, -872, 7709, 10686, -1139, -862, 7620, 10771, -1144, -852, 7531, 10855, -1150, -842, 7442, 10939, -1155, -832, 7354, 11022, -1159, -822, 7265, 11106, -1164, -812, 7176, 11189, -1168, -802, 7088, 11271, -1173, -792, 6999, 11354, -1177, -782, 6911, 11436, -1181, -772, 6823, 11517, -1184, -761, 6735, 11598, -1188, -751, 6647, 11679, -1191, -740, 6559, 11760, -1194, -730, 6471, 11840, -1197, -720, 6384, 11920, -1200, -709, 6296, 11999, -1202, -698, 6209, 12078, -1204, -688, 6122, 12156, -1206, -677, 6035, 12234, -1208, -667, 5948, 12312, -1209, -656, 5862, 12389, -1210, -645, 5775, 12466, -1211, -635, 5689, 12542, -1212, -624, 5603, 12617, -1213, -613, 5518, 12693, -1213, -603, 5432, 12767, -1213, -592, 5347, 12842, -1213, -581, 5262, 12915, -1212, -571, 5178, 12989, -1212, -560, 5094, 13061, -1211, -550, 5010, 13134, -1210, -539, 4926, 13205, -1208, -528, 4842, 13276, -1206, -518, 4759, 13347, -1204, -507, 4676, 13417, -1202, -497, 4594, 13486, -1199, -486, 4512, 13555, -1196, -476, 4430, 13623, -1193, -465, 4349, 13690, -1190, -455, 4268, 13757, -1186, -445, 4187, 13823, -1182, -434, 4107, 13889, -1178, -424, 4027, 13954, -1173, -414, 3947, 14018, -1168, -404, 3868, 14082, -1163, -394, 3790, 14145, -1157, -384, 3712, 14208, -1152, -374, 3634, 14269, -1145, -364, 3556, 14330, -1139, -354, 3480, 14390, -1132, -344, 3403, 14450, -1125, -334, 3327, 14509, -1118, -325, 3252, 14567, -1110, -315, 3177, 14624, -1102, -306, 3102, 14681, -1093, -296, 3028, 14737, -1084, -287, 2955, 14792, -1075, -278, 2882, 14846, -1066, -269, 2810, 14899, -1056, -260, 2738, 14952, -1046, -251, 2666, 15004, -1036, -242, 2596, 15055, -1025, -234, 2526, 15106, -1014, -225, 2456, 15155, -1002, -216, 2387, 15204, -990, -208, 2319, 15251, -978, -200, 2251, 15298, -965, -192, 2184, 15344, -952, -184, 2117, 15390, -939, -176, 2051, 15434, -925, -168, 1986, 15477, -911, -161, 1921, 15520, -896, -153, 1857, 15561, -881, -146, 1794, 15602, -866, -139, 1731, 15642, -850, -132, 1669, 15681, -834, -125, 1608, 15719, -818, -118, 1547, 15756, -801, -112, 1488, 15792, -784, -105, 1428, 15827, -766, -99, 1370, 15861, -748, -93, 1312, 15894, -729, -87, 1255, 15926, -710, -81, 1199, 15957, -691, -75, 1144, 15987, -671, -70, 1089, 16016, -651, -65, 1035, 16044, -630, -60, 982, 16071, -609, -55, 930, 16097, -588, -50, 878, 16121, -566, -46, 828, 16145, -543, -41, 778, 16168, -521, -37, 729, 16190, -497, -33, 681, 16210, -474, -30, 634, 16230, -450, -26, 587, 16248, -425, -23, 541, 16265, -400, -20, 497, 16281, -374, -17, 453, 16296, -348, -14, 410, 16310, -322, -12, 368, 16322, -295, -9, 327, 16334, -268, -7, 287, 16344, -240, -5, 247, 16353, -211, -4, 209, 16361, -183, -3, 172, 16368, -153, -1, 135, 16374, -124, -1, 100, 16378, -93, 0, 65, 16381, -63, 0, 32, 16383, -31, }; ///////////////////////////////////////////////////////////////////////////////////////////// // Compute Bessel function Izero(y) using a series approximation static double izero(double y) { double s=1, ds=1, d=0; do { d = d + 2; ds = ds * (y*y)/(d*d); s = s + ds; } while (ds > 1E-7 * s); return s; } static void getsinc(SINC_TYPE *psinc, double beta, double lowpass_factor) { if(lowpass_factor >= 0.999) { // Avoid mixer overflows. // 1.0 itself does not make much sense. lowpass_factor = 0.999; } const double izero_beta = izero(beta); const double kPi = 4.0*atan(1.0)*lowpass_factor; for (int isrc=0; isrc<8*SINC_PHASES; isrc++) { double fsinc; int ix = 7 - (isrc & 7); ix = (ix*SINC_PHASES)+(isrc>>3); if (ix == (4*SINC_PHASES)) { fsinc = 1.0; } else { double x = (double)(ix - (4*SINC_PHASES)) * (double)(1.0/SINC_PHASES); fsinc = sin(x*kPi) * izero(beta*sqrt(1-x*x*(1.0/16.0))) / (izero_beta*x*kPi); // Kaiser window } double coeff = fsinc * lowpass_factor; #ifdef MPT_INTMIXER int n = (int)std::floor(coeff * (1< int16_min); *psinc++ = static_cast(n); #else *psinc++ = static_cast(coeff); #endif } } #if 0 // this code is currently unused static double GetSpline(double x, double c0, double c1, double c2, double c3) { double Xo = c1; double Xa = c0 - Xo; double Xb = c2 - Xo; double Ux = (Xb-Xa)/2; double Vx = (c3 - Xo)/2; double a = Vx+Ux-2*Xb; double b = 3*Xb-2*Ux-Vx; return (((a*x+b)*x)+Ux)*x+Xo; } static void getdownsample2x(short int *psinc) { for (int i=0; i(FastSincTable[i] * mixsample_t(1.0f / 16384.0f)); } #endif // !defined(MPT_INTMIXER) } void CResampler::InitializeTablesFromScratch(bool force) { bool initParameterIndependentTables = false; if(force) { initParameterIndependentTables = true; } #ifdef MODPLUG_TRACKER if(!StaticTablesInitialized) { initParameterIndependentTables = true; } #endif // MODPLUG_TRACKER MPT_MAYBE_CONSTANT_IF(initParameterIndependentTables) { InitFloatmixerTables(); getsinc(gKaiserSinc, 9.6377, 0.97); //ericus' downsampling improvement. //getsinc(gDownsample13x, 8.5, 3.0/4.0); //getdownsample2x(gDownsample2x); getsinc(gDownsample13x, 8.5, 0.5); getsinc(gDownsample2x, 2.7625, 0.425); //end ericus' downsampling improvement. #ifdef MODPLUG_TRACKER StaticTablesInitialized = true; #endif // MODPLUG_TRACKER } if((m_OldSettings == m_Settings) && !force) { return; } m_WindowedFIR.InitTable(m_Settings.gdWFIRCutoff, m_Settings.gbWFIRType); m_OldSettings = m_Settings; } #ifdef MPT_RESAMPLER_TABLES_CACHED static const CResampler & GetCachedResampler() { static CResampler s_CachedResampler(true); return s_CachedResampler; } void CResampler::InitializeTablesFromCache() { const CResampler & s_CachedResampler = GetCachedResampler(); InitFloatmixerTables(); std::copy(s_CachedResampler.gKaiserSinc, s_CachedResampler.gKaiserSinc + SINC_PHASES*8, gKaiserSinc); std::copy(s_CachedResampler.gDownsample13x, s_CachedResampler.gDownsample13x + SINC_PHASES*8, gDownsample13x); std::copy(s_CachedResampler.gDownsample2x, s_CachedResampler.gDownsample2x + SINC_PHASES*8, gDownsample2x); std::copy(s_CachedResampler.m_WindowedFIR.lut, s_CachedResampler.m_WindowedFIR.lut + WFIR_LUTLEN*WFIR_WIDTH, m_WindowedFIR.lut); } #endif // MPT_RESAMPLER_TABLES_CACHED #ifdef MPT_RESAMPLER_TABLES_CACHED_ONSTARTUP struct ResampleCacheInitializer { ResampleCacheInitializer() { GetCachedResampler(); } }; static ResampleCacheInitializer g_ResamplerCachePrimer; #endif // MPT_RESAMPLER_TABLES_CACHED_ONSTARTUP OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/configure0000755000372100037210000263426313235362220016203 00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for libopenmpt 0.3.6+release.autotools. # # Report bugs to . # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and $0: https://bugs.openmpt.org/ about your system, including $0: any error possibly output before this message. Then $0: install a modern shell, or manually run the script $0: under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" SHELL=${CONFIG_SHELL-/bin/sh} test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='libopenmpt' PACKAGE_TARNAME='libopenmpt' PACKAGE_VERSION='0.3.6+release.autotools' PACKAGE_STRING='libopenmpt 0.3.6+release.autotools' PACKAGE_BUGREPORT='https://bugs.openmpt.org/' PACKAGE_URL='https://lib.openmpt.org/' # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS DX_RULES PAPER_SIZE DOXYGEN_PAPER_SIZE GENERATE_LATEX DX_PDFLATEX DX_FLAG_pdf DX_EGREP DX_DVIPS DX_MAKEINDEX DX_LATEX DX_FLAG_ps DX_FLAG_html GENERATE_CHI DX_FLAG_chi GENERATE_HTMLHELP GENERATE_HTML HHC_PATH DX_HHC DX_FLAG_chm GENERATE_XML DX_FLAG_xml GENERATE_RTF DX_FLAG_rtf GENERATE_MAN DX_FLAG_man DOT_PATH HAVE_DOT DX_DOT DX_FLAG_dot PERL_PATH DX_PERL DX_DOXYGEN DX_FLAG_doc PROJECT SRCDIR DX_ENV DX_DOCDIR DX_CONFIG DX_PROJECT ENABLE_LIBMODPLUG_FALSE ENABLE_LIBMODPLUG_TRUE ENABLE_LIBOPENMPT_MODPLUG_FALSE ENABLE_LIBOPENMPT_MODPLUG_TRUE HAVE_CXX11 FLAC_LIBS FLAC_CFLAGS SNDFILE_LIBS SNDFILE_CFLAGS SDL_LIBS SDL_CFLAGS SDL2_LIBS SDL2_CFLAGS HAVE_PORTAUDIOCPP_FALSE HAVE_PORTAUDIOCPP_TRUE PORTAUDIOCPP_LIBS PORTAUDIOCPP_CFLAGS HAVE_PORTAUDIO_FALSE HAVE_PORTAUDIO_TRUE PORTAUDIO_LIBS PORTAUDIO_CFLAGS PULSEAUDIO_LIBS PULSEAUDIO_CFLAGS ENABLE_TESTS_FALSE ENABLE_TESTS_TRUE ENABLE_EXAMPLES_FALSE ENABLE_EXAMPLES_TRUE ENABLE_OPENMPT123_FALSE ENABLE_OPENMPT123_TRUE LIBOPENMPT_LIBS_PRIVATE LIBOPENMPT_REQUIRES_PRIVATE VORBISFILE_LIBS VORBISFILE_CFLAGS VORBIS_LIBS VORBIS_CFLAGS OGG_LIBS OGG_CFLAGS MPG123_LIBS MPG123_CFLAGS ZLIB_LIBS ZLIB_CFLAGS WIN32_CONSOLE_CFLAGS WIN32_CONSOLE_CXXFLAGS OPENMPT123_WIN32_LIBS LIBOPENMPT_WIN32_LIBS CXXSTDLIB_PCLIBSPRIVATE LIBOPENMPT_LTVER_AGE LIBOPENMPT_LTVER_REVISION LIBOPENMPT_LTVER_CURRENT CXXCPP am__fastdepCXX_FALSE am__fastdepCXX_TRUE CXXDEPMODE ac_ct_CXX CXXFLAGS CXX PKG_CONFIG_LIBDIR PKG_CONFIG_PATH PKG_CONFIG CPP LT_SYS_LIBRARY_PATH OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL MANIFEST_TOOL RANLIB DLLTOOL OBJDUMP LN_S NM ac_ct_DUMPBIN DUMPBIN LD FGREP EGREP GREP SED host_os host_vendor host_cpu host build_os build_vendor build_cpu build LIBTOOL am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC ac_ct_AR AR AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V AM_V am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir runstatedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_silent_rules enable_dependency_tracking enable_shared enable_static with_pic enable_fast_install with_aix_soname with_gnu_ld with_sysroot enable_libtool_lock enable_largefile with_zlib with_mpg123 with_ogg with_vorbis with_vorbisfile enable_openmpt123 enable_examples enable_tests with_pulseaudio with_portaudio with_portaudiocpp with_sdl2 with_sdl with_sndfile with_flac enable_libopenmpt_modplug enable_libmodplug enable_doxygen_doc enable_doxygen_dot enable_doxygen_man enable_doxygen_rtf enable_doxygen_xml enable_doxygen_chm enable_doxygen_chi enable_doxygen_html enable_doxygen_ps enable_doxygen_pdf ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS LT_SYS_LIBRARY_PATH CPP PKG_CONFIG PKG_CONFIG_PATH PKG_CONFIG_LIBDIR CXX CXXFLAGS CCC CXXCPP CXXSTDLIB_PCLIBSPRIVATE ZLIB_CFLAGS ZLIB_LIBS MPG123_CFLAGS MPG123_LIBS OGG_CFLAGS OGG_LIBS VORBIS_CFLAGS VORBIS_LIBS VORBISFILE_CFLAGS VORBISFILE_LIBS PULSEAUDIO_CFLAGS PULSEAUDIO_LIBS PORTAUDIO_CFLAGS PORTAUDIO_LIBS PORTAUDIOCPP_CFLAGS PORTAUDIOCPP_LIBS SDL2_CFLAGS SDL2_LIBS SDL_CFLAGS SDL_LIBS SNDFILE_CFLAGS SNDFILE_LIBS FLAC_CFLAGS FLAC_LIBS DOXYGEN_PAPER_SIZE' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -runstatedir | --runstatedir | --runstatedi | --runstated \ | --runstate | --runstat | --runsta | --runst | --runs \ | --run | --ru | --r) ac_prev=runstatedir ;; -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ | --run=* | --ru=* | --r=*) runstatedir=$ac_optarg ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures libopenmpt 0.3.6+release.autotools to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/libopenmpt] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of libopenmpt 0.3.6+release.autotools:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-silent-rules less verbose build output (undo: "make V=1") --disable-silent-rules verbose build output (undo: "make V=0") --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build --enable-shared[=PKGS] build shared libraries [default=yes] --enable-static[=PKGS] build static libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) --disable-largefile omit support for large files --disable-openmpt123 Disable the openmpt123 command line player. --disable-examples Disable the example programs. --disable-tests Disable the test suite. --enable-libopenmpt_modplug Enable the libopenmpt_modplug emulation library of the libmodplug interface. --enable-libmodplug Enable libmodplug replacement library based on libopenmpt. WARNING: This will replace your current libmodplug installation. CAUTION: The emulation of the libmodplug interface is not complete as libmodplug exposes lots of internal implementation details. If any of those is used by an application, the emulation via libopenmpt will fail and/or crash. --disable-doxygen-doc don't generate any doxygen documentation --enable-doxygen-dot generate graphics for doxygen documentation --enable-doxygen-man generate doxygen manual pages --enable-doxygen-rtf generate doxygen RTF documentation --enable-doxygen-xml generate doxygen XML documentation --enable-doxygen-chm generate doxygen compressed HTML help documentation --enable-doxygen-chi generate doxygen seperate compressed HTML help index file --disable-doxygen-html don't generate doxygen plain HTML documentation --enable-doxygen-ps generate doxygen PostScript documentation --enable-doxygen-pdf generate doxygen PDF documentation Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use both] --with-aix-soname=aix|svr4|both shared library versioning (aka "SONAME") variant to provide on AIX, [default=aix]. --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified). --without-zlib Disable use of zlib. --without-mpg123 Disable use of libmpg123. --without-ogg Disable use of libogg. --without-vorbis Disable use of libvorbis. --without-vorbisfile Disable use of libvorbisfile. --with-pulseaudio Enable use of libpulse and libpulse-simple (enabled by default on Linux). --without-portaudio Disable use of libportaudio. --without-portaudiocpp Disable use of libportaudiocpp. --with-sdl2 Enable use of libsdl2. --with-sdl Enable use of libsdl. --without-sndfile Disable use of libsndfile. --without-flac Disable use of libflac. Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory LT_SYS_LIBRARY_PATH User-defined run-time library search path. CPP C preprocessor PKG_CONFIG path to pkg-config utility PKG_CONFIG_PATH directories to add to pkg-config's search path PKG_CONFIG_LIBDIR path overriding pkg-config's built-in search path CXX C++ compiler command CXXFLAGS C++ compiler flags CXXCPP C++ preprocessor CXXSTDLIB_PCLIBSPRIVATE C++ standard library (or libraries) required for static linking. This will be put in the pkg-config file libopenmpt.pc Libs.private field and used for nothing else. ZLIB_CFLAGS C compiler flags for ZLIB, overriding pkg-config ZLIB_LIBS linker flags for ZLIB, overriding pkg-config MPG123_CFLAGS C compiler flags for MPG123, overriding pkg-config MPG123_LIBS linker flags for MPG123, overriding pkg-config OGG_CFLAGS C compiler flags for OGG, overriding pkg-config OGG_LIBS linker flags for OGG, overriding pkg-config VORBIS_CFLAGS C compiler flags for VORBIS, overriding pkg-config VORBIS_LIBS linker flags for VORBIS, overriding pkg-config VORBISFILE_CFLAGS C compiler flags for VORBISFILE, overriding pkg-config VORBISFILE_LIBS linker flags for VORBISFILE, overriding pkg-config PULSEAUDIO_CFLAGS C compiler flags for PULSEAUDIO, overriding pkg-config PULSEAUDIO_LIBS linker flags for PULSEAUDIO, overriding pkg-config PORTAUDIO_CFLAGS C compiler flags for PORTAUDIO, overriding pkg-config PORTAUDIO_LIBS linker flags for PORTAUDIO, overriding pkg-config PORTAUDIOCPP_CFLAGS C compiler flags for PORTAUDIOCPP, overriding pkg-config PORTAUDIOCPP_LIBS linker flags for PORTAUDIOCPP, overriding pkg-config SDL2_CFLAGS C compiler flags for SDL2, overriding pkg-config SDL2_LIBS linker flags for SDL2, overriding pkg-config SDL_CFLAGS C compiler flags for SDL, overriding pkg-config SDL_LIBS linker flags for SDL, overriding pkg-config SNDFILE_CFLAGS C compiler flags for SNDFILE, overriding pkg-config SNDFILE_LIBS linker flags for SNDFILE, overriding pkg-config FLAC_CFLAGS C compiler flags for FLAC, overriding pkg-config FLAC_LIBS linker flags for FLAC, overriding pkg-config DOXYGEN_PAPER_SIZE a4wide (default), a4, letter, legal or executive Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . libopenmpt home page: . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF libopenmpt configure 0.3.6+release.autotools generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_cxx_try_compile LINENO # ---------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile # ac_fn_cxx_try_cpp LINENO # ------------------------ # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_cpp # ac_fn_cxx_try_link LINENO # ------------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_link cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by libopenmpt $as_me 0.3.6+release.autotools, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers config.h" ac_aux_dir= for ac_dir in build-aux "$srcdir"/build-aux; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in build-aux \"$srcdir\"/build-aux" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. ac_config_files="$ac_config_files Makefile libopenmpt/libopenmpt.pc libmodplug/libmodplug.pc Doxyfile" am__api_version='1.15' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi if test "$2" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi rm -f conftest.file test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=1;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 $as_echo_n "checking whether $am_make supports nested variables... " >&6; } if ${am_cv_make_support_nested_variables+:} false; then : $as_echo_n "(cached) " >&6 else if $as_echo 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 $as_echo "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='libopenmpt' VERSION='0.3.6+release.autotools' cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # mkdir_p='$(MKDIR_P)' # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar pax cpio none' am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 fi fi DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 $as_echo_n "checking whether $CC understands -c and -o together... " >&6; } if ${am_cv_prog_cc_c_o+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 $as_echo "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi if test -n "$ac_tool_prefix"; then for ac_prog in ar lib "link -lib" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar lib "link -lib" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} { $as_echo "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5 $as_echo_n "checking the archiver ($AR) interface... " >&6; } if ${am_cv_ar_interface+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu am_cv_ar_interface=ar cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int some_variable = 0; _ACEOF if ac_fn_c_try_compile "$LINENO"; then : am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 (eval $am_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -eq 0; then am_cv_ar_interface=ar else am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 (eval $am_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -eq 0; then am_cv_ar_interface=lib else am_cv_ar_interface=unknown fi fi rm -f conftest.lib libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5 $as_echo "$am_cv_ar_interface" >&6; } case $am_cv_ar_interface in ar) ;; lib) # Microsoft lib, so override with the ar-lib wrapper script. # FIXME: It is wrong to rewrite AR. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__AR in this case, # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something # similar. AR="$am_aux_dir/ar-lib $AR" ;; unknown) as_fn_error $? "could not determine $AR interface" "$LINENO" 5 ;; esac case `pwd` in *\ * | *\ *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 $as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; esac macro_version='2.4.6' macro_revision='2.4.6' ltmain=$ac_aux_dir/ltmain.sh # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac # Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\(["`$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 $as_echo_n "checking how to print strings... " >&6; } # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "" } case $ECHO in printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 $as_echo "printf" >&6; } ;; print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 $as_echo "print -r" >&6; } ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 $as_echo "cat" >&6; } ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed { ac_script=; unset ac_script;} if test -z "$SED"; then ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_SED_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 $as_echo "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } if ${ac_cv_path_FGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 then ac_cv_path_FGREP="$GREP -F" else if test -z "$FGREP"; then ac_path_FGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in fgrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_FGREP" || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in *GNU*) ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'FGREP' >> "conftest.nl" "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_FGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_FGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_FGREP"; then as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_FGREP=$FGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 $as_echo "$ac_cv_path_FGREP" >&6; } FGREP="$ac_cv_path_FGREP" test -z "$GREP" && GREP=grep # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if ${lt_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 $as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } if ${lt_cv_path_NM+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM=$NM else lt_nm_to_check=${ac_tool_prefix}nm if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. tmp_nm=$ac_dir/$lt_tmp_nm if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then # Check to see if the nm accepts a BSD-compat flag. # Adding the 'sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty case $build_os in mingw*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 $as_echo "$lt_cv_path_NM" >&6; } if test no != "$lt_cv_path_NM"; then NM=$lt_cv_path_NM else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else if test -n "$ac_tool_prefix"; then for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DUMPBIN"; then ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DUMPBIN=$ac_cv_prog_DUMPBIN if test -n "$DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 $as_echo "$DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$DUMPBIN" && break done fi if test -z "$DUMPBIN"; then ac_ct_DUMPBIN=$DUMPBIN for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DUMPBIN"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN if test -n "$ac_ct_DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 $as_echo "$ac_ct_DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_DUMPBIN" && break done if test "x$ac_ct_DUMPBIN" = x; then DUMPBIN=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DUMPBIN=$ac_ct_DUMPBIN fi fi case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: ;; esac fi if test : != "$DUMPBIN"; then NM=$DUMPBIN fi fi test -z "$NM" && NM=nm { $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 $as_echo_n "checking the name lister ($NM) interface... " >&6; } if ${lt_cv_nm_interface+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 $as_echo "$lt_cv_nm_interface" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 $as_echo_n "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 $as_echo "no, using $LN_S" >&6; } fi # find the maximum length of command line arguments { $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 $as_echo_n "checking the maximum length of command line arguments... " >&6; } if ${lt_cv_sys_max_cmd_len+:} false; then : $as_echo_n "(cached) " >&6 else i=0 teststring=ABCD case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test X`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test 17 != "$i" # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac fi if test -n "$lt_cv_sys_max_cmd_len"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 $as_echo "$lt_cv_sys_max_cmd_len" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 $as_echo "none" >&6; } fi max_cmd_len=$lt_cv_sys_max_cmd_len : ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 $as_echo_n "checking how to convert $build file names to $host format... " >&6; } if ${lt_cv_to_host_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac fi to_host_file_cmd=$lt_cv_to_host_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 $as_echo "$lt_cv_to_host_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 $as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } if ${lt_cv_to_tool_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else #assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac fi to_tool_file_cmd=$lt_cv_to_tool_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 $as_echo "$lt_cv_to_tool_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 $as_echo_n "checking for $LD option to reload object files... " >&6; } if ${lt_cv_ld_reload_flag+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_reload_flag='-r' fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 $as_echo "$lt_cv_ld_reload_flag" >&6; } reload_flag=$lt_cv_ld_reload_flag case $reload_flag in "" | " "*) ;; *) reload_flag=" $reload_flag" ;; esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in cygwin* | mingw* | pw32* | cegcc*) if test yes != "$GCC"; then reload_cmds=false fi ;; darwin*) if test yes = "$GCC"; then reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi ;; esac if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 $as_echo "$OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 $as_echo "$ac_ct_OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi test -z "$OBJDUMP" && OBJDUMP=objdump { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 $as_echo_n "checking how to recognize dependent libraries... " >&6; } if ${lt_cv_deplibs_check_method+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # that responds to the $file_magic_cmd with a given extended regex. # If you have 'file' or equivalent on your system and you're not sure # whether 'pass_all' will *always* work, you probably want this one. case $host_os in aix[4-9]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[3-9]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd* | bitrig*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; os2*) lt_cv_deplibs_check_method=pass_all ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 $as_echo "$lt_cv_deplibs_check_method" >&6; } file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 $as_echo "$DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 $as_echo "$ac_ct_DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi test -z "$DLLTOOL" && DLLTOOL=dlltool { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 $as_echo_n "checking how to associate runtime and link libraries... " >&6; } if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh; # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 $as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO if test -n "$ac_tool_prefix"; then for ac_prog in ar do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} : ${AR_FLAGS=cru} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 $as_echo_n "checking for archiver @FILE support... " >&6; } if ${lt_cv_ar_at_file+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ar_at_file=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 $as_echo "$lt_cv_ar_at_file" >&6; } if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi test -z "$STRIP" && STRIP=: if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi test -z "$RANLIB" && RANLIB=: # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in bitrig* | openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Check for command to grab the raw symbol name followed by C symbol from nm. { $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 $as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } if ${lt_cv_sys_global_symbol_pipe+:} false; then : $as_echo_n "(cached) " >&6 else # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[BCDT]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) if test ia64 = "$host_cpu"; then symcode='[ABCDEGRST]' fi ;; irix* | nonstopux*) symcode='[BCDEGRST]' ;; osf*) symcode='[BCDEGQRST]' ;; solaris*) symcode='[BDRT]' ;; sco3.2v5*) symcode='[DT]' ;; sysv4.2uw2*) symcode='[DT]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[ABDT]' ;; sysv4) symcode='[DFNSTU]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[ABCDGIRSTW]' ;; esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" lt_c_name_lib_hook="\ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" else # Disable hooks by default. lt_cv_sys_global_symbol_to_import= lt_cdecl_hook= lt_c_name_hook= lt_c_name_lib_hook= fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ " /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ " /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ " {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ " s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&5 fi else echo "cannot find nm_test_var in $nlist" >&5 fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 fi else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= fi done fi if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 $as_echo "failed" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; } fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then nm_file_list_spec='@' fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 $as_echo_n "checking for sysroot... " >&6; } # Check whether --with-sysroot was given. if test "${with_sysroot+set}" = set; then : withval=$with_sysroot; else with_sysroot=no fi lt_sysroot= case $with_sysroot in #( yes) if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 $as_echo "$with_sysroot" >&6; } as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 $as_echo "${lt_sysroot:-no}" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5 $as_echo_n "checking for a working dd... " >&6; } if ${ac_cv_path_lt_DD+:} false; then : $as_echo_n "(cached) " >&6 else printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i : ${lt_DD:=$DD} if test -z "$lt_DD"; then ac_path_lt_DD_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in dd; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_lt_DD="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_lt_DD" || continue if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: fi $ac_path_lt_DD_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_lt_DD"; then : fi else ac_cv_path_lt_DD=$lt_DD fi rm -f conftest.i conftest2.i conftest.out fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5 $as_echo "$ac_cv_path_lt_DD" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5 $as_echo_n "checking how to truncate binary pipes... " >&6; } if ${lt_cv_truncate_bin+:} false; then : $as_echo_n "(cached) " >&6 else printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i lt_cv_truncate_bin= if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" fi rm -f conftest.i conftest2.i conftest.out test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5 $as_echo "$lt_cv_truncate_bin" >&6; } # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in $*""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } # Check whether --enable-libtool-lock was given. if test "${enable_libtool_lock+set}" = set; then : enableval=$enable_libtool_lock; fi test no = "$enable_libtool_lock" || enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out what ABI is being produced by ac_compile, and set mode # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; *ELF-64*) HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test yes = "$lt_cv_prog_gnu_ld"; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; mips64*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then emul=elf case `/usr/bin/file conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; *64-bit*) emul="${emul}64" ;; esac case `/usr/bin/file conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; *LSB*) emul="${emul}ltsmip" ;; esac case `/usr/bin/file conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; esac LD="${LD-ld} -m $emul" fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. Note that the listed cases only cover the # situations where additional linker options are needed (such as when # doing 32-bit compilation for a host where ld defaults to 64-bit, or # vice versa); the common cases where no linker options are needed do # not appear in the list. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `/usr/bin/file conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*linux*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*linux*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -belf" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 $as_echo_n "checking whether the C compiler needs -belf... " >&6; } if ${lt_cv_cc_needs_belf+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_cc_needs_belf=yes else lt_cv_cc_needs_belf=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 $as_echo "$lt_cv_cc_needs_belf" >&6; } if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD=${LD-ld}_sol2 fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks=$enable_libtool_lock if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. set dummy ${ac_tool_prefix}mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$MANIFEST_TOOL"; then ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL if test -n "$MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 $as_echo "$MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_MANIFEST_TOOL"; then ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL # Extract the first word of "mt", so it can be a program name with args. set dummy mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_MANIFEST_TOOL"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL if test -n "$ac_ct_MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 $as_echo "$ac_ct_MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_MANIFEST_TOOL" = x; then MANIFEST_TOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL fi else MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" fi test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 $as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } if ${lt_cv_path_mainfest_tool+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&5 if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 $as_echo "$lt_cv_path_mainfest_tool" >&6; } if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi case $host_os in rhapsody* | darwin*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DSYMUTIL"; then ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DSYMUTIL=$ac_cv_prog_DSYMUTIL if test -n "$DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 $as_echo "$DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DSYMUTIL"; then ac_ct_DSYMUTIL=$DSYMUTIL # Extract the first word of "dsymutil", so it can be a program name with args. set dummy dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DSYMUTIL"; then ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL if test -n "$ac_ct_DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 $as_echo "$ac_ct_DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DSYMUTIL" = x; then DSYMUTIL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DSYMUTIL=$ac_ct_DSYMUTIL fi else DSYMUTIL="$ac_cv_prog_DSYMUTIL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. set dummy ${ac_tool_prefix}nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NMEDIT"; then ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi NMEDIT=$ac_cv_prog_NMEDIT if test -n "$NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 $as_echo "$NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_NMEDIT"; then ac_ct_NMEDIT=$NMEDIT # Extract the first word of "nmedit", so it can be a program name with args. set dummy nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_NMEDIT"; then ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_NMEDIT="nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT if test -n "$ac_ct_NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 $as_echo "$ac_ct_NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_NMEDIT" = x; then NMEDIT=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac NMEDIT=$ac_ct_NMEDIT fi else NMEDIT="$ac_cv_prog_NMEDIT" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. set dummy ${ac_tool_prefix}lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LIPO"; then ac_cv_prog_LIPO="$LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LIPO=$ac_cv_prog_LIPO if test -n "$LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 $as_echo "$LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_LIPO"; then ac_ct_LIPO=$LIPO # Extract the first word of "lipo", so it can be a program name with args. set dummy lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_LIPO"; then ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_LIPO="lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO if test -n "$ac_ct_LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 $as_echo "$ac_ct_LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_LIPO" = x; then LIPO=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac LIPO=$ac_ct_LIPO fi else LIPO="$ac_cv_prog_LIPO" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. set dummy ${ac_tool_prefix}otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL"; then ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL=$ac_cv_prog_OTOOL if test -n "$OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 $as_echo "$OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL"; then ac_ct_OTOOL=$OTOOL # Extract the first word of "otool", so it can be a program name with args. set dummy otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL"; then ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL="otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL if test -n "$ac_ct_OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 $as_echo "$ac_ct_OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL" = x; then OTOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL=$ac_ct_OTOOL fi else OTOOL="$ac_cv_prog_OTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. set dummy ${ac_tool_prefix}otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL64"; then ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL64=$ac_cv_prog_OTOOL64 if test -n "$OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 $as_echo "$OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL64"; then ac_ct_OTOOL64=$OTOOL64 # Extract the first word of "otool64", so it can be a program name with args. set dummy otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL64"; then ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL64="otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 if test -n "$ac_ct_OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 $as_echo "$ac_ct_OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL64" = x; then OTOOL64=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL64=$ac_ct_OTOOL64 fi else OTOOL64="$ac_cv_prog_OTOOL64" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 $as_echo_n "checking for -single_module linker flag... " >&6; } if ${lt_cv_apple_cc_single_mod+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_apple_cc_single_mod=no if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&5 $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&5 # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 fi rm -rf libconftest.dylib* rm -f conftest.* fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 $as_echo "$lt_cv_apple_cc_single_mod" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 $as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } if ${lt_cv_ld_exported_symbols_list+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_ld_exported_symbols_list=yes else lt_cv_ld_exported_symbols_list=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 $as_echo "$lt_cv_ld_exported_symbols_list" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 $as_echo_n "checking for -force_load linker flag... " >&6; } if ${lt_cv_ld_force_load+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 echo "$AR cru libconftest.a conftest.o" >&5 $AR cru libconftest.a conftest.o 2>&5 echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 2>&5 cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&5 elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&5 fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 $as_echo "$lt_cv_ld_force_load" >&6; } case $host_os in rhapsody* | darwin1.[012]) _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[91]*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; 10.[012][,.]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi if test yes = "$lt_cv_ld_exported_symbols_list"; then _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' fi if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac # func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x$2 in x) ;; *:) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" ;; x:*) eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" ;; *::*) eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" ;; *) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" ;; esac } ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in dlfcn.h do : ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default " if test "x$ac_cv_header_dlfcn_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DLFCN_H 1 _ACEOF fi done # Set options enable_dlopen=no enable_win32_dll=no # Check whether --enable-shared was given. if test "${enable_shared+set}" = set; then : enableval=$enable_shared; p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS=$lt_save_ifs ;; esac else enable_shared=yes fi # Check whether --enable-static was given. if test "${enable_static+set}" = set; then : enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS=$lt_save_ifs ;; esac else enable_static=yes fi # Check whether --with-pic was given. if test "${with_pic+set}" = set; then : withval=$with_pic; lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS=$lt_save_ifs ;; esac else pic_mode=default fi # Check whether --enable-fast-install was given. if test "${enable_fast_install+set}" = set; then : enableval=$enable_fast_install; p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS=$lt_save_ifs ;; esac else enable_fast_install=yes fi shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[5-9]*,yes) { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 $as_echo_n "checking which variant of shared library versioning to provide... " >&6; } # Check whether --with-aix-soname was given. if test "${with_aix_soname+set}" = set; then : withval=$with_aix_soname; case $withval in aix|svr4|both) ;; *) as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 ;; esac lt_cv_with_aix_soname=$with_aix_soname else if ${lt_cv_with_aix_soname+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_with_aix_soname=aix fi with_aix_soname=$lt_cv_with_aix_soname fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 $as_echo "$with_aix_soname" >&6; } if test aix != "$with_aix_soname"; then # For the AIX way of multilib, we name the shared archive member # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, # the AIX toolchain works better with OBJECT_MODE set (default 32). if test 64 = "${OBJECT_MODE-32}"; then shared_archive_member_spec=shr_64 else shared_archive_member_spec=shr fi fi ;; *) with_aix_soname=aix ;; esac # This can be used to rebuild libtool when needed LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' test -z "$LN_S" && LN_S="ln -s" if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 $as_echo_n "checking for objdir... " >&6; } if ${lt_cv_objdir+:} false; then : $as_echo_n "(cached) " >&6 else rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 $as_echo "$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir cat >>confdefs.h <<_ACEOF #define LT_OBJDIR "$lt_cv_objdir/" _ACEOF case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a '.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld old_CC=$CC old_CFLAGS=$CFLAGS # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o func_cc_basename $compiler cc_basename=$func_cc_basename_result # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 $as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/${ac_tool_prefix}file"; then lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac fi MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 $as_echo_n "checking for file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/file"; then lt_cv_path_MAGIC_CMD=$ac_dir/"file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac fi MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else MAGIC_CMD=: fi fi fi ;; esac # Use C for the default configuration in the libtool script lt_save_CC=$CC ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o objext=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then lt_prog_compiler_no_builtin_flag= if test yes = "$GCC"; then case $cc_basename in nvcc*) lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; *) lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 $as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : fi fi lt_prog_compiler_wl= lt_prog_compiler_pic= lt_prog_compiler_static= if test yes = "$GCC"; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi lt_prog_compiler_pic='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) lt_prog_compiler_pic='-fPIC' ;; esac ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic=-Kconform_pic fi ;; *) lt_prog_compiler_pic='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 lt_prog_compiler_wl='-Xlinker ' if test -n "$lt_prog_compiler_pic"; then lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl='-Wl,' if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' case $cc_basename in nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; esac ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static='$wl-static' ;; esac ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64, which still supported -KPIC. ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # Lahey Fortran 8.1. lf95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='--shared' lt_prog_compiler_static='--static' ;; nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; tcc*) # Fabrice Bellard et al's Tiny C Compiler lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; ccc*) lt_prog_compiler_wl='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-qpic' lt_prog_compiler_static='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='' ;; *Sun\ F* | *Sun*Fortran*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; *Intel*\ [CF]*Compiler*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; *Portland\ Group*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; esac ;; esac ;; newsos6) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static='-non_shared' ;; rdos*) lt_prog_compiler_static='-non_shared' ;; solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) lt_prog_compiler_wl='-Qoption ld ';; *) lt_prog_compiler_wl='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl='-Qoption ld ' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; unicos*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_can_build_shared=no ;; uts4*) lt_prog_compiler_pic='-pic' lt_prog_compiler_static='-Bstatic' ;; *) lt_prog_compiler_can_build_shared=no ;; esac fi case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; *) lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } if ${lt_cv_prog_compiler_pic+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic=$lt_prog_compiler_pic fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 $as_echo "$lt_cv_prog_compiler_pic" >&6; } lt_prog_compiler_pic=$lt_cv_prog_compiler_pic # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } if ${lt_cv_prog_compiler_pic_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 $as_echo "$lt_cv_prog_compiler_pic_works" >&6; } if test yes = "$lt_cv_prog_compiler_pic_works"; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; esac else lt_prog_compiler_pic= lt_prog_compiler_can_build_shared=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if ${lt_cv_prog_compiler_static_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works=yes fi else lt_cv_prog_compiler_static_works=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 $as_echo "$lt_cv_prog_compiler_static_works" >&6; } if test yes = "$lt_cv_prog_compiler_static_works"; then : else lt_prog_compiler_static= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } hard_links=nottested if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test no = "$hard_links"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 $as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } runpath_var= allow_undefined_flag= always_export_symbols=no archive_cmds= archive_expsym_cmds= compiler_needs_object=no enable_shared_with_static_runtimes=no export_dynamic_flag_spec= export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' hardcode_automatic=no hardcode_direct=no hardcode_direct_absolute=no hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_minus_L=no hardcode_shlibpath_var=unsupported inherit_rpath=no link_all_deplibs=unknown module_cmds= module_expsym_cmds= old_archive_from_new_cmds= old_archive_from_expsyms_cmds= thread_safe_flag_spec= whole_archive_flag_spec= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ' (' and ')$', so one must not match beginning or # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', # as well as any symbol that contains 'd'. exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd* | bitrig*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) link_all_deplibs=no ;; esac ld_shlibs=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test yes = "$with_gnu_ld"; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; *\ \(GNU\ Binutils\)\ [3-9]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test yes = "$lt_use_gnu_ld_interface"; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='$wl' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' export_dynamic_flag_spec='$wl--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test ia64 != "$host_cpu"; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else ld_shlibs=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' export_dynamic_flag_spec='$wl--export-all-symbols' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; haiku*) archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' link_all_deplibs=yes ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported shrext_cmds=.dll archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes ;; interix[3-9]*) hardcode_direct=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='$wl-rpath,$libdir' export_dynamic_flag_spec='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test linux-dietlibc = "$host_os"; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 whole_archive_flag_spec= tmp_sharedflag='--shared' ;; nagfor*) # NAGFOR 5.3 tmp_sharedflag='-Wl,-shared' ;; xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in tcc*) export_dynamic_flag_spec='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else ld_shlibs=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac ;; sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct=yes hardcode_shlibpath_var=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac if test no = "$ld_shlibs"; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= whole_archive_flag_spec= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag=unsupported always_export_symbols=yes archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix[4-9]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds='' hardcode_direct=yes hardcode_direct_absolute=yes hardcode_libdir_separator=':' link_all_deplibs=yes file_list_spec='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # traditional, no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. hardcode_direct=no hardcode_direct_absolute=no ;; esac if test yes = "$GCC"; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag="$shared_flag "'$wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi export_dynamic_flag_spec='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag=' $wl-bernotok' allow_undefined_flag=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' fi archive_cmds_need_lc=yes archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; bsdi[45]*) export_dynamic_flag_spec=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported always_export_symbols=yes file_list_spec='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' enable_shared_with_static_runtimes=yes exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib old_postinstall_cmds='chmod 644 $oldlib' postlink_cmds='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_from_new_cmds='true' # FIXME: Should let the user specify the lib program. old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' enable_shared_with_static_runtimes=yes ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported if test yes = "$lt_cv_ld_force_load"; then whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec='' fi link_all_deplibs=yes allow_undefined_flag=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" else ld_shlibs=no fi ;; dgux*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test yes = "$GCC"; then archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes export_dynamic_flag_spec='$wl-E' ;; hpux10*) if test yes,no = "$GCC,$with_gnu_ld"; then archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 $as_echo_n "checking if $CC understands -b... " >&6; } if ${lt_cv_prog_compiler__b+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler__b=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -b" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler__b=yes fi else lt_cv_prog_compiler__b=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 $as_echo "$lt_cv_prog_compiler__b" >&6; } if test yes = "$lt_cv_prog_compiler__b"; then archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi ;; esac fi if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no hardcode_shlibpath_var=no ;; *) hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test yes = "$GCC"; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 $as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } if ${lt_cv_irix_exported_symbol+:} false; then : $as_echo_n "(cached) " >&6 else save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo (void) { return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_irix_exported_symbol=yes else lt_cv_irix_exported_symbol=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 $as_echo "$lt_cv_irix_exported_symbol" >&6; } if test yes = "$lt_cv_irix_exported_symbol"; then archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi link_all_deplibs=no else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: inherit_rpath=yes link_all_deplibs=yes ;; linux*) case $cc_basename in tcc*) # Fabrice Bellard et al's Tiny C Compiler ld_shlibs=yes archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; *nto* | *qnx*) ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no hardcode_direct_absolute=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec='$wl-rpath,$libdir' export_dynamic_flag_spec='$wl-E' else archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='$wl-rpath,$libdir' fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported shrext_cmds=.dll archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes ;; osf3*) if test yes = "$GCC"; then allow_undefined_flag=' $wl-expect_unresolved $wl\*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test yes = "$GCC"; then allow_undefined_flag=' $wl-expect_unresolved $wl\*' archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi archive_cmds_need_lc='no' hardcode_libdir_separator=: ;; solaris*) no_undefined_flag=' -z defs' if test yes = "$GCC"; then wlarc='$wl' archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='$wl' archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi hardcode_libdir_flag_spec='-R$libdir' hardcode_shlibpath_var=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. GCC discards it without '$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test yes = "$GCC"; then whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else whole_archive_flag_spec='-z allextract$convenience -z defaultextract' fi ;; esac link_all_deplibs=yes ;; sunos4*) if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; sysv4) case $host_vendor in sni) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds='$CC -r -o $output$reload_objs' hardcode_direct=no ;; motorola) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var=no ;; sysv4.3*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no export_dynamic_flag_spec='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag='$wl-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag='$wl-z,text' allow_undefined_flag='$wl-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='$wl-R,$libdir' hardcode_libdir_separator=':' link_all_deplibs=yes export_dynamic_flag_spec='$wl-Bexport' runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; *) ld_shlibs=no ;; esac if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) export_dynamic_flag_spec='$wl-Blargedynsym' ;; esac fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 $as_echo "$ld_shlibs" >&6; } test no = "$ld_shlibs" && can_build_shared=no with_gnu_ld=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc" in x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes if test yes,yes = "$GCC,$enable_shared"; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } if ${lt_cv_archive_cmds_need_lc+:} false; then : $as_echo_n "(cached) " >&6 else $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl pic_flag=$lt_prog_compiler_pic compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag allow_undefined_flag= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc=no else lt_cv_archive_cmds_need_lc=yes fi allow_undefined_flag=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 $as_echo "$lt_cv_archive_cmds_need_lc" >&6; } archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ;; esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } if test yes = "$GCC"; then case $host_os in darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary... lt_tmp_lt_search_path_spec= lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` # ...but if some path component already ends with the multilib dir we assume # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). case "$lt_multi_os_dir; $lt_search_path_spec " in "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) lt_multi_os_dir= ;; esac for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" elif test -n "$lt_multi_os_dir"; then test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS = " "; FS = "/|\n";} { lt_foo = ""; lt_count = 0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo = "/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[lt_foo]++; } if (lt_freq[lt_foo] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's|/\([A-Za-z]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a(lib.so.V)' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. hardcode_libdir_flag_spec='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if ${lt_cv_shlibpath_overrides_runpath+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || test -n "$runpath_var" || test yes = "$hardcode_automatic"; then # We can hardcode non-existent directories. if test no != "$hardcode_direct" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" && test no != "$hardcode_minus_L"; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action=unsupported fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 $as_echo "$hardcode_action" >&6; } if test relink = "$hardcode_action" || test yes = "$inherit_rpath"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi if test yes != "$enable_dlopen"; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen=load_add_on lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen=dlopen lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl else lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes fi ;; tpf*) # Don't try to run any link tests for TPF. We know it's impossible # because TPF is a cross-compiler, and we know how we open DSOs. lt_cv_dlopen=dlopen lt_cv_dlopen_libs= lt_cv_dlopen_self=no ;; *) ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" if test "x$ac_cv_func_shl_load" = xyes; then : lt_cv_dlopen=shl_load else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 $as_echo_n "checking for shl_load in -ldld... " >&6; } if ${ac_cv_lib_dld_shl_load+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shl_load (); int main () { return shl_load (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_shl_load=yes else ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 $as_echo "$ac_cv_lib_dld_shl_load" >&6; } if test "x$ac_cv_lib_dld_shl_load" = xyes; then : lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld else ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes; then : lt_cv_dlopen=dlopen else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 $as_echo_n "checking for dlopen in -lsvld... " >&6; } if ${ac_cv_lib_svld_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_svld_dlopen=yes else ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 $as_echo "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = xyes; then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 $as_echo_n "checking for dld_link in -ldld... " >&6; } if ${ac_cv_lib_dld_dld_link+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dld_link (); int main () { return dld_link (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_dld_link=yes else ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 $as_echo "$ac_cv_lib_dld_dld_link" >&6; } if test "x$ac_cv_lib_dld_dld_link" = xyes; then : lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld fi fi fi fi fi fi ;; esac if test no = "$lt_cv_dlopen"; then enable_dlopen=no else enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS=$CPPFLAGS test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS=$LDFLAGS wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS=$LIBS LIBS="$lt_cv_dlopen_libs $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 $as_echo_n "checking whether a program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self+:} false; then : $as_echo_n "(cached) " >&6 else if test yes = "$cross_compiling"; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; esac else : # compilation failed lt_cv_dlopen_self=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 $as_echo "$lt_cv_dlopen_self" >&6; } if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 $as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self_static+:} false; then : $as_echo_n "(cached) " >&6 else if test yes = "$cross_compiling"; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; esac else : # compilation failed lt_cv_dlopen_self_static=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 $as_echo "$lt_cv_dlopen_self_static" >&6; } fi CPPFLAGS=$save_CPPFLAGS LDFLAGS=$save_LDFLAGS LIBS=$save_LIBS ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi striplib= old_striplib= { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 $as_echo_n "checking whether stripping libraries is possible... " >&6; } if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP"; then striplib="$STRIP -x" old_striplib="$STRIP -S" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; esac fi # Report what library types will actually be built { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 $as_echo_n "checking if libtool supports shared libraries... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 $as_echo "$can_build_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 $as_echo_n "checking whether to build shared libraries... " >&6; } test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[4-9]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 $as_echo "$enable_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 $as_echo_n "checking whether to build static libraries... " >&6; } # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 $as_echo "$enable_static" >&6; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CC=$lt_save_CC ac_config_commands="$ac_config_commands libtool" # Only expand once: # Check whether --enable-largefile was given. if test "${enable_largefile+set}" = set; then : enableval=$enable_largefile; fi if test "$enable_largefile" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5 $as_echo_n "checking for special C compiler options needed for large files... " >&6; } if ${ac_cv_sys_largefile_CC+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_sys_largefile_CC=no if test "$GCC" != yes; then ac_save_CC=$CC while :; do # IRIX 6.2 and later do not support large files by default, # so use the C compiler's -n32 option if that helps. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : break fi rm -f core conftest.err conftest.$ac_objext CC="$CC -n32" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_largefile_CC=' -n32'; break fi rm -f core conftest.err conftest.$ac_objext break done CC=$ac_save_CC rm -f conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5 $as_echo "$ac_cv_sys_largefile_CC" >&6; } if test "$ac_cv_sys_largefile_CC" != no; then CC=$CC$ac_cv_sys_largefile_CC fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5 $as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; } if ${ac_cv_sys_file_offset_bits+:} false; then : $as_echo_n "(cached) " >&6 else while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_file_offset_bits=no; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _FILE_OFFSET_BITS 64 #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_file_offset_bits=64; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_sys_file_offset_bits=unknown break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5 $as_echo "$ac_cv_sys_file_offset_bits" >&6; } case $ac_cv_sys_file_offset_bits in #( no | unknown) ;; *) cat >>confdefs.h <<_ACEOF #define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits _ACEOF ;; esac rm -rf conftest* if test $ac_cv_sys_file_offset_bits = unknown; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5 $as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; } if ${ac_cv_sys_large_files+:} false; then : $as_echo_n "(cached) " >&6 else while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_large_files=no; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _LARGE_FILES 1 #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_large_files=1; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_sys_large_files=unknown break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5 $as_echo "$ac_cv_sys_large_files" >&6; } case $ac_cv_sys_large_files in #( no | unknown) ;; *) cat >>confdefs.h <<_ACEOF #define _LARGE_FILES $ac_cv_sys_large_files _ACEOF ;; esac rm -rf conftest* fi fi if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 $as_echo "$PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_PKG_CONFIG"; then ac_pt_PKG_CONFIG=$PKG_CONFIG # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG if test -n "$ac_pt_PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 $as_echo "$ac_pt_PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_PKG_CONFIG" = x; then PKG_CONFIG="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac PKG_CONFIG=$ac_pt_PKG_CONFIG fi else PKG_CONFIG="$ac_cv_path_PKG_CONFIG" fi fi if test -n "$PKG_CONFIG"; then _pkg_min_version=0.24 { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 $as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } PKG_CONFIG="" fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 $as_echo_n "checking whether $CC understands -c and -o together... " >&6; } if ${am_cv_prog_cc_c_o+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 $as_echo "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 $as_echo "$ac_ct_CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } if ${ac_cv_cxx_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 $as_echo "$ac_cv_cxx_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } if ${ac_cv_prog_cxx_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes else CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 $as_echo "$ac_cv_prog_cxx_g" >&6; } if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CXX" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CXX_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CXX_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CXX_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CXX_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 $as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then am__fastdepCXX_TRUE= am__fastdepCXX_FALSE='#' else am__fastdepCXX_TRUE='#' am__fastdepCXX_FALSE= fi func_stripname_cnf () { case $2 in .*) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%\\\\$2\$%%"`;; *) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%$2\$%%"`;; esac } # func_stripname_cnf if test -n "$CXX" && ( test no != "$CXX" && ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || (test g++ != "$CXX"))); then ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 $as_echo_n "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then if ${ac_cv_prog_CXXCPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CXXCPP needs to be expanded for CXXCPP in "$CXX -E" "/lib/cpp" do ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CXXCPP=$CXXCPP fi CXXCPP=$ac_cv_prog_CXXCPP else ac_cv_prog_CXXCPP=$CXXCPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 $as_echo "$CXXCPP" >&6; } ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu else _lt_caught_CXX_error=yes fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu archive_cmds_need_lc_CXX=no allow_undefined_flag_CXX= always_export_symbols_CXX=no archive_expsym_cmds_CXX= compiler_needs_object_CXX=no export_dynamic_flag_spec_CXX= hardcode_direct_CXX=no hardcode_direct_absolute_CXX=no hardcode_libdir_flag_spec_CXX= hardcode_libdir_separator_CXX= hardcode_minus_L_CXX=no hardcode_shlibpath_var_CXX=unsupported hardcode_automatic_CXX=no inherit_rpath_CXX=no module_cmds_CXX= module_expsym_cmds_CXX= link_all_deplibs_CXX=unknown old_archive_cmds_CXX=$old_archive_cmds reload_flag_CXX=$reload_flag reload_cmds_CXX=$reload_cmds no_undefined_flag_CXX= whole_archive_flag_spec_CXX= enable_shared_with_static_runtimes_CXX=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o objext_CXX=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_caught_CXX_error"; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC compiler_CXX=$CC func_cc_basename $compiler cc_basename=$func_cc_basename_result if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test yes = "$GXX"; then lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' else lt_prog_compiler_no_builtin_flag_CXX= fi if test yes = "$GXX"; then # Set up default GNU C++ configuration # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if ${lt_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test yes = "$with_gnu_ld"; then archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='$wl' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else whole_archive_flag_spec_CXX= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } ld_shlibs_CXX=yes case $host_os in aix3*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aix[4-9]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds_CXX='' hardcode_direct_CXX=yes hardcode_direct_absolute_CXX=yes hardcode_libdir_separator_CXX=':' link_all_deplibs_CXX=yes file_list_spec_CXX='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. hardcode_direct_CXX=no hardcode_direct_absolute_CXX=no ;; esac if test yes = "$GXX"; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct_CXX=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L_CXX=yes hardcode_libdir_flag_spec_CXX='-L$libdir' hardcode_libdir_separator_CXX= fi esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag=$shared_flag' $wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi export_dynamic_flag_spec_CXX='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. always_export_symbols_CXX=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. # The "-G" linker flag allows undefined symbols. no_undefined_flag_CXX='-bernotok' # Determine the default libpath from the value encoded in an empty # executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath__CXX+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath__CXX fi hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then hardcode_libdir_flag_spec_CXX='$wl-R $libdir:/usr/lib:/lib' allow_undefined_flag_CXX="-z nodefs" archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath__CXX+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath__CXX fi hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag_CXX=' $wl-bernotok' allow_undefined_flag_CXX=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec_CXX='$convenience' fi archive_cmds_need_lc_CXX=yes archive_expsym_cmds_CXX='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$RM -r $output_objdir/$realname.d' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag_CXX=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else ld_shlibs_CXX=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl*) # Native MSVC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec_CXX=' ' allow_undefined_flag_CXX=unsupported always_export_symbols_CXX=yes file_list_spec_CXX='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true' enable_shared_with_static_runtimes_CXX=yes # Don't use ranlib old_postinstall_cmds_CXX='chmod 644 $oldlib' postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ func_to_tool_file "$lt_outputfile"~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec_CXX='-L$libdir' export_dynamic_flag_spec_CXX='$wl--export-all-symbols' allow_undefined_flag_CXX=unsupported always_export_symbols_CXX=no enable_shared_with_static_runtimes_CXX=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs_CXX=no fi ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc_CXX=no hardcode_direct_CXX=no hardcode_automatic_CXX=yes hardcode_shlibpath_var_CXX=unsupported if test yes = "$lt_cv_ld_force_load"; then whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec_CXX='' fi link_all_deplibs_CXX=yes allow_undefined_flag_CXX=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" module_expsym_cmds_CXX="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" if test yes != "$lt_cv_apple_cc_single_mod"; then archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" fi else ld_shlibs_CXX=no fi ;; os2*) hardcode_libdir_flag_spec_CXX='-L$libdir' hardcode_minus_L_CXX=yes allow_undefined_flag_CXX=unsupported shrext_cmds=.dll archive_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds_CXX='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes_CXX=yes ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF ld_shlibs_CXX=no ;; freebsd-elf*) archive_cmds_need_lc_CXX=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions ld_shlibs_CXX=yes ;; haiku*) archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' link_all_deplibs_CXX=yes ;; hpux9*) hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' hardcode_libdir_separator_CXX=: export_dynamic_flag_spec_CXX='$wl-E' hardcode_direct_CXX=yes hardcode_minus_L_CXX=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aCC*) archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; hpux10*|hpux11*) if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' hardcode_libdir_separator_CXX=: case $host_cpu in hppa*64*|ia64*) ;; *) export_dynamic_flag_spec_CXX='$wl-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) hardcode_direct_CXX=no hardcode_shlibpath_var_CXX=no ;; *) hardcode_direct_CXX=yes hardcode_direct_absolute_CXX=yes hardcode_minus_L_CXX=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aCC*) case $host_cpu in hppa*64*) archive_cmds_CXX='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then case $host_cpu in hppa*64*) archive_cmds_CXX='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; interix[3-9]*) hardcode_direct_CXX=no hardcode_shlibpath_var_CXX=no hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' export_dynamic_flag_spec_CXX='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds_CXX='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' fi fi link_all_deplibs_CXX=yes ;; esac hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' hardcode_libdir_separator_CXX=: inherit_rpath_CXX=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac archive_cmds_need_lc_CXX=no hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [1-5].* | *pgcpp\ [1-5].*) prelink_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' old_archive_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' archive_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac hardcode_libdir_flag_spec_CXX='$wl--rpath $wl$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' whole_archive_flag_spec_CXX='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ;; cxx*) # Compaq C++ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec_CXX='-rpath $libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 no_undefined_flag_CXX=' -zdefs' archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' archive_expsym_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' hardcode_libdir_flag_spec_CXX='-R$libdir' whole_archive_flag_spec_CXX='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object_CXX=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; m88k*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= hardcode_libdir_flag_spec_CXX='-R$libdir' hardcode_direct_CXX=yes hardcode_shlibpath_var_CXX=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) ld_shlibs_CXX=yes ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then hardcode_direct_CXX=yes hardcode_shlibpath_var_CXX=no hardcode_direct_absolute_CXX=yes archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' export_dynamic_flag_spec_CXX='$wl-E' whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else ld_shlibs_CXX=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' hardcode_libdir_separator_CXX=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; cxx*) case $host in osf3*) allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' ;; *) allow_undefined_flag_CXX=' -expect_unresolved \*' archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ $RM $lib.exp' hardcode_libdir_flag_spec_CXX='-rpath $libdir' ;; esac hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes,no = "$GXX,$with_gnu_ld"; then allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' case $host in osf3*) archive_cmds_CXX='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; *) archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; esac hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ archive_cmds_need_lc_CXX=yes no_undefined_flag_CXX=' -zdefs' archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' hardcode_libdir_flag_spec_CXX='-R$libdir' hardcode_shlibpath_var_CXX=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' ;; esac link_all_deplibs_CXX=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test yes,no = "$GXX,$with_gnu_ld"; then no_undefined_flag_CXX=' $wl-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. archive_cmds_CXX='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' fi hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir' case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) whole_archive_flag_spec_CXX='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag_CXX='$wl-z,text' archive_cmds_need_lc_CXX=no hardcode_shlibpath_var_CXX=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag_CXX='$wl-z,text' allow_undefined_flag_CXX='$wl-z,nodefs' archive_cmds_need_lc_CXX=no hardcode_shlibpath_var_CXX=no hardcode_libdir_flag_spec_CXX='$wl-R,$libdir' hardcode_libdir_separator_CXX=':' link_all_deplibs_CXX=yes export_dynamic_flag_spec_CXX='$wl-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~ '"$old_archive_cmds_CXX" reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~ '"$reload_cmds_CXX" ;; *) archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 $as_echo "$ld_shlibs_CXX" >&6; } test no = "$ld_shlibs_CXX" && can_build_shared=no GCC_CXX=$GXX LD_CXX=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... # Dependencies to place before and after the object being linked: predep_objects_CXX= postdep_objects_CXX= predeps_CXX= postdeps_CXX= compiler_lib_search_path_CXX= cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case $prev$p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test x-L = "$p" || test x-R = "$p"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test no = "$pre_test_object_deps_done"; then case $prev in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$compiler_lib_search_path_CXX"; then compiler_lib_search_path_CXX=$prev$p else compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} $prev$p" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$postdeps_CXX"; then postdeps_CXX=$prev$p else postdeps_CXX="${postdeps_CXX} $prev$p" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test no = "$pre_test_object_deps_done"; then if test -z "$predep_objects_CXX"; then predep_objects_CXX=$p else predep_objects_CXX="$predep_objects_CXX $p" fi else if test -z "$postdep_objects_CXX"; then postdep_objects_CXX=$p else postdep_objects_CXX="$postdep_objects_CXX $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling CXX test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken case $host_os in interix[3-9]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. predep_objects_CXX= postdep_objects_CXX= postdeps_CXX= ;; esac case " $postdeps_CXX " in *" -lc "*) archive_cmds_need_lc_CXX=no ;; esac compiler_lib_search_dirs_CXX= if test -n "${compiler_lib_search_path_CXX}"; then compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | $SED -e 's! -L! !g' -e 's!^ !!'` fi lt_prog_compiler_wl_CXX= lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX= # C++ specific cases for pic, static, wl, etc. if test yes = "$GXX"; then lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_CXX='-Bstatic' fi lt_prog_compiler_pic_CXX='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic_CXX='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic_CXX='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static_CXX='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic_CXX='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all lt_prog_compiler_pic_CXX= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static_CXX= ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic_CXX=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) lt_prog_compiler_pic_CXX='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic_CXX='-fPIC -shared' ;; *) lt_prog_compiler_pic_CXX='-fPIC' ;; esac else case $host_os in aix[4-9]*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_CXX='-Bstatic' else lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic_CXX='-DDLL_EXPORT' ;; dgux*) case $cc_basename in ec++*) lt_prog_compiler_pic_CXX='-KPIC' ;; ghcx*) # Green Hills C++ Compiler lt_prog_compiler_pic_CXX='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='$wl-a ${wl}archive' if test ia64 != "$host_cpu"; then lt_prog_compiler_pic_CXX='+Z' fi ;; aCC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='$wl-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic_CXX='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # KAI C++ Compiler lt_prog_compiler_wl_CXX='--backend -Wl,' lt_prog_compiler_pic_CXX='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64, which still supported -KPIC. lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-fPIC' lt_prog_compiler_static_CXX='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-fpic' lt_prog_compiler_static_CXX='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX='-non_shared' ;; xlc* | xlC* | bgxl[cC]* | mpixl[cC]*) # IBM XL 8.0, 9.0 on PPC and BlueGene lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-qpic' lt_prog_compiler_static_CXX='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' lt_prog_compiler_wl_CXX='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) lt_prog_compiler_pic_CXX='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic_CXX='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) lt_prog_compiler_wl_CXX='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 lt_prog_compiler_pic_CXX='-pic' ;; cxx*) # Digital/Compaq C++ lt_prog_compiler_wl_CXX='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' lt_prog_compiler_wl_CXX='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler lt_prog_compiler_pic_CXX='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x lt_prog_compiler_pic_CXX='-pic' lt_prog_compiler_static_CXX='-Bstatic' ;; lcc*) # Lucid lt_prog_compiler_pic_CXX='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 lt_prog_compiler_pic_CXX='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) lt_prog_compiler_can_build_shared_CXX=no ;; esac fi case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic_CXX= ;; *) lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } if ${lt_cv_prog_compiler_pic_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 $as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; } lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works_CXX=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works_CXX=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 $as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } if test yes = "$lt_cv_prog_compiler_pic_works_CXX"; then case $lt_prog_compiler_pic_CXX in "" | " "*) ;; *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; esac else lt_prog_compiler_pic_CXX= lt_prog_compiler_can_build_shared_CXX=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if ${lt_cv_prog_compiler_static_works_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works_CXX=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works_CXX=yes fi else lt_cv_prog_compiler_static_works_CXX=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 $as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } if test yes = "$lt_cv_prog_compiler_static_works_CXX"; then : else lt_prog_compiler_static_CXX= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o_CXX=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_CXX=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 $as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o_CXX=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_CXX=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 $as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } hard_links=nottested if test no = "$lt_cv_prog_compiler_c_o_CXX" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test no = "$hard_links"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 $as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' case $host_os in aix[4-9]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else export_symbols_cmds_CXX='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi ;; pw32*) export_symbols_cmds_CXX=$ltdll_cmds ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl*) exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' ;; esac ;; linux* | k*bsd*-gnu | gnu*) link_all_deplibs_CXX=no ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 $as_echo "$ld_shlibs_CXX" >&6; } test no = "$ld_shlibs_CXX" && can_build_shared=no with_gnu_ld_CXX=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc_CXX" in x|xyes) # Assume -lc should be added archive_cmds_need_lc_CXX=yes if test yes,yes = "$GCC,$enable_shared"; then case $archive_cmds_CXX in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then : $as_echo_n "(cached) " >&6 else $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl_CXX pic_flag=$lt_prog_compiler_pic_CXX compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag_CXX allow_undefined_flag_CXX= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc_CXX=no else lt_cv_archive_cmds_need_lc_CXX=yes fi allow_undefined_flag_CXX=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 $as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; } archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX ;; esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a(lib.so.V)' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. hardcode_libdir_flag_spec_CXX='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if ${lt_cv_shlibpath_overrides_runpath+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action_CXX= if test -n "$hardcode_libdir_flag_spec_CXX" || test -n "$runpath_var_CXX" || test yes = "$hardcode_automatic_CXX"; then # We can hardcode non-existent directories. if test no != "$hardcode_direct_CXX" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" && test no != "$hardcode_minus_L_CXX"; then # Linking always hardcodes the temporary library directory. hardcode_action_CXX=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action_CXX=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action_CXX=unsupported fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 $as_echo "$hardcode_action_CXX" >&6; } if test relink = "$hardcode_action_CXX" || test yes = "$inherit_rpath_CXX"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test yes != "$_lt_caught_CXX_error" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu LIBOPENMPT_LTVER_CURRENT=1 LIBOPENMPT_LTVER_REVISION=1 LIBOPENMPT_LTVER_AGE=1 $as_echo "#define MPT_SVNURL \"https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.3.6\"" >>confdefs.h $as_echo "#define MPT_SVNVERSION \"9580\"" >>confdefs.h $as_echo "#define MPT_SVNDATE \"2018-02-03T16:27:58.395807Z\"" >>confdefs.h $as_echo "#define MPT_PACKAGE true" >>confdefs.h case $host_os in mingw32*) LIBOPENMPT_WIN32_LIBS=-lrpcrt4 OPENMPT123_WIN32_LIBS=-lwinmm CXXFLAGS="$CXXFLAGS -municode" CFLAGS="$CFLAGS -municode" WIN32_CONSOLE_CXXFLAGS=-mconsole WIN32_CONSOLE_CFLAGS=-mconsole ;; *) LIBOPENMPT_WIN32_LIBS= OPENMPT123_WIN32_LIBS= WIN32_CONSOLE_CXXFLAGS= WIN32_CONSOLE_CFLAGS= ;; esac LIBOPENMPT_REQUIRES_PRIVATE= LIBOPENMPT_LIBS_PRIVATE= # Required libopenmpt dependency: zlib ZLIB_PKG= # Check whether --with-zlib was given. if test "${with_zlib+set}" = set; then : withval=$with_zlib; fi if test "x$with_zlib" != "xno"; then : pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ZLIB" >&5 $as_echo_n "checking for ZLIB... " >&6; } if test -n "$ZLIB_CFLAGS"; then pkg_cv_ZLIB_CFLAGS="$ZLIB_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"zlib\""; } >&5 ($PKG_CONFIG --exists --print-errors "zlib") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_ZLIB_CFLAGS=`$PKG_CONFIG --cflags "zlib" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$ZLIB_LIBS"; then pkg_cv_ZLIB_LIBS="$ZLIB_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"zlib\""; } >&5 ($PKG_CONFIG --exists --print-errors "zlib") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_ZLIB_LIBS=`$PKG_CONFIG --libs "zlib" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then ZLIB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "zlib" 2>&1` else ZLIB_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "zlib" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$ZLIB_PKG_ERRORS" >&5 as_fn_error $? "Unable to find zlib." "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "Unable to find zlib." "$LINENO" 5 else ZLIB_CFLAGS=$pkg_cv_ZLIB_CFLAGS ZLIB_LIBS=$pkg_cv_ZLIB_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ZLIB_PKG=zlib $as_echo "#define MPT_WITH_ZLIB /**/" >>confdefs.h fi fi # Required libopenmpt dependency: mpg123 MPG123_PKG= # Check whether --with-mpg123 was given. if test "${with_mpg123+set}" = set; then : withval=$with_mpg123; fi if test "x$with_mpg123" != "xno"; then : pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for MPG123" >&5 $as_echo_n "checking for MPG123... " >&6; } if test -n "$MPG123_CFLAGS"; then pkg_cv_MPG123_CFLAGS="$MPG123_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libmpg123 >= 1.13.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "libmpg123 >= 1.13.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_MPG123_CFLAGS=`$PKG_CONFIG --cflags "libmpg123 >= 1.13.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$MPG123_LIBS"; then pkg_cv_MPG123_LIBS="$MPG123_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libmpg123 >= 1.13.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "libmpg123 >= 1.13.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_MPG123_LIBS=`$PKG_CONFIG --libs "libmpg123 >= 1.13.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then MPG123_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libmpg123 >= 1.13.0" 2>&1` else MPG123_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libmpg123 >= 1.13.0" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$MPG123_PKG_ERRORS" >&5 as_fn_error $? "Unable to find libmpg123." "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "Unable to find libmpg123." "$LINENO" 5 else MPG123_CFLAGS=$pkg_cv_MPG123_CFLAGS MPG123_LIBS=$pkg_cv_MPG123_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } MPG123_PKG=libmpg123 $as_echo "#define MPT_WITH_MPG123 /**/" >>confdefs.h fi fi # Required libopenmpt dependency: ogg OGG_PKG= # Check whether --with-ogg was given. if test "${with_ogg+set}" = set; then : withval=$with_ogg; fi if test "x$with_ogg" != "xno"; then : pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OGG" >&5 $as_echo_n "checking for OGG... " >&6; } if test -n "$OGG_CFLAGS"; then pkg_cv_OGG_CFLAGS="$OGG_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ogg\""; } >&5 ($PKG_CONFIG --exists --print-errors "ogg") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_OGG_CFLAGS=`$PKG_CONFIG --cflags "ogg" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$OGG_LIBS"; then pkg_cv_OGG_LIBS="$OGG_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ogg\""; } >&5 ($PKG_CONFIG --exists --print-errors "ogg") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_OGG_LIBS=`$PKG_CONFIG --libs "ogg" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then OGG_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "ogg" 2>&1` else OGG_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "ogg" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$OGG_PKG_ERRORS" >&5 as_fn_error $? "Unable to find libogg." "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "Unable to find libogg." "$LINENO" 5 else OGG_CFLAGS=$pkg_cv_OGG_CFLAGS OGG_LIBS=$pkg_cv_OGG_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } OGG_PKG=ogg $as_echo "#define MPT_WITH_OGG /**/" >>confdefs.h fi fi # Required libopenmpt dependency: vorbis VORBIS_PKG= # Check whether --with-vorbis was given. if test "${with_vorbis+set}" = set; then : withval=$with_vorbis; fi if test "x$with_vorbis" != "xno"; then : pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for VORBIS" >&5 $as_echo_n "checking for VORBIS... " >&6; } if test -n "$VORBIS_CFLAGS"; then pkg_cv_VORBIS_CFLAGS="$VORBIS_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"vorbis\""; } >&5 ($PKG_CONFIG --exists --print-errors "vorbis") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_VORBIS_CFLAGS=`$PKG_CONFIG --cflags "vorbis" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$VORBIS_LIBS"; then pkg_cv_VORBIS_LIBS="$VORBIS_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"vorbis\""; } >&5 ($PKG_CONFIG --exists --print-errors "vorbis") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_VORBIS_LIBS=`$PKG_CONFIG --libs "vorbis" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then VORBIS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "vorbis" 2>&1` else VORBIS_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "vorbis" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$VORBIS_PKG_ERRORS" >&5 as_fn_error $? "Unable to find libvorbis." "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "Unable to find libvorbis." "$LINENO" 5 else VORBIS_CFLAGS=$pkg_cv_VORBIS_CFLAGS VORBIS_LIBS=$pkg_cv_VORBIS_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } VORBIS_PKG=vorbis $as_echo "#define MPT_WITH_VORBIS /**/" >>confdefs.h fi fi # Required libopenmpt dependency: vorbisfile VORBISFILE_PKG= # Check whether --with-vorbisfile was given. if test "${with_vorbisfile+set}" = set; then : withval=$with_vorbisfile; fi if test "x$with_vorbisfile" != "xno"; then : pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for VORBISFILE" >&5 $as_echo_n "checking for VORBISFILE... " >&6; } if test -n "$VORBISFILE_CFLAGS"; then pkg_cv_VORBISFILE_CFLAGS="$VORBISFILE_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"vorbisfile\""; } >&5 ($PKG_CONFIG --exists --print-errors "vorbisfile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_VORBISFILE_CFLAGS=`$PKG_CONFIG --cflags "vorbisfile" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$VORBISFILE_LIBS"; then pkg_cv_VORBISFILE_LIBS="$VORBISFILE_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"vorbisfile\""; } >&5 ($PKG_CONFIG --exists --print-errors "vorbisfile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_VORBISFILE_LIBS=`$PKG_CONFIG --libs "vorbisfile" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then VORBISFILE_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "vorbisfile" 2>&1` else VORBISFILE_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "vorbisfile" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$VORBISFILE_PKG_ERRORS" >&5 as_fn_error $? "Unable to find libvorbisfile." "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "Unable to find libvorbisfile." "$LINENO" 5 else VORBISFILE_CFLAGS=$pkg_cv_VORBISFILE_CFLAGS VORBISFILE_LIBS=$pkg_cv_VORBISFILE_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } VORBISFILE_PKG=vorbisfile $as_echo "#define MPT_WITH_VORBISFILE /**/" >>confdefs.h fi fi LIBOPENMPT_REQUIRES_PRIVATE="$ZLIB_PKG $MPG123_PKG $OGG_PKG $VORBIS_PKG $VORBISFILE_PKG" LIBOPENMPT_LIBS_PRIVATE="$CXXSTDLIB_PCLIBSPRIVATE" # openmpt123 # Check whether --enable-openmpt123 was given. if test "${enable_openmpt123+set}" = set; then : enableval=$enable_openmpt123; fi if test "x$enable_openmpt123" != "xno"; then ENABLE_OPENMPT123_TRUE= ENABLE_OPENMPT123_FALSE='#' else ENABLE_OPENMPT123_TRUE='#' ENABLE_OPENMPT123_FALSE= fi # examples # Check whether --enable-examples was given. if test "${enable_examples+set}" = set; then : enableval=$enable_examples; fi if test "x$enable_examples" != "xno"; then ENABLE_EXAMPLES_TRUE= ENABLE_EXAMPLES_FALSE='#' else ENABLE_EXAMPLES_TRUE='#' ENABLE_EXAMPLES_FALSE= fi # tests # Check whether --enable-tests was given. if test "${enable_tests+set}" = set; then : enableval=$enable_tests; fi if test "x$enable_tests" != "xno"; then ENABLE_TESTS_TRUE= ENABLE_TESTS_FALSE='#' else ENABLE_TESTS_TRUE='#' ENABLE_TESTS_FALSE= fi # Optional openmpt123 dependency # Check whether --with-pulseaudio was given. if test "${with_pulseaudio+set}" = set; then : withval=$with_pulseaudio; fi if test "x$enable_openmpt123" != "xno"; then : case $host_os in linux*) if test "x$with_pulseaudio" != "xno"; then : pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PULSEAUDIO" >&5 $as_echo_n "checking for PULSEAUDIO... " >&6; } if test -n "$PULSEAUDIO_CFLAGS"; then pkg_cv_PULSEAUDIO_CFLAGS="$PULSEAUDIO_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libpulse libpulse-simple\""; } >&5 ($PKG_CONFIG --exists --print-errors "libpulse libpulse-simple") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_PULSEAUDIO_CFLAGS=`$PKG_CONFIG --cflags "libpulse libpulse-simple" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$PULSEAUDIO_LIBS"; then pkg_cv_PULSEAUDIO_LIBS="$PULSEAUDIO_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libpulse libpulse-simple\""; } >&5 ($PKG_CONFIG --exists --print-errors "libpulse libpulse-simple") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_PULSEAUDIO_LIBS=`$PKG_CONFIG --libs "libpulse libpulse-simple" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then PULSEAUDIO_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libpulse libpulse-simple" 2>&1` else PULSEAUDIO_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libpulse libpulse-simple" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$PULSEAUDIO_PKG_ERRORS" >&5 have_pulseaudio=0 as_fn_error $? "Unable to find libpulse and/or libpulse-simple." "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } have_pulseaudio=0 as_fn_error $? "Unable to find libpulse and/or libpulse-simple." "$LINENO" 5 else PULSEAUDIO_CFLAGS=$pkg_cv_PULSEAUDIO_CFLAGS PULSEAUDIO_LIBS=$pkg_cv_PULSEAUDIO_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } have_pulseaudio=1 $as_echo "#define MPT_WITH_PULSEAUDIO /**/" >>confdefs.h fi else have_pulseaudio=0 fi ;; *) if test "x$with_pulseaudio" = "xyes"; then : pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PULSEAUDIO" >&5 $as_echo_n "checking for PULSEAUDIO... " >&6; } if test -n "$PULSEAUDIO_CFLAGS"; then pkg_cv_PULSEAUDIO_CFLAGS="$PULSEAUDIO_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libpulse libpulse-simple\""; } >&5 ($PKG_CONFIG --exists --print-errors "libpulse libpulse-simple") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_PULSEAUDIO_CFLAGS=`$PKG_CONFIG --cflags "libpulse libpulse-simple" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$PULSEAUDIO_LIBS"; then pkg_cv_PULSEAUDIO_LIBS="$PULSEAUDIO_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libpulse libpulse-simple\""; } >&5 ($PKG_CONFIG --exists --print-errors "libpulse libpulse-simple") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_PULSEAUDIO_LIBS=`$PKG_CONFIG --libs "libpulse libpulse-simple" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then PULSEAUDIO_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libpulse libpulse-simple" 2>&1` else PULSEAUDIO_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libpulse libpulse-simple" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$PULSEAUDIO_PKG_ERRORS" >&5 have_pulseaudio=0 as_fn_error $? "Unable to find libpulse and/or libpulse-simple." "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } have_pulseaudio=0 as_fn_error $? "Unable to find libpulse and/or libpulse-simple." "$LINENO" 5 else PULSEAUDIO_CFLAGS=$pkg_cv_PULSEAUDIO_CFLAGS PULSEAUDIO_LIBS=$pkg_cv_PULSEAUDIO_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } have_pulseaudio=1 $as_echo "#define MPT_WITH_PULSEAUDIO /**/" >>confdefs.h fi else have_pulseaudio=0 fi ;; esac else have_pulseaudio=0 fi # Optional openmpt123 and examples dependency # Check whether --with-portaudio was given. if test "${with_portaudio+set}" = set; then : withval=$with_portaudio; fi if test "x$enable_openmpt123$enable_examples" != "xnono"; then : if test "x$with_portaudio" != "xno"; then : pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PORTAUDIO" >&5 $as_echo_n "checking for PORTAUDIO... " >&6; } if test -n "$PORTAUDIO_CFLAGS"; then pkg_cv_PORTAUDIO_CFLAGS="$PORTAUDIO_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"portaudio-2.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "portaudio-2.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_PORTAUDIO_CFLAGS=`$PKG_CONFIG --cflags "portaudio-2.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$PORTAUDIO_LIBS"; then pkg_cv_PORTAUDIO_LIBS="$PORTAUDIO_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"portaudio-2.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "portaudio-2.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_PORTAUDIO_LIBS=`$PKG_CONFIG --libs "portaudio-2.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then PORTAUDIO_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "portaudio-2.0" 2>&1` else PORTAUDIO_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "portaudio-2.0" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$PORTAUDIO_PKG_ERRORS" >&5 have_portaudio=0 as_fn_error $? "Unable to find libportaudio." "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } have_portaudio=0 as_fn_error $? "Unable to find libportaudio." "$LINENO" 5 else PORTAUDIO_CFLAGS=$pkg_cv_PORTAUDIO_CFLAGS PORTAUDIO_LIBS=$pkg_cv_PORTAUDIO_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } have_portaudio=1 $as_echo "#define MPT_WITH_PORTAUDIO /**/" >>confdefs.h fi else have_portaudio=0 fi else have_portaudio=0 fi if test x$have_portaudio = x1; then HAVE_PORTAUDIO_TRUE= HAVE_PORTAUDIO_FALSE='#' else HAVE_PORTAUDIO_TRUE='#' HAVE_PORTAUDIO_FALSE= fi # Optional examples dependency: PortAudio C++ # Check whether --with-portaudiocpp was given. if test "${with_portaudiocpp+set}" = set; then : withval=$with_portaudiocpp; fi if test "x$enable_examples" != "xno"; then : if test "x$with_portaudiocpp" != "xno"; then : pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PORTAUDIOCPP" >&5 $as_echo_n "checking for PORTAUDIOCPP... " >&6; } if test -n "$PORTAUDIOCPP_CFLAGS"; then pkg_cv_PORTAUDIOCPP_CFLAGS="$PORTAUDIOCPP_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"portaudiocpp\""; } >&5 ($PKG_CONFIG --exists --print-errors "portaudiocpp") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_PORTAUDIOCPP_CFLAGS=`$PKG_CONFIG --cflags "portaudiocpp" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$PORTAUDIOCPP_LIBS"; then pkg_cv_PORTAUDIOCPP_LIBS="$PORTAUDIOCPP_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"portaudiocpp\""; } >&5 ($PKG_CONFIG --exists --print-errors "portaudiocpp") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_PORTAUDIOCPP_LIBS=`$PKG_CONFIG --libs "portaudiocpp" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then PORTAUDIOCPP_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "portaudiocpp" 2>&1` else PORTAUDIOCPP_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "portaudiocpp" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$PORTAUDIOCPP_PKG_ERRORS" >&5 have_portaudiocpp=0 as_fn_error $? "Unable to find libportaudiocpp." "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } have_portaudiocpp=0 as_fn_error $? "Unable to find libportaudiocpp." "$LINENO" 5 else PORTAUDIOCPP_CFLAGS=$pkg_cv_PORTAUDIOCPP_CFLAGS PORTAUDIOCPP_LIBS=$pkg_cv_PORTAUDIOCPP_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } have_portaudiocpp=1 $as_echo "#define MPT_WITH_PORTAUDIOCPP /**/" >>confdefs.h fi else have_portaudiocpp=0 fi else have_portaudicppo=0 fi if test x$have_portaudio = x1; then HAVE_PORTAUDIOCPP_TRUE= HAVE_PORTAUDIOCPP_FALSE='#' else HAVE_PORTAUDIOCPP_TRUE='#' HAVE_PORTAUDIOCPP_FALSE= fi # Optional disabled openmpt123 dependency: libsdl2 # Check whether --with-sdl2 was given. if test "${with_sdl2+set}" = set; then : withval=$with_sdl2; fi if test "x$enable_openmpt123" != "xno"; then : if test "x$with_sdl2" = "xyes"; then : pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SDL2" >&5 $as_echo_n "checking for SDL2... " >&6; } if test -n "$SDL2_CFLAGS"; then pkg_cv_SDL2_CFLAGS="$SDL2_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sdl2\""; } >&5 ($PKG_CONFIG --exists --print-errors "sdl2") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_SDL2_CFLAGS=`$PKG_CONFIG --cflags "sdl2" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$SDL2_LIBS"; then pkg_cv_SDL2_LIBS="$SDL2_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sdl2\""; } >&5 ($PKG_CONFIG --exists --print-errors "sdl2") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_SDL2_LIBS=`$PKG_CONFIG --libs "sdl2" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then SDL2_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "sdl2" 2>&1` else SDL2_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "sdl2" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$SDL2_PKG_ERRORS" >&5 as_fn_error $? "Unable to find libsdl2." "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "Unable to find libsdl2." "$LINENO" 5 else SDL2_CFLAGS=$pkg_cv_SDL2_CFLAGS SDL2_LIBS=$pkg_cv_SDL2_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define MPT_WITH_SDL2 /**/" >>confdefs.h fi fi fi # Optional disabled openmpt123 dependency: libsdl # Check whether --with-sdl was given. if test "${with_sdl+set}" = set; then : withval=$with_sdl; fi if test "x$enable_openmpt123" != "xno"; then : if test "x$with_sdl" = "xyes"; then : pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SDL" >&5 $as_echo_n "checking for SDL... " >&6; } if test -n "$SDL_CFLAGS"; then pkg_cv_SDL_CFLAGS="$SDL_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sdl\""; } >&5 ($PKG_CONFIG --exists --print-errors "sdl") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_SDL_CFLAGS=`$PKG_CONFIG --cflags "sdl" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$SDL_LIBS"; then pkg_cv_SDL_LIBS="$SDL_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sdl\""; } >&5 ($PKG_CONFIG --exists --print-errors "sdl") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_SDL_LIBS=`$PKG_CONFIG --libs "sdl" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then SDL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "sdl" 2>&1` else SDL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "sdl" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$SDL_PKG_ERRORS" >&5 as_fn_error $? "Unable to find libsdl." "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "Unable to find libsdl." "$LINENO" 5 else SDL_CFLAGS=$pkg_cv_SDL_CFLAGS SDL_LIBS=$pkg_cv_SDL_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define MPT_WITH_SDL /**/" >>confdefs.h fi fi fi # Optional openmpt123 dependency: libsndfile # Check whether --with-sndfile was given. if test "${with_sndfile+set}" = set; then : withval=$with_sndfile; fi if test "x$enable_openmpt123" != "xno"; then : if test "x$with_sndfile" != "xno"; then : pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SNDFILE" >&5 $as_echo_n "checking for SNDFILE... " >&6; } if test -n "$SNDFILE_CFLAGS"; then pkg_cv_SNDFILE_CFLAGS="$SNDFILE_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sndfile\""; } >&5 ($PKG_CONFIG --exists --print-errors "sndfile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_SNDFILE_CFLAGS=`$PKG_CONFIG --cflags "sndfile" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$SNDFILE_LIBS"; then pkg_cv_SNDFILE_LIBS="$SNDFILE_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sndfile\""; } >&5 ($PKG_CONFIG --exists --print-errors "sndfile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_SNDFILE_LIBS=`$PKG_CONFIG --libs "sndfile" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then SNDFILE_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "sndfile" 2>&1` else SNDFILE_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "sndfile" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$SNDFILE_PKG_ERRORS" >&5 as_fn_error $? "Unable to find libsndfile." "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "Unable to find libsndfile." "$LINENO" 5 else SNDFILE_CFLAGS=$pkg_cv_SNDFILE_CFLAGS SNDFILE_LIBS=$pkg_cv_SNDFILE_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define MPT_WITH_SNDFILE /**/" >>confdefs.h fi fi fi # Optional openmpt123 dependency: libFLAC # Check whether --with-flac was given. if test "${with_flac+set}" = set; then : withval=$with_flac; fi if test "x$enable_openmpt123" != "xno"; then : if test "x$with_flac" != "xno"; then : pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for FLAC" >&5 $as_echo_n "checking for FLAC... " >&6; } if test -n "$FLAC_CFLAGS"; then pkg_cv_FLAC_CFLAGS="$FLAC_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"flac >= 1.3.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "flac >= 1.3.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_FLAC_CFLAGS=`$PKG_CONFIG --cflags "flac >= 1.3.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$FLAC_LIBS"; then pkg_cv_FLAC_LIBS="$FLAC_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"flac >= 1.3.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "flac >= 1.3.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_FLAC_LIBS=`$PKG_CONFIG --libs "flac >= 1.3.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then FLAC_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "flac >= 1.3.0" 2>&1` else FLAC_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "flac >= 1.3.0" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$FLAC_PKG_ERRORS" >&5 as_fn_error $? "Unable to find libflac >= 1.3.0." "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "Unable to find libflac >= 1.3.0." "$LINENO" 5 else FLAC_CFLAGS=$pkg_cv_FLAC_CFLAGS FLAC_LIBS=$pkg_cv_FLAC_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define MPT_WITH_FLAC /**/" >>confdefs.h fi fi fi # We want a modern C compiler case $ac_cv_prog_cc_stdc in #( no) : ac_cv_prog_cc_c99=no; ac_cv_prog_cc_c89=no ;; #( *) : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C99" >&5 $as_echo_n "checking for $CC option to accept ISO C99... " >&6; } if ${ac_cv_prog_cc_c99+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c99=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include #include // Check varargs macros. These examples are taken from C99 6.10.3.5. #define debug(...) fprintf (stderr, __VA_ARGS__) #define showlist(...) puts (#__VA_ARGS__) #define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) static void test_varargs_macros (void) { int x = 1234; int y = 5678; debug ("Flag"); debug ("X = %d\n", x); showlist (The first, second, and third items.); report (x>y, "x is %d but y is %d", x, y); } // Check long long types. #define BIG64 18446744073709551615ull #define BIG32 4294967295ul #define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) #if !BIG_OK your preprocessor is broken; #endif #if BIG_OK #else your preprocessor is broken; #endif static long long int bignum = -9223372036854775807LL; static unsigned long long int ubignum = BIG64; struct incomplete_array { int datasize; double data[]; }; struct named_init { int number; const wchar_t *name; double average; }; typedef const char *ccp; static inline int test_restrict (ccp restrict text) { // See if C++-style comments work. // Iterate through items via the restricted pointer. // Also check for declarations in for loops. for (unsigned int i = 0; *(text+i) != '\0'; ++i) continue; return 0; } // Check varargs and va_copy. static void test_varargs (const char *format, ...) { va_list args; va_start (args, format); va_list args_copy; va_copy (args_copy, args); const char *str; int number; float fnumber; while (*format) { switch (*format++) { case 's': // string str = va_arg (args_copy, const char *); break; case 'd': // int number = va_arg (args_copy, int); break; case 'f': // float fnumber = va_arg (args_copy, double); break; default: break; } } va_end (args_copy); va_end (args); } int main () { // Check bool. _Bool success = false; // Check restrict. if (test_restrict ("String literal") == 0) success = true; char *restrict newvar = "Another string"; // Check varargs. test_varargs ("s, d' f .", "string", 65, 34.234); test_varargs_macros (); // Check flexible array members. struct incomplete_array *ia = malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); ia->datasize = 10; for (int i = 0; i < ia->datasize; ++i) ia->data[i] = i * 1.234; // Check named initializers. struct named_init ni = { .number = 34, .name = L"Test wide string", .average = 543.34343, }; ni.number = 58; int dynamic_array[ni.number]; dynamic_array[ni.number - 1] = 543; // work around unused variable warnings return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x' || dynamic_array[ni.number - 1] != 543); ; return 0; } _ACEOF for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99 do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c99=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c99" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c99" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c99" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 $as_echo "$ac_cv_prog_cc_c99" >&6; } ;; esac if test "x$ac_cv_prog_cc_c99" != xno; then : ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 else ac_cv_prog_cc_stdc=no fi fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO Standard C" >&5 $as_echo_n "checking for $CC option to accept ISO Standard C... " >&6; } if ${ac_cv_prog_cc_stdc+:} false; then : $as_echo_n "(cached) " >&6 fi case $ac_cv_prog_cc_stdc in #( no) : { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; #( '') : { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; #( *) : { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_stdc" >&5 $as_echo "$ac_cv_prog_cc_stdc" >&6; } ;; esac #AC_PROG_CC_C99 #AC_LANG_PUSH([C]) #AX_CHECK_COMPILE_FLAG([-std=c++0x], [CFLAGS="$CFLAGS -std=c99"]) #AC_LANG_POP([C]) # We need basic C++11 support (implementing C++03TR2 features in namespace std::) ax_cxx_compile_cxx11_required=false ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_success=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features by default" >&5 $as_echo_n "checking whether $CXX supports C++11 features by default... " >&6; } if ${ax_cv_cxx_compile_cxx11+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ // If the compiler admits that it is not ready for C++11, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" #elif __cplusplus < 201103L #error "This is not a C++11 compiler" #else namespace cxx11 { namespace test_static_assert { template struct check { static_assert(sizeof(int) <= sizeof(T), "not big enough"); }; } namespace test_final_override { struct Base { virtual void f() {} }; struct Derived : public Base { virtual void f() override {} }; } namespace test_double_right_angle_brackets { template < typename T > struct check {}; typedef check single_type; typedef check> double_type; typedef check>> triple_type; typedef check>>> quadruple_type; } namespace test_decltype { int f() { int a = 1; decltype(a) b = 2; return a + b; } } namespace test_type_deduction { template < typename T1, typename T2 > struct is_same { static const bool value = false; }; template < typename T > struct is_same { static const bool value = true; }; template < typename T1, typename T2 > auto add(T1 a1, T2 a2) -> decltype(a1 + a2) { return a1 + a2; } int test(const int c, volatile int v) { static_assert(is_same::value == true, ""); static_assert(is_same::value == false, ""); static_assert(is_same::value == false, ""); auto ac = c; auto av = v; auto sumi = ac + av + 'x'; auto sumf = ac + av + 1.0; static_assert(is_same::value == true, ""); static_assert(is_same::value == true, ""); static_assert(is_same::value == true, ""); static_assert(is_same::value == false, ""); static_assert(is_same::value == true, ""); return (sumf > 0.0) ? sumi : add(c, v); } } namespace test_noexcept { int f() { return 0; } int g() noexcept { return 0; } static_assert(noexcept(f()) == false, ""); static_assert(noexcept(g()) == true, ""); } namespace test_constexpr { template < typename CharT > unsigned long constexpr strlen_c_r(const CharT *const s, const unsigned long acc) noexcept { return *s ? strlen_c_r(s + 1, acc + 1) : acc; } template < typename CharT > unsigned long constexpr strlen_c(const CharT *const s) noexcept { return strlen_c_r(s, 0UL); } static_assert(strlen_c("") == 0UL, ""); static_assert(strlen_c("1") == 1UL, ""); static_assert(strlen_c("example") == 7UL, ""); static_assert(strlen_c("another\0example") == 7UL, ""); } namespace test_rvalue_references { template < int N > struct answer { static constexpr int value = N; }; answer<1> f(int&) { return answer<1>(); } answer<2> f(const int&) { return answer<2>(); } answer<3> f(int&&) { return answer<3>(); } void test() { int i = 0; const int c = 0; static_assert(decltype(f(i))::value == 1, ""); static_assert(decltype(f(c))::value == 2, ""); static_assert(decltype(f(0))::value == 3, ""); } } namespace test_uniform_initialization { struct test { static const int zero {}; static const int one {1}; }; static_assert(test::zero == 0, ""); static_assert(test::one == 1, ""); } namespace test_lambdas { void test1() { auto lambda1 = [](){}; auto lambda2 = lambda1; lambda1(); lambda2(); } int test2() { auto a = [](int i, int j){ return i + j; }(1, 2); auto b = []() -> int { return '0'; }(); auto c = [=](){ return a + b; }(); auto d = [&](){ return c; }(); auto e = [a, &b](int x) mutable { const auto identity = [](int y){ return y; }; for (auto i = 0; i < a; ++i) a += b--; return x + identity(a + b); }(0); return a + b + c + d + e; } int test3() { const auto nullary = [](){ return 0; }; const auto unary = [](int x){ return x; }; using nullary_t = decltype(nullary); using unary_t = decltype(unary); const auto higher1st = [](nullary_t f){ return f(); }; const auto higher2nd = [unary](nullary_t f1){ return [unary, f1](unary_t f2){ return f2(unary(f1())); }; }; return higher1st(nullary) + higher2nd(nullary)(unary); } } namespace test_variadic_templates { template struct sum; template struct sum { static constexpr auto value = N0 + sum::value; }; template <> struct sum<> { static constexpr auto value = 0; }; static_assert(sum<>::value == 0, ""); static_assert(sum<1>::value == 1, ""); static_assert(sum<23>::value == 23, ""); static_assert(sum<1, 2>::value == 3, ""); static_assert(sum<5, 5, 11>::value == 21, ""); static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); } // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function // because of this. namespace test_template_alias_sfinae { struct foo {}; template using member = typename T::member_type; template void func(...) {} template void func(member*) {} void test(); void test() { func(0); } } } // namespace cxx11 #endif // __cplusplus >= 201103L _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ax_cv_cxx_compile_cxx11=yes else ax_cv_cxx_compile_cxx11=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_cxx_compile_cxx11" >&5 $as_echo "$ax_cv_cxx_compile_cxx11" >&6; } if test x$ax_cv_cxx_compile_cxx11 = xyes; then ac_success=yes fi if test x$ac_success = xno; then for switch in -std=c++11 -std=c++0x +std=c++11 "-h std=c++11"; do cachevar=`$as_echo "ax_cv_cxx_compile_cxx11_$switch" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features with $switch" >&5 $as_echo_n "checking whether $CXX supports C++11 features with $switch... " >&6; } if eval \${$cachevar+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_CXX="$CXX" CXX="$CXX $switch" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ // If the compiler admits that it is not ready for C++11, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" #elif __cplusplus < 201103L #error "This is not a C++11 compiler" #else namespace cxx11 { namespace test_static_assert { template struct check { static_assert(sizeof(int) <= sizeof(T), "not big enough"); }; } namespace test_final_override { struct Base { virtual void f() {} }; struct Derived : public Base { virtual void f() override {} }; } namespace test_double_right_angle_brackets { template < typename T > struct check {}; typedef check single_type; typedef check> double_type; typedef check>> triple_type; typedef check>>> quadruple_type; } namespace test_decltype { int f() { int a = 1; decltype(a) b = 2; return a + b; } } namespace test_type_deduction { template < typename T1, typename T2 > struct is_same { static const bool value = false; }; template < typename T > struct is_same { static const bool value = true; }; template < typename T1, typename T2 > auto add(T1 a1, T2 a2) -> decltype(a1 + a2) { return a1 + a2; } int test(const int c, volatile int v) { static_assert(is_same::value == true, ""); static_assert(is_same::value == false, ""); static_assert(is_same::value == false, ""); auto ac = c; auto av = v; auto sumi = ac + av + 'x'; auto sumf = ac + av + 1.0; static_assert(is_same::value == true, ""); static_assert(is_same::value == true, ""); static_assert(is_same::value == true, ""); static_assert(is_same::value == false, ""); static_assert(is_same::value == true, ""); return (sumf > 0.0) ? sumi : add(c, v); } } namespace test_noexcept { int f() { return 0; } int g() noexcept { return 0; } static_assert(noexcept(f()) == false, ""); static_assert(noexcept(g()) == true, ""); } namespace test_constexpr { template < typename CharT > unsigned long constexpr strlen_c_r(const CharT *const s, const unsigned long acc) noexcept { return *s ? strlen_c_r(s + 1, acc + 1) : acc; } template < typename CharT > unsigned long constexpr strlen_c(const CharT *const s) noexcept { return strlen_c_r(s, 0UL); } static_assert(strlen_c("") == 0UL, ""); static_assert(strlen_c("1") == 1UL, ""); static_assert(strlen_c("example") == 7UL, ""); static_assert(strlen_c("another\0example") == 7UL, ""); } namespace test_rvalue_references { template < int N > struct answer { static constexpr int value = N; }; answer<1> f(int&) { return answer<1>(); } answer<2> f(const int&) { return answer<2>(); } answer<3> f(int&&) { return answer<3>(); } void test() { int i = 0; const int c = 0; static_assert(decltype(f(i))::value == 1, ""); static_assert(decltype(f(c))::value == 2, ""); static_assert(decltype(f(0))::value == 3, ""); } } namespace test_uniform_initialization { struct test { static const int zero {}; static const int one {1}; }; static_assert(test::zero == 0, ""); static_assert(test::one == 1, ""); } namespace test_lambdas { void test1() { auto lambda1 = [](){}; auto lambda2 = lambda1; lambda1(); lambda2(); } int test2() { auto a = [](int i, int j){ return i + j; }(1, 2); auto b = []() -> int { return '0'; }(); auto c = [=](){ return a + b; }(); auto d = [&](){ return c; }(); auto e = [a, &b](int x) mutable { const auto identity = [](int y){ return y; }; for (auto i = 0; i < a; ++i) a += b--; return x + identity(a + b); }(0); return a + b + c + d + e; } int test3() { const auto nullary = [](){ return 0; }; const auto unary = [](int x){ return x; }; using nullary_t = decltype(nullary); using unary_t = decltype(unary); const auto higher1st = [](nullary_t f){ return f(); }; const auto higher2nd = [unary](nullary_t f1){ return [unary, f1](unary_t f2){ return f2(unary(f1())); }; }; return higher1st(nullary) + higher2nd(nullary)(unary); } } namespace test_variadic_templates { template struct sum; template struct sum { static constexpr auto value = N0 + sum::value; }; template <> struct sum<> { static constexpr auto value = 0; }; static_assert(sum<>::value == 0, ""); static_assert(sum<1>::value == 1, ""); static_assert(sum<23>::value == 23, ""); static_assert(sum<1, 2>::value == 3, ""); static_assert(sum<5, 5, 11>::value == 21, ""); static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); } // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function // because of this. namespace test_template_alias_sfinae { struct foo {}; template using member = typename T::member_type; template void func(...) {} template void func(member*) {} void test(); void test() { func(0); } } } // namespace cxx11 #endif // __cplusplus >= 201103L _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : eval $cachevar=yes else eval $cachevar=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CXX="$ac_save_CXX" fi eval ac_res=\$$cachevar { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test x\$$cachevar = xyes; then CXX="$CXX $switch" if test -n "$CXXCPP" ; then CXXCPP="$CXXCPP $switch" fi ac_success=yes break fi done fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test x$ax_cxx_compile_cxx11_required = xtrue; then if test x$ac_success = xno; then as_fn_error $? "*** A compiler with support for C++11 language features is required." "$LINENO" 5 fi fi if test x$ac_success = xno; then HAVE_CXX11=0 { $as_echo "$as_me:${as_lineno-$LINENO}: No compiler with C++11 support was found" >&5 $as_echo "$as_me: No compiler with C++11 support was found" >&6;} else HAVE_CXX11=1 $as_echo "#define HAVE_CXX11 1" >>confdefs.h fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu # Even if AX_CXX_COMPILE_STDCXX_11 fails, std=c++0x on older GCC and Clang compilers enables enough of C++11 for libopenmpt to build. if test "x$HAVE_CXX11" = x0; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts -std=c++0x" >&5 $as_echo_n "checking whether C++ compiler accepts -std=c++0x... " >&6; } if ${ax_cv_check_cxxflags___std_cpp0x+:} false; then : $as_echo_n "(cached) " >&6 else ax_check_save_flags=$CXXFLAGS CXXFLAGS="$CXXFLAGS -std=c++0x" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ax_cv_check_cxxflags___std_cpp0x=yes else ax_cv_check_cxxflags___std_cpp0x=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CXXFLAGS=$ax_check_save_flags fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cxxflags___std_cpp0x" >&5 $as_echo "$ax_cv_check_cxxflags___std_cpp0x" >&6; } if test "x$ax_cv_check_cxxflags___std_cpp0x" = xyes; then : CXXFLAGS="$CXXFLAGS -std=c++0x" else : fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fvisibility=hidden" >&5 $as_echo_n "checking whether C compiler accepts -fvisibility=hidden... " >&6; } if ${ax_cv_check_cflags___fvisibility_hidden+:} false; then : $as_echo_n "(cached) " >&6 else ax_check_save_flags=$CFLAGS CFLAGS="$CFLAGS -fvisibility=hidden" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ax_cv_check_cflags___fvisibility_hidden=yes else ax_cv_check_cflags___fvisibility_hidden=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS=$ax_check_save_flags fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___fvisibility_hidden" >&5 $as_echo "$ax_cv_check_cflags___fvisibility_hidden" >&6; } if test "x$ax_cv_check_cflags___fvisibility_hidden" = xyes; then : CFLAGS="$CFLAGS -fvisibility=hidden" else : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking CFLAGS for maximum warnings" >&5 $as_echo_n "checking CFLAGS for maximum warnings... " >&6; } if ${ac_cv_cflags_warn_all+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_cflags_warn_all="no, unknown" ac_save_CFLAGS="$CFLAGS" for ac_arg in "-warn all % -warn all" "-pedantic % -Wall" "-xstrconst % -v" "-std1 % -verbose -w0 -warnprotos" "-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" "-ansi -ansiE % -fullwarn" "+ESlit % +w1" "-Xc % -pvctl,fullmsg" "-h conform % -h msglevel 2" # do CFLAGS="$ac_save_CFLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_cflags_warn_all=`echo $ac_arg | sed -e 's,.*% *,,'` ; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done CFLAGS="$ac_save_CFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cflags_warn_all" >&5 $as_echo "$ac_cv_cflags_warn_all" >&6; } case ".$ac_cv_cflags_warn_all" in .ok|.ok,*) ;; .|.no|.no,*) ;; *) if ${CFLAGS+:} false; then : case " $CFLAGS " in #( *" $ac_cv_cflags_warn_all "*) : { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$ac_cv_cflags_warn_all"; } >&5 (: CFLAGS already contains $ac_cv_cflags_warn_all) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } ;; #( *) : as_fn_append CFLAGS " $ac_cv_cflags_warn_all" { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5 (: CFLAGS="$CFLAGS") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } ;; esac else CFLAGS=$ac_cv_cflags_warn_all { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5 (: CFLAGS="$CFLAGS") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } fi ;; esac ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts -fvisibility=hidden" >&5 $as_echo_n "checking whether C++ compiler accepts -fvisibility=hidden... " >&6; } if ${ax_cv_check_cxxflags___fvisibility_hidden+:} false; then : $as_echo_n "(cached) " >&6 else ax_check_save_flags=$CXXFLAGS CXXFLAGS="$CXXFLAGS -fvisibility=hidden" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ax_cv_check_cxxflags___fvisibility_hidden=yes else ax_cv_check_cxxflags___fvisibility_hidden=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CXXFLAGS=$ax_check_save_flags fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cxxflags___fvisibility_hidden" >&5 $as_echo "$ax_cv_check_cxxflags___fvisibility_hidden" >&6; } if test "x$ax_cv_check_cxxflags___fvisibility_hidden" = xyes; then : CXXFLAGS="$CXXFLAGS -fvisibility=hidden" else : fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking CXXFLAGS for maximum warnings" >&5 $as_echo_n "checking CXXFLAGS for maximum warnings... " >&6; } if ${ac_cv_cxxflags_warn_all+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_cxxflags_warn_all="no, unknown" ac_save_CXXFLAGS="$CXXFLAGS" for ac_arg in "-warn all % -warn all" "-pedantic % -Wall" "-xstrconst % -v" "-std1 % -verbose -w0 -warnprotos" "-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" "-ansi -ansiE % -fullwarn" "+ESlit % +w1" "-Xc % -pvctl,fullmsg" "-h conform % -h msglevel 2" # do CXXFLAGS="$ac_save_CXXFLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_cxxflags_warn_all=`echo $ac_arg | sed -e 's,.*% *,,'` ; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done CXXFLAGS="$ac_save_CXXFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxxflags_warn_all" >&5 $as_echo "$ac_cv_cxxflags_warn_all" >&6; } case ".$ac_cv_cxxflags_warn_all" in .ok|.ok,*) ;; .|.no|.no,*) ;; *) if ${CXXFLAGS+:} false; then : case " $CXXFLAGS " in #( *" $ac_cv_cxxflags_warn_all "*) : { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS already contains \$ac_cv_cxxflags_warn_all"; } >&5 (: CXXFLAGS already contains $ac_cv_cxxflags_warn_all) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } ;; #( *) : as_fn_append CXXFLAGS " $ac_cv_cxxflags_warn_all" { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS=\"\$CXXFLAGS\""; } >&5 (: CXXFLAGS="$CXXFLAGS") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } ;; esac else CXXFLAGS=$ac_cv_cxxflags_warn_all { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS=\"\$CXXFLAGS\""; } >&5 (: CXXFLAGS="$CXXFLAGS") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } fi ;; esac ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # libmodplug emulation # Check whether --enable-libopenmpt_modplug was given. if test "${enable_libopenmpt_modplug+set}" = set; then : enableval=$enable_libopenmpt_modplug; fi if test "x$enable_libopenmpt_modplug" = "xyes"; then ENABLE_LIBOPENMPT_MODPLUG_TRUE= ENABLE_LIBOPENMPT_MODPLUG_FALSE='#' else ENABLE_LIBOPENMPT_MODPLUG_TRUE='#' ENABLE_LIBOPENMPT_MODPLUG_FALSE= fi # libmodplug replacement # Check whether --enable-libmodplug was given. if test "${enable_libmodplug+set}" = set; then : enableval=$enable_libmodplug; fi if test "x$enable_libmodplug" = "xyes"; then ENABLE_LIBMODPLUG_TRUE= ENABLE_LIBMODPLUG_FALSE='#' else ENABLE_LIBMODPLUG_TRUE='#' ENABLE_LIBMODPLUG_FALSE= fi # Files: DX_PROJECT=libopenmpt DX_CONFIG='Doxyfile' DX_DOCDIR='doxygen-doc' # Environment variables used inside doxygen.cfg: DX_ENV="$DX_ENV SRCDIR='$srcdir'" SRCDIR=$srcdir DX_ENV="$DX_ENV PROJECT='$DX_PROJECT'" PROJECT=$DX_PROJECT DX_ENV="$DX_ENV VERSION='$PACKAGE_VERSION'" # Doxygen itself: # Check whether --enable-doxygen-doc was given. if test "${enable_doxygen_doc+set}" = set; then : enableval=$enable_doxygen_doc; case "$enableval" in #( y|Y|yes|Yes|YES) DX_FLAG_doc=1 ;; #( n|N|no|No|NO) DX_FLAG_doc=0 ;; #( *) as_fn_error $? "invalid value '$enableval' given to doxygen-doc" "$LINENO" 5 ;; esac else DX_FLAG_doc=1 fi if test "$DX_FLAG_doc" = 1; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}doxygen", so it can be a program name with args. set dummy ${ac_tool_prefix}doxygen; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_DX_DOXYGEN+:} false; then : $as_echo_n "(cached) " >&6 else case $DX_DOXYGEN in [\\/]* | ?:[\\/]*) ac_cv_path_DX_DOXYGEN="$DX_DOXYGEN" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_DX_DOXYGEN="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi DX_DOXYGEN=$ac_cv_path_DX_DOXYGEN if test -n "$DX_DOXYGEN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DX_DOXYGEN" >&5 $as_echo "$DX_DOXYGEN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_DX_DOXYGEN"; then ac_pt_DX_DOXYGEN=$DX_DOXYGEN # Extract the first word of "doxygen", so it can be a program name with args. set dummy doxygen; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_DX_DOXYGEN+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_DX_DOXYGEN in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_DX_DOXYGEN="$ac_pt_DX_DOXYGEN" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_DX_DOXYGEN="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_DX_DOXYGEN=$ac_cv_path_ac_pt_DX_DOXYGEN if test -n "$ac_pt_DX_DOXYGEN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_DX_DOXYGEN" >&5 $as_echo "$ac_pt_DX_DOXYGEN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_DX_DOXYGEN" = x; then DX_DOXYGEN="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DX_DOXYGEN=$ac_pt_DX_DOXYGEN fi else DX_DOXYGEN="$ac_cv_path_DX_DOXYGEN" fi if test "$DX_FLAG_doc$DX_DOXYGEN" = 1; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: doxygen not found - will not generate any doxygen documentation" >&5 $as_echo "$as_me: WARNING: doxygen not found - will not generate any doxygen documentation" >&2;} DX_FLAG_doc=0 fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}perl", so it can be a program name with args. set dummy ${ac_tool_prefix}perl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_DX_PERL+:} false; then : $as_echo_n "(cached) " >&6 else case $DX_PERL in [\\/]* | ?:[\\/]*) ac_cv_path_DX_PERL="$DX_PERL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_DX_PERL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi DX_PERL=$ac_cv_path_DX_PERL if test -n "$DX_PERL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DX_PERL" >&5 $as_echo "$DX_PERL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_DX_PERL"; then ac_pt_DX_PERL=$DX_PERL # Extract the first word of "perl", so it can be a program name with args. set dummy perl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_DX_PERL+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_DX_PERL in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_DX_PERL="$ac_pt_DX_PERL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_DX_PERL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_DX_PERL=$ac_cv_path_ac_pt_DX_PERL if test -n "$ac_pt_DX_PERL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_DX_PERL" >&5 $as_echo "$ac_pt_DX_PERL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_DX_PERL" = x; then DX_PERL="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DX_PERL=$ac_pt_DX_PERL fi else DX_PERL="$ac_cv_path_DX_PERL" fi if test "$DX_FLAG_doc$DX_PERL" = 1; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: perl not found - will not generate any doxygen documentation" >&5 $as_echo "$as_me: WARNING: perl not found - will not generate any doxygen documentation" >&2;} DX_FLAG_doc=0 fi : fi if test "$DX_FLAG_doc" = 1; then DX_ENV="$DX_ENV PERL_PATH='$DX_PERL'" PERL_PATH=$DX_PERL : else : fi # Dot for graphics: # Check whether --enable-doxygen-dot was given. if test "${enable_doxygen_dot+set}" = set; then : enableval=$enable_doxygen_dot; case "$enableval" in #( y|Y|yes|Yes|YES) DX_FLAG_dot=1 test "$DX_FLAG_doc" = "1" \ || as_fn_error $? "doxygen-dot requires doxygen-dot" "$LINENO" 5 ;; #( n|N|no|No|NO) DX_FLAG_dot=0 ;; #( *) as_fn_error $? "invalid value '$enableval' given to doxygen-dot" "$LINENO" 5 ;; esac else DX_FLAG_dot=0 test "$DX_FLAG_doc" = "1" || DX_FLAG_dot=0 fi if test "$DX_FLAG_dot" = 1; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dot", so it can be a program name with args. set dummy ${ac_tool_prefix}dot; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_DX_DOT+:} false; then : $as_echo_n "(cached) " >&6 else case $DX_DOT in [\\/]* | ?:[\\/]*) ac_cv_path_DX_DOT="$DX_DOT" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_DX_DOT="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi DX_DOT=$ac_cv_path_DX_DOT if test -n "$DX_DOT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DX_DOT" >&5 $as_echo "$DX_DOT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_DX_DOT"; then ac_pt_DX_DOT=$DX_DOT # Extract the first word of "dot", so it can be a program name with args. set dummy dot; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_DX_DOT+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_DX_DOT in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_DX_DOT="$ac_pt_DX_DOT" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_DX_DOT="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_DX_DOT=$ac_cv_path_ac_pt_DX_DOT if test -n "$ac_pt_DX_DOT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_DX_DOT" >&5 $as_echo "$ac_pt_DX_DOT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_DX_DOT" = x; then DX_DOT="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DX_DOT=$ac_pt_DX_DOT fi else DX_DOT="$ac_cv_path_DX_DOT" fi if test "$DX_FLAG_dot$DX_DOT" = 1; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: dot not found - will not generate graphics for doxygen documentation" >&5 $as_echo "$as_me: WARNING: dot not found - will not generate graphics for doxygen documentation" >&2;} DX_FLAG_dot=0 fi : fi if test "$DX_FLAG_dot" = 1; then DX_ENV="$DX_ENV HAVE_DOT='YES'" HAVE_DOT=YES DX_ENV="$DX_ENV DOT_PATH='`expr ".$DX_DOT" : '\(\.\)[^/]*$' \| "x$DX_DOT" : 'x\(.*\)/[^/]*$'`'" DOT_PATH=`expr ".$DX_DOT" : '\(\.\)[^/]*$' \| "x$DX_DOT" : 'x\(.*\)/[^/]*$'` : else DX_ENV="$DX_ENV HAVE_DOT='NO'" HAVE_DOT=NO : fi # Man pages generation: # Check whether --enable-doxygen-man was given. if test "${enable_doxygen_man+set}" = set; then : enableval=$enable_doxygen_man; case "$enableval" in #( y|Y|yes|Yes|YES) DX_FLAG_man=1 test "$DX_FLAG_doc" = "1" \ || as_fn_error $? "doxygen-man requires doxygen-man" "$LINENO" 5 ;; #( n|N|no|No|NO) DX_FLAG_man=0 ;; #( *) as_fn_error $? "invalid value '$enableval' given to doxygen-man" "$LINENO" 5 ;; esac else DX_FLAG_man=0 test "$DX_FLAG_doc" = "1" || DX_FLAG_man=0 fi if test "$DX_FLAG_man" = 1; then : fi if test "$DX_FLAG_man" = 1; then DX_ENV="$DX_ENV GENERATE_MAN='YES'" GENERATE_MAN=YES : else DX_ENV="$DX_ENV GENERATE_MAN='NO'" GENERATE_MAN=NO : fi # RTF file generation: # Check whether --enable-doxygen-rtf was given. if test "${enable_doxygen_rtf+set}" = set; then : enableval=$enable_doxygen_rtf; case "$enableval" in #( y|Y|yes|Yes|YES) DX_FLAG_rtf=1 test "$DX_FLAG_doc" = "1" \ || as_fn_error $? "doxygen-rtf requires doxygen-rtf" "$LINENO" 5 ;; #( n|N|no|No|NO) DX_FLAG_rtf=0 ;; #( *) as_fn_error $? "invalid value '$enableval' given to doxygen-rtf" "$LINENO" 5 ;; esac else DX_FLAG_rtf=0 test "$DX_FLAG_doc" = "1" || DX_FLAG_rtf=0 fi if test "$DX_FLAG_rtf" = 1; then : fi if test "$DX_FLAG_rtf" = 1; then DX_ENV="$DX_ENV GENERATE_RTF='YES'" GENERATE_RTF=YES : else DX_ENV="$DX_ENV GENERATE_RTF='NO'" GENERATE_RTF=NO : fi # XML file generation: # Check whether --enable-doxygen-xml was given. if test "${enable_doxygen_xml+set}" = set; then : enableval=$enable_doxygen_xml; case "$enableval" in #( y|Y|yes|Yes|YES) DX_FLAG_xml=1 test "$DX_FLAG_doc" = "1" \ || as_fn_error $? "doxygen-xml requires doxygen-xml" "$LINENO" 5 ;; #( n|N|no|No|NO) DX_FLAG_xml=0 ;; #( *) as_fn_error $? "invalid value '$enableval' given to doxygen-xml" "$LINENO" 5 ;; esac else DX_FLAG_xml=0 test "$DX_FLAG_doc" = "1" || DX_FLAG_xml=0 fi if test "$DX_FLAG_xml" = 1; then : fi if test "$DX_FLAG_xml" = 1; then DX_ENV="$DX_ENV GENERATE_XML='YES'" GENERATE_XML=YES : else DX_ENV="$DX_ENV GENERATE_XML='NO'" GENERATE_XML=NO : fi # (Compressed) HTML help generation: # Check whether --enable-doxygen-chm was given. if test "${enable_doxygen_chm+set}" = set; then : enableval=$enable_doxygen_chm; case "$enableval" in #( y|Y|yes|Yes|YES) DX_FLAG_chm=1 test "$DX_FLAG_doc" = "1" \ || as_fn_error $? "doxygen-chm requires doxygen-chm" "$LINENO" 5 ;; #( n|N|no|No|NO) DX_FLAG_chm=0 ;; #( *) as_fn_error $? "invalid value '$enableval' given to doxygen-chm" "$LINENO" 5 ;; esac else DX_FLAG_chm=0 test "$DX_FLAG_doc" = "1" || DX_FLAG_chm=0 fi if test "$DX_FLAG_chm" = 1; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}hhc", so it can be a program name with args. set dummy ${ac_tool_prefix}hhc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_DX_HHC+:} false; then : $as_echo_n "(cached) " >&6 else case $DX_HHC in [\\/]* | ?:[\\/]*) ac_cv_path_DX_HHC="$DX_HHC" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_DX_HHC="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi DX_HHC=$ac_cv_path_DX_HHC if test -n "$DX_HHC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DX_HHC" >&5 $as_echo "$DX_HHC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_DX_HHC"; then ac_pt_DX_HHC=$DX_HHC # Extract the first word of "hhc", so it can be a program name with args. set dummy hhc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_DX_HHC+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_DX_HHC in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_DX_HHC="$ac_pt_DX_HHC" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_DX_HHC="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_DX_HHC=$ac_cv_path_ac_pt_DX_HHC if test -n "$ac_pt_DX_HHC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_DX_HHC" >&5 $as_echo "$ac_pt_DX_HHC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_DX_HHC" = x; then DX_HHC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DX_HHC=$ac_pt_DX_HHC fi else DX_HHC="$ac_cv_path_DX_HHC" fi if test "$DX_FLAG_chm$DX_HHC" = 1; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: hhc not found - will not generate doxygen compressed HTML help documentation" >&5 $as_echo "$as_me: WARNING: hhc not found - will not generate doxygen compressed HTML help documentation" >&2;} DX_FLAG_chm=0 fi : fi if test "$DX_FLAG_chm" = 1; then DX_ENV="$DX_ENV HHC_PATH='$DX_HHC'" HHC_PATH=$DX_HHC DX_ENV="$DX_ENV GENERATE_HTML='YES'" GENERATE_HTML=YES DX_ENV="$DX_ENV GENERATE_HTMLHELP='YES'" GENERATE_HTMLHELP=YES : else DX_ENV="$DX_ENV GENERATE_HTMLHELP='NO'" GENERATE_HTMLHELP=NO : fi # Seperate CHI file generation. # Check whether --enable-doxygen-chi was given. if test "${enable_doxygen_chi+set}" = set; then : enableval=$enable_doxygen_chi; case "$enableval" in #( y|Y|yes|Yes|YES) DX_FLAG_chi=1 test "$DX_FLAG_chm" = "1" \ || as_fn_error $? "doxygen-chi requires doxygen-chi" "$LINENO" 5 ;; #( n|N|no|No|NO) DX_FLAG_chi=0 ;; #( *) as_fn_error $? "invalid value '$enableval' given to doxygen-chi" "$LINENO" 5 ;; esac else DX_FLAG_chi=0 test "$DX_FLAG_chm" = "1" || DX_FLAG_chi=0 fi if test "$DX_FLAG_chi" = 1; then : fi if test "$DX_FLAG_chi" = 1; then DX_ENV="$DX_ENV GENERATE_CHI='YES'" GENERATE_CHI=YES : else DX_ENV="$DX_ENV GENERATE_CHI='NO'" GENERATE_CHI=NO : fi # Plain HTML pages generation: # Check whether --enable-doxygen-html was given. if test "${enable_doxygen_html+set}" = set; then : enableval=$enable_doxygen_html; case "$enableval" in #( y|Y|yes|Yes|YES) DX_FLAG_html=1 test "$DX_FLAG_doc" = "1" \ || as_fn_error $? "doxygen-html requires doxygen-html" "$LINENO" 5 test "$DX_FLAG_chm" = "0" \ || as_fn_error $? "doxygen-html contradicts doxygen-html" "$LINENO" 5 ;; #( n|N|no|No|NO) DX_FLAG_html=0 ;; #( *) as_fn_error $? "invalid value '$enableval' given to doxygen-html" "$LINENO" 5 ;; esac else DX_FLAG_html=1 test "$DX_FLAG_doc" = "1" || DX_FLAG_html=0 test "$DX_FLAG_chm" = "0" || DX_FLAG_html=0 fi if test "$DX_FLAG_html" = 1; then : fi if test "$DX_FLAG_html" = 1; then DX_ENV="$DX_ENV GENERATE_HTML='YES'" GENERATE_HTML=YES : else test "$DX_FLAG_chm" = 1 || DX_ENV="$DX_ENV GENERATE_HTML='NO'" GENERATE_HTML=NO : fi # PostScript file generation: # Check whether --enable-doxygen-ps was given. if test "${enable_doxygen_ps+set}" = set; then : enableval=$enable_doxygen_ps; case "$enableval" in #( y|Y|yes|Yes|YES) DX_FLAG_ps=1 test "$DX_FLAG_doc" = "1" \ || as_fn_error $? "doxygen-ps requires doxygen-ps" "$LINENO" 5 ;; #( n|N|no|No|NO) DX_FLAG_ps=0 ;; #( *) as_fn_error $? "invalid value '$enableval' given to doxygen-ps" "$LINENO" 5 ;; esac else DX_FLAG_ps=0 test "$DX_FLAG_doc" = "1" || DX_FLAG_ps=0 fi if test "$DX_FLAG_ps" = 1; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}latex", so it can be a program name with args. set dummy ${ac_tool_prefix}latex; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_DX_LATEX+:} false; then : $as_echo_n "(cached) " >&6 else case $DX_LATEX in [\\/]* | ?:[\\/]*) ac_cv_path_DX_LATEX="$DX_LATEX" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_DX_LATEX="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi DX_LATEX=$ac_cv_path_DX_LATEX if test -n "$DX_LATEX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DX_LATEX" >&5 $as_echo "$DX_LATEX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_DX_LATEX"; then ac_pt_DX_LATEX=$DX_LATEX # Extract the first word of "latex", so it can be a program name with args. set dummy latex; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_DX_LATEX+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_DX_LATEX in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_DX_LATEX="$ac_pt_DX_LATEX" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_DX_LATEX="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_DX_LATEX=$ac_cv_path_ac_pt_DX_LATEX if test -n "$ac_pt_DX_LATEX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_DX_LATEX" >&5 $as_echo "$ac_pt_DX_LATEX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_DX_LATEX" = x; then DX_LATEX="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DX_LATEX=$ac_pt_DX_LATEX fi else DX_LATEX="$ac_cv_path_DX_LATEX" fi if test "$DX_FLAG_ps$DX_LATEX" = 1; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: latex not found - will not generate doxygen PostScript documentation" >&5 $as_echo "$as_me: WARNING: latex not found - will not generate doxygen PostScript documentation" >&2;} DX_FLAG_ps=0 fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}makeindex", so it can be a program name with args. set dummy ${ac_tool_prefix}makeindex; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_DX_MAKEINDEX+:} false; then : $as_echo_n "(cached) " >&6 else case $DX_MAKEINDEX in [\\/]* | ?:[\\/]*) ac_cv_path_DX_MAKEINDEX="$DX_MAKEINDEX" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_DX_MAKEINDEX="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi DX_MAKEINDEX=$ac_cv_path_DX_MAKEINDEX if test -n "$DX_MAKEINDEX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DX_MAKEINDEX" >&5 $as_echo "$DX_MAKEINDEX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_DX_MAKEINDEX"; then ac_pt_DX_MAKEINDEX=$DX_MAKEINDEX # Extract the first word of "makeindex", so it can be a program name with args. set dummy makeindex; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_DX_MAKEINDEX+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_DX_MAKEINDEX in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_DX_MAKEINDEX="$ac_pt_DX_MAKEINDEX" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_DX_MAKEINDEX="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_DX_MAKEINDEX=$ac_cv_path_ac_pt_DX_MAKEINDEX if test -n "$ac_pt_DX_MAKEINDEX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_DX_MAKEINDEX" >&5 $as_echo "$ac_pt_DX_MAKEINDEX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_DX_MAKEINDEX" = x; then DX_MAKEINDEX="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DX_MAKEINDEX=$ac_pt_DX_MAKEINDEX fi else DX_MAKEINDEX="$ac_cv_path_DX_MAKEINDEX" fi if test "$DX_FLAG_ps$DX_MAKEINDEX" = 1; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: makeindex not found - will not generate doxygen PostScript documentation" >&5 $as_echo "$as_me: WARNING: makeindex not found - will not generate doxygen PostScript documentation" >&2;} DX_FLAG_ps=0 fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dvips", so it can be a program name with args. set dummy ${ac_tool_prefix}dvips; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_DX_DVIPS+:} false; then : $as_echo_n "(cached) " >&6 else case $DX_DVIPS in [\\/]* | ?:[\\/]*) ac_cv_path_DX_DVIPS="$DX_DVIPS" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_DX_DVIPS="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi DX_DVIPS=$ac_cv_path_DX_DVIPS if test -n "$DX_DVIPS"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DX_DVIPS" >&5 $as_echo "$DX_DVIPS" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_DX_DVIPS"; then ac_pt_DX_DVIPS=$DX_DVIPS # Extract the first word of "dvips", so it can be a program name with args. set dummy dvips; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_DX_DVIPS+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_DX_DVIPS in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_DX_DVIPS="$ac_pt_DX_DVIPS" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_DX_DVIPS="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_DX_DVIPS=$ac_cv_path_ac_pt_DX_DVIPS if test -n "$ac_pt_DX_DVIPS"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_DX_DVIPS" >&5 $as_echo "$ac_pt_DX_DVIPS" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_DX_DVIPS" = x; then DX_DVIPS="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DX_DVIPS=$ac_pt_DX_DVIPS fi else DX_DVIPS="$ac_cv_path_DX_DVIPS" fi if test "$DX_FLAG_ps$DX_DVIPS" = 1; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: dvips not found - will not generate doxygen PostScript documentation" >&5 $as_echo "$as_me: WARNING: dvips not found - will not generate doxygen PostScript documentation" >&2;} DX_FLAG_ps=0 fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}egrep", so it can be a program name with args. set dummy ${ac_tool_prefix}egrep; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_DX_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else case $DX_EGREP in [\\/]* | ?:[\\/]*) ac_cv_path_DX_EGREP="$DX_EGREP" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_DX_EGREP="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi DX_EGREP=$ac_cv_path_DX_EGREP if test -n "$DX_EGREP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DX_EGREP" >&5 $as_echo "$DX_EGREP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_DX_EGREP"; then ac_pt_DX_EGREP=$DX_EGREP # Extract the first word of "egrep", so it can be a program name with args. set dummy egrep; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_DX_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_DX_EGREP in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_DX_EGREP="$ac_pt_DX_EGREP" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_DX_EGREP="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_DX_EGREP=$ac_cv_path_ac_pt_DX_EGREP if test -n "$ac_pt_DX_EGREP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_DX_EGREP" >&5 $as_echo "$ac_pt_DX_EGREP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_DX_EGREP" = x; then DX_EGREP="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DX_EGREP=$ac_pt_DX_EGREP fi else DX_EGREP="$ac_cv_path_DX_EGREP" fi if test "$DX_FLAG_ps$DX_EGREP" = 1; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: egrep not found - will not generate doxygen PostScript documentation" >&5 $as_echo "$as_me: WARNING: egrep not found - will not generate doxygen PostScript documentation" >&2;} DX_FLAG_ps=0 fi : fi if test "$DX_FLAG_ps" = 1; then : else : fi # PDF file generation: # Check whether --enable-doxygen-pdf was given. if test "${enable_doxygen_pdf+set}" = set; then : enableval=$enable_doxygen_pdf; case "$enableval" in #( y|Y|yes|Yes|YES) DX_FLAG_pdf=1 test "$DX_FLAG_doc" = "1" \ || as_fn_error $? "doxygen-pdf requires doxygen-pdf" "$LINENO" 5 ;; #( n|N|no|No|NO) DX_FLAG_pdf=0 ;; #( *) as_fn_error $? "invalid value '$enableval' given to doxygen-pdf" "$LINENO" 5 ;; esac else DX_FLAG_pdf=0 test "$DX_FLAG_doc" = "1" || DX_FLAG_pdf=0 fi if test "$DX_FLAG_pdf" = 1; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pdflatex", so it can be a program name with args. set dummy ${ac_tool_prefix}pdflatex; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_DX_PDFLATEX+:} false; then : $as_echo_n "(cached) " >&6 else case $DX_PDFLATEX in [\\/]* | ?:[\\/]*) ac_cv_path_DX_PDFLATEX="$DX_PDFLATEX" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_DX_PDFLATEX="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi DX_PDFLATEX=$ac_cv_path_DX_PDFLATEX if test -n "$DX_PDFLATEX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DX_PDFLATEX" >&5 $as_echo "$DX_PDFLATEX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_DX_PDFLATEX"; then ac_pt_DX_PDFLATEX=$DX_PDFLATEX # Extract the first word of "pdflatex", so it can be a program name with args. set dummy pdflatex; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_DX_PDFLATEX+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_DX_PDFLATEX in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_DX_PDFLATEX="$ac_pt_DX_PDFLATEX" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_DX_PDFLATEX="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_DX_PDFLATEX=$ac_cv_path_ac_pt_DX_PDFLATEX if test -n "$ac_pt_DX_PDFLATEX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_DX_PDFLATEX" >&5 $as_echo "$ac_pt_DX_PDFLATEX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_DX_PDFLATEX" = x; then DX_PDFLATEX="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DX_PDFLATEX=$ac_pt_DX_PDFLATEX fi else DX_PDFLATEX="$ac_cv_path_DX_PDFLATEX" fi if test "$DX_FLAG_pdf$DX_PDFLATEX" = 1; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: pdflatex not found - will not generate doxygen PDF documentation" >&5 $as_echo "$as_me: WARNING: pdflatex not found - will not generate doxygen PDF documentation" >&2;} DX_FLAG_pdf=0 fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}makeindex", so it can be a program name with args. set dummy ${ac_tool_prefix}makeindex; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_DX_MAKEINDEX+:} false; then : $as_echo_n "(cached) " >&6 else case $DX_MAKEINDEX in [\\/]* | ?:[\\/]*) ac_cv_path_DX_MAKEINDEX="$DX_MAKEINDEX" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_DX_MAKEINDEX="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi DX_MAKEINDEX=$ac_cv_path_DX_MAKEINDEX if test -n "$DX_MAKEINDEX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DX_MAKEINDEX" >&5 $as_echo "$DX_MAKEINDEX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_DX_MAKEINDEX"; then ac_pt_DX_MAKEINDEX=$DX_MAKEINDEX # Extract the first word of "makeindex", so it can be a program name with args. set dummy makeindex; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_DX_MAKEINDEX+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_DX_MAKEINDEX in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_DX_MAKEINDEX="$ac_pt_DX_MAKEINDEX" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_DX_MAKEINDEX="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_DX_MAKEINDEX=$ac_cv_path_ac_pt_DX_MAKEINDEX if test -n "$ac_pt_DX_MAKEINDEX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_DX_MAKEINDEX" >&5 $as_echo "$ac_pt_DX_MAKEINDEX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_DX_MAKEINDEX" = x; then DX_MAKEINDEX="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DX_MAKEINDEX=$ac_pt_DX_MAKEINDEX fi else DX_MAKEINDEX="$ac_cv_path_DX_MAKEINDEX" fi if test "$DX_FLAG_pdf$DX_MAKEINDEX" = 1; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: makeindex not found - will not generate doxygen PDF documentation" >&5 $as_echo "$as_me: WARNING: makeindex not found - will not generate doxygen PDF documentation" >&2;} DX_FLAG_pdf=0 fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}egrep", so it can be a program name with args. set dummy ${ac_tool_prefix}egrep; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_DX_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else case $DX_EGREP in [\\/]* | ?:[\\/]*) ac_cv_path_DX_EGREP="$DX_EGREP" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_DX_EGREP="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi DX_EGREP=$ac_cv_path_DX_EGREP if test -n "$DX_EGREP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DX_EGREP" >&5 $as_echo "$DX_EGREP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_DX_EGREP"; then ac_pt_DX_EGREP=$DX_EGREP # Extract the first word of "egrep", so it can be a program name with args. set dummy egrep; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_DX_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_DX_EGREP in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_DX_EGREP="$ac_pt_DX_EGREP" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_DX_EGREP="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_DX_EGREP=$ac_cv_path_ac_pt_DX_EGREP if test -n "$ac_pt_DX_EGREP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_DX_EGREP" >&5 $as_echo "$ac_pt_DX_EGREP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_DX_EGREP" = x; then DX_EGREP="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DX_EGREP=$ac_pt_DX_EGREP fi else DX_EGREP="$ac_cv_path_DX_EGREP" fi if test "$DX_FLAG_pdf$DX_EGREP" = 1; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: egrep not found - will not generate doxygen PDF documentation" >&5 $as_echo "$as_me: WARNING: egrep not found - will not generate doxygen PDF documentation" >&2;} DX_FLAG_pdf=0 fi : fi if test "$DX_FLAG_pdf" = 1; then : else : fi # LaTeX generation for PS and/or PDF: if test "$DX_FLAG_ps" = 1 || test "$DX_FLAG_pdf" = 1; then DX_ENV="$DX_ENV GENERATE_LATEX='YES'" GENERATE_LATEX=YES else DX_ENV="$DX_ENV GENERATE_LATEX='NO'" GENERATE_LATEX=NO fi # Paper size for PS and/or PDF: case "$DOXYGEN_PAPER_SIZE" in #( "") DOXYGEN_PAPER_SIZE="" ;; #( a4wide|a4|letter|legal|executive) DX_ENV="$DX_ENV PAPER_SIZE='$DOXYGEN_PAPER_SIZE'" PAPER_SIZE=$DOXYGEN_PAPER_SIZE ;; #( *) as_fn_error $? "unknown DOXYGEN_PAPER_SIZE='$DOXYGEN_PAPER_SIZE'" "$LINENO" 5 ;; esac # Rules: if test $DX_FLAG_html -eq 1; then : DX_SNIPPET_html="## ------------------------------- ## ## Rules specific for HTML output. ## ## ------------------------------- ## DX_CLEAN_HTML = \$(DX_DOCDIR)/html\\ \$(DX_DOCDIR)/html " else DX_SNIPPET_html="" fi if test $DX_FLAG_chi -eq 1; then : DX_SNIPPET_chi=" DX_CLEAN_CHI = \$(DX_DOCDIR)/\$(PACKAGE).chi\\ \$(DX_DOCDIR)/\$(PACKAGE).chi" else DX_SNIPPET_chi="" fi if test $DX_FLAG_chm -eq 1; then : DX_SNIPPET_chm="## ------------------------------ ## ## Rules specific for CHM output. ## ## ------------------------------ ## DX_CLEAN_CHM = \$(DX_DOCDIR)/chm\\ \$(DX_DOCDIR)/chm\ ${DX_SNIPPET_chi} " else DX_SNIPPET_chm="" fi if test $DX_FLAG_man -eq 1; then : DX_SNIPPET_man="## ------------------------------ ## ## Rules specific for MAN output. ## ## ------------------------------ ## DX_CLEAN_MAN = \$(DX_DOCDIR)/man\\ \$(DX_DOCDIR)/man " else DX_SNIPPET_man="" fi if test $DX_FLAG_rtf -eq 1; then : DX_SNIPPET_rtf="## ------------------------------ ## ## Rules specific for RTF output. ## ## ------------------------------ ## DX_CLEAN_RTF = \$(DX_DOCDIR)/rtf\\ \$(DX_DOCDIR)/rtf " else DX_SNIPPET_rtf="" fi if test $DX_FLAG_xml -eq 1; then : DX_SNIPPET_xml="## ------------------------------ ## ## Rules specific for XML output. ## ## ------------------------------ ## DX_CLEAN_XML = \$(DX_DOCDIR)/xml\\ \$(DX_DOCDIR)/xml " else DX_SNIPPET_xml="" fi if test $DX_FLAG_ps -eq 1; then : DX_SNIPPET_ps="## ----------------------------- ## ## Rules specific for PS output. ## ## ----------------------------- ## DX_CLEAN_PS = \$(DX_DOCDIR)/\$(PACKAGE).ps\\ \$(DX_DOCDIR)/\$(PACKAGE).ps DX_PS_GOAL = doxygen-ps doxygen-ps: \$(DX_CLEAN_PS) \$(DX_DOCDIR)/\$(PACKAGE).ps: \$(DX_DOCDIR)/\$(PACKAGE).tag \$(DX_V_LATEX)cd \$(DX_DOCDIR)/latex; \\ rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \\ \$(DX_LATEX) refman.tex; \\ \$(DX_MAKEINDEX) refman.idx; \\ \$(DX_LATEX) refman.tex; \\ countdown=5; \\ while \$(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \\ refman.log > /dev/null 2>&1 \\ && test \$\$countdown -gt 0; do \\ \$(DX_LATEX) refman.tex; \\ countdown=\`expr \$\$countdown - 1\`; \\ done; \\ \$(DX_DVIPS) -o ../\$(PACKAGE).ps refman.dvi " else DX_SNIPPET_ps="" fi if test $DX_FLAG_pdf -eq 1; then : DX_SNIPPET_pdf="## ------------------------------ ## ## Rules specific for PDF output. ## ## ------------------------------ ## DX_CLEAN_PDF = \$(DX_DOCDIR)/\$(PACKAGE).pdf\\ \$(DX_DOCDIR)/\$(PACKAGE).pdf DX_PDF_GOAL = doxygen-pdf doxygen-pdf: \$(DX_CLEAN_PDF) \$(DX_DOCDIR)/\$(PACKAGE).pdf: \$(DX_DOCDIR)/\$(PACKAGE).tag \$(DX_V_LATEX)cd \$(DX_DOCDIR)/latex; \\ rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \\ \$(DX_PDFLATEX) refman.tex; \\ \$(DX_MAKEINDEX) refman.idx; \\ \$(DX_PDFLATEX) refman.tex; \\ countdown=5; \\ while \$(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \\ refman.log > /dev/null 2>&1 \\ && test \$\$countdown -gt 0; do \\ \$(DX_PDFLATEX) refman.tex; \\ countdown=\`expr \$\$countdown - 1\`; \\ done; \\ mv refman.pdf ../\$(PACKAGE).pdf " else DX_SNIPPET_pdf="" fi if test $DX_FLAG_ps -eq 1 -o $DX_FLAG_pdf -eq 1; then : DX_SNIPPET_latex="## ------------------------------------------------- ## ## Rules specific for LaTeX (shared for PS and PDF). ## ## ------------------------------------------------- ## DX_V_LATEX = \$(_DX_v_LATEX_\$(V)) _DX_v_LATEX_ = \$(_DX_v_LATEX_\$(AM_DEFAULT_VERBOSITY)) _DX_v_LATEX_0 = @echo \" LATEX \" \$@; DX_CLEAN_LATEX = \$(DX_DOCDIR)/latex\\ \$(DX_DOCDIR)/latex " else DX_SNIPPET_latex="" fi if test $DX_FLAG_doc -eq 1; then : DX_SNIPPET_doc="## --------------------------------- ## ## Format-independent Doxygen rules. ## ## --------------------------------- ## ${DX_SNIPPET_html}\ ${DX_SNIPPET_chm}\ ${DX_SNIPPET_man}\ ${DX_SNIPPET_rtf}\ ${DX_SNIPPET_xml}\ ${DX_SNIPPET_ps}\ ${DX_SNIPPET_pdf}\ ${DX_SNIPPET_latex}\ DX_V_DXGEN = \$(_DX_v_DXGEN_\$(V)) _DX_v_DXGEN_ = \$(_DX_v_DXGEN_\$(AM_DEFAULT_VERBOSITY)) _DX_v_DXGEN_0 = @echo \" DXGEN \" \$<; .PHONY: doxygen-run doxygen-doc \$(DX_PS_GOAL) \$(DX_PDF_GOAL) .INTERMEDIATE: doxygen-run \$(DX_PS_GOAL) \$(DX_PDF_GOAL) doxygen-run: \$(DX_DOCDIR)/\$(PACKAGE).tag doxygen-doc: doxygen-run \$(DX_PS_GOAL) \$(DX_PDF_GOAL) \$(DX_DOCDIR)/\$(PACKAGE).tag: \$(DX_CONFIG) \$(pkginclude_HEADERS) \$(A""M_V_at)rm -rf \$(DX_DOCDIR) \$(DX_V_DXGEN)\$(DX_ENV) DOCDIR=\$(DX_DOCDIR) \$(DX_DOXYGEN) \$(DX_CONFIG) \$(A""M_V_at)echo Timestamp >\$@ DX_CLEANFILES = \\ \$(DX_DOCDIR)/doxygen_sqlite3.db \\ \$(DX_DOCDIR)/\$(PACKAGE).tag \\ -r \\ \$(DX_CLEAN_HTML) \\ \$(DX_CLEAN_CHM) \\ \$(DX_CLEAN_CHI) \\ \$(DX_CLEAN_MAN) \\ \$(DX_CLEAN_RTF) \\ \$(DX_CLEAN_XML) \\ \$(DX_CLEAN_PS) \\ \$(DX_CLEAN_PDF) \\ \$(DX_CLEAN_LATEX)" else DX_SNIPPET_doc="" fi DX_RULES="${DX_SNIPPET_doc}" #For debugging: #echo DX_FLAG_doc=$DX_FLAG_doc #echo DX_FLAG_dot=$DX_FLAG_dot #echo DX_FLAG_man=$DX_FLAG_man #echo DX_FLAG_html=$DX_FLAG_html #echo DX_FLAG_chm=$DX_FLAG_chm #echo DX_FLAG_chi=$DX_FLAG_chi #echo DX_FLAG_rtf=$DX_FLAG_rtf #echo DX_FLAG_xml=$DX_FLAG_xml #echo DX_FLAG_pdf=$DX_FLAG_pdf #echo DX_FLAG_ps=$DX_FLAG_ps #echo DX_ENV=$DX_ENV cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs { $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 $as_echo_n "checking that generated files are newer than configure... " >&6; } if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 $as_echo "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${ENABLE_OPENMPT123_TRUE}" && test -z "${ENABLE_OPENMPT123_FALSE}"; then as_fn_error $? "conditional \"ENABLE_OPENMPT123\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${ENABLE_EXAMPLES_TRUE}" && test -z "${ENABLE_EXAMPLES_FALSE}"; then as_fn_error $? "conditional \"ENABLE_EXAMPLES\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${ENABLE_TESTS_TRUE}" && test -z "${ENABLE_TESTS_FALSE}"; then as_fn_error $? "conditional \"ENABLE_TESTS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_PORTAUDIO_TRUE}" && test -z "${HAVE_PORTAUDIO_FALSE}"; then as_fn_error $? "conditional \"HAVE_PORTAUDIO\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_PORTAUDIOCPP_TRUE}" && test -z "${HAVE_PORTAUDIOCPP_FALSE}"; then as_fn_error $? "conditional \"HAVE_PORTAUDIOCPP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${ENABLE_LIBOPENMPT_MODPLUG_TRUE}" && test -z "${ENABLE_LIBOPENMPT_MODPLUG_FALSE}"; then as_fn_error $? "conditional \"ENABLE_LIBOPENMPT_MODPLUG\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${ENABLE_LIBMODPLUG_TRUE}" && test -z "${ENABLE_LIBMODPLUG_FALSE}"; then as_fn_error $? "conditional \"ENABLE_LIBMODPLUG\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by libopenmpt $as_me 0.3.6+release.autotools, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to . libopenmpt home page: ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ libopenmpt config.status 0.3.6+release.autotools configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`' SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`' nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`' objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`' configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`' hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`' predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`' postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } # Quote evaled strings. for var in SHELL \ ECHO \ PATH_SEPARATOR \ SED \ GREP \ EGREP \ FGREP \ LD \ NM \ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ OBJDUMP \ deplibs_check_method \ file_magic_cmd \ file_magic_glob \ want_nocaseglob \ DLLTOOL \ sharedlib_from_linklib_cmd \ AR \ AR_FLAGS \ archiver_list_spec \ STRIP \ RANLIB \ CC \ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_import \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ lt_cv_nm_interface \ nm_file_list_spec \ lt_cv_truncate_bin \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_pic \ lt_prog_compiler_wl \ lt_prog_compiler_static \ lt_cv_prog_compiler_c_o \ need_locks \ MANIFEST_TOOL \ DSYMUTIL \ NMEDIT \ LIPO \ OTOOL \ OTOOL64 \ shrext_cmds \ export_dynamic_flag_spec \ whole_archive_flag_spec \ compiler_needs_object \ with_gnu_ld \ allow_undefined_flag \ no_undefined_flag \ hardcode_libdir_flag_spec \ hardcode_libdir_separator \ exclude_expsyms \ include_expsyms \ file_list_spec \ variables_saved_for_relink \ libname_spec \ library_names_spec \ soname_spec \ install_override_mode \ finish_eval \ old_striplib \ striplib \ compiler_lib_search_dirs \ predep_objects \ postdep_objects \ predeps \ postdeps \ compiler_lib_search_path \ LD_CXX \ reload_flag_CXX \ compiler_CXX \ lt_prog_compiler_no_builtin_flag_CXX \ lt_prog_compiler_pic_CXX \ lt_prog_compiler_wl_CXX \ lt_prog_compiler_static_CXX \ lt_cv_prog_compiler_c_o_CXX \ export_dynamic_flag_spec_CXX \ whole_archive_flag_spec_CXX \ compiler_needs_object_CXX \ with_gnu_ld_CXX \ allow_undefined_flag_CXX \ no_undefined_flag_CXX \ hardcode_libdir_flag_spec_CXX \ hardcode_libdir_separator_CXX \ exclude_expsyms_CXX \ include_expsyms_CXX \ file_list_spec_CXX \ compiler_lib_search_dirs_CXX \ predep_objects_CXX \ postdep_objects_CXX \ predeps_CXX \ postdeps_CXX \ compiler_lib_search_path_CXX; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in reload_cmds \ old_postinstall_cmds \ old_postuninstall_cmds \ old_archive_cmds \ extract_expsyms_cmds \ old_archive_from_new_cmds \ old_archive_from_expsyms_cmds \ archive_cmds \ archive_expsym_cmds \ module_cmds \ module_expsym_cmds \ export_symbols_cmds \ prelink_cmds \ postlink_cmds \ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ configure_time_dlsearch_path \ configure_time_lt_sys_library_path \ reload_cmds_CXX \ old_archive_cmds_CXX \ old_archive_from_new_cmds_CXX \ old_archive_from_expsyms_cmds_CXX \ archive_cmds_CXX \ archive_expsym_cmds_CXX \ module_cmds_CXX \ module_expsym_cmds_CXX \ export_symbols_cmds_CXX \ prelink_cmds_CXX \ postlink_cmds_CXX; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done ac_aux_dir='$ac_aux_dir' # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi PACKAGE='$PACKAGE' VERSION='$VERSION' RM='$RM' ofile='$ofile' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "libopenmpt/libopenmpt.pc") CONFIG_FILES="$CONFIG_FILES libopenmpt/libopenmpt.pc" ;; "libmodplug/libmodplug.pc") CONFIG_FILES="$CONFIG_FILES libmodplug/libmodplug.pc" ;; "Doxyfile") CONFIG_FILES="$CONFIG_FILES Doxyfile" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; "libtool":C) # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi cfgfile=${ofile}T trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. # Written by Gordon Matzigkeit, 1996 # Copyright (C) 2014 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program or library that is built # using GNU Libtool, you may include this file under the same # distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # The names of the tagged configurations supported by this script. available_tags='CXX ' # Configured defaults for sys_lib_dlsearch_path munging. : \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} # ### BEGIN LIBTOOL CONFIG # Which release of libtool.m4 was used? macro_version=$macro_version macro_revision=$macro_revision # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # What type of objects to build. pic_mode=$pic_mode # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # Shared archive member basename,for filename based shared library versioning on AIX. shared_archive_member_spec=$shared_archive_member_spec # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # An echo program that protects backslashes. ECHO=$lt_ECHO # The PATH separator for the build system. PATH_SEPARATOR=$lt_PATH_SEPARATOR # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # A sed program that does not truncate output. SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="\$SED -e 1s/^X//" # A grep program that handles long lines. GREP=$lt_GREP # An ERE matcher. EGREP=$lt_EGREP # A literal string matcher. FGREP=$lt_FGREP # A BSD- or MS-compatible name lister. NM=$lt_NM # Whether we need soft or hard links. LN_S=$lt_LN_S # What is the maximum length of a command? max_cmd_len=$max_cmd_len # Object file suffix (normally "o"). objext=$ac_objext # Executable file suffix (normally ""). exeext=$exeext # whether the shell understands "unset". lt_unset=$lt_unset # turn spaces into newlines. SP2NL=$lt_lt_SP2NL # turn newlines into spaces. NL2SP=$lt_lt_NL2SP # convert \$build file names to \$host format. to_host_file_cmd=$lt_cv_to_host_file_cmd # convert \$build files to toolchain format. to_tool_file_cmd=$lt_cv_to_tool_file_cmd # An object symbol dumper. OBJDUMP=$lt_OBJDUMP # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method = "file_magic". file_magic_cmd=$lt_file_magic_cmd # How to find potential files when deplibs_check_method = "file_magic". file_magic_glob=$lt_file_magic_glob # Find potential files using nocaseglob when deplibs_check_method = "file_magic". want_nocaseglob=$lt_want_nocaseglob # DLL creation program. DLLTOOL=$lt_DLLTOOL # Command to associate shared and link libraries. sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd # The archiver. AR=$lt_AR # Flags to create an archive. AR_FLAGS=$lt_AR_FLAGS # How to feed a file listing to the archiver. archiver_list_spec=$lt_archiver_list_spec # A symbol stripping program. STRIP=$lt_STRIP # Commands used to install an old-style archive. RANLIB=$lt_RANLIB old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Whether to use a lock for old archive extraction. lock_old_archive_extraction=$lock_old_archive_extraction # A C compiler. LTCC=$lt_CC # LTCC compiler flags. LTCFLAGS=$lt_CFLAGS # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration. global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm into a list of symbols to manually relocate. global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import # Transform the output of nm in a C name address pair. global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix # The name lister interface. nm_interface=$lt_lt_cv_nm_interface # Specify filename containing input files for \$NM. nm_file_list_spec=$lt_nm_file_list_spec # The root where to search for dependent libraries,and where our libraries should be installed. lt_sysroot=$lt_sysroot # Command to truncate a binary pipe. lt_truncate_bin=$lt_lt_cv_truncate_bin # The name of the directory that contains temporary libtool files. objdir=$objdir # Used to examine libraries when file_magic_cmd begins with "file". MAGIC_CMD=$MAGIC_CMD # Must we lock files when doing compilation? need_locks=$lt_need_locks # Manifest tool. MANIFEST_TOOL=$lt_MANIFEST_TOOL # Tool to manipulate archived DWARF debug symbol files on Mac OS X. DSYMUTIL=$lt_DSYMUTIL # Tool to change global to local symbols on Mac OS X. NMEDIT=$lt_NMEDIT # Tool to manipulate fat objects and archives on Mac OS X. LIPO=$lt_LIPO # ldd/readelf like tool for Mach-O binaries on Mac OS X. OTOOL=$lt_OTOOL # ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. OTOOL64=$lt_OTOOL64 # Old archive suffix (normally "a"). libext=$libext # Shared library suffix (normally ".so"). shrext_cmds=$lt_shrext_cmds # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Variables whose values should be saved in libtool wrapper scripts and # restored at link time. variables_saved_for_relink=$lt_variables_saved_for_relink # Do we need the "lib" prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Library versioning type. version_type=$version_type # Shared library runtime path variable. runpath_var=$runpath_var # Shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Permission mode override for installation of shared libraries. install_override_mode=$lt_install_override_mode # Command to use after installation of a shared archive. postinstall_cmds=$lt_postinstall_cmds # Command to use after uninstallation of a shared archive. postuninstall_cmds=$lt_postuninstall_cmds # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # As "finish_cmds", except a single script fragment to be evaled but # not shown. finish_eval=$lt_finish_eval # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Compile-time system search path for libraries. sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Detected run-time system search path for libraries. sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path # Explicit LT_SYS_LIBRARY_PATH set during ./configure time. configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # The linker used to build libraries. LD=$lt_LD # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds # A language specific compiler. CC=$lt_compiler # Is the compiler the GNU compiler? with_gcc=$GCC # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds archive_expsym_cmds=$lt_archive_expsym_cmds # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds module_expsym_cmds=$lt_module_expsym_cmds # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \$shlibpath_var if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms # Symbols that must always be exported. include_expsyms=$lt_include_expsyms # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds # Specify filename containing input files. file_list_spec=$lt_file_list_spec # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # The directories searched by this compiler when creating a shared library. compiler_lib_search_dirs=$lt_compiler_lib_search_dirs # Dependencies to place before and after the objects being linked to # create a shared library. predep_objects=$lt_predep_objects postdep_objects=$lt_postdep_objects predeps=$lt_predeps postdeps=$lt_postdeps # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path # ### END LIBTOOL CONFIG _LT_EOF cat <<'_LT_EOF' >> "$cfgfile" # ### BEGIN FUNCTIONS SHARED WITH CONFIGURE # func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x$2 in x) ;; *:) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" ;; x:*) eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" ;; *::*) eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" ;; *) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" ;; esac } # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in $*""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } # ### END FUNCTIONS SHARED WITH CONFIGURE _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac ltmain=$ac_aux_dir/ltmain.sh # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" cat <<_LT_EOF >> "$ofile" # ### BEGIN LIBTOOL TAG CONFIG: CXX # The linker used to build libraries. LD=$lt_LD_CXX # How to create reloadable object files. reload_flag=$lt_reload_flag_CXX reload_cmds=$lt_reload_cmds_CXX # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds_CXX # A language specific compiler. CC=$lt_compiler_CXX # Is the compiler the GNU compiler? with_gcc=$GCC_CXX # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic_CXX # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl_CXX # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static_CXX # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc_CXX # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object_CXX # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds_CXX archive_expsym_cmds=$lt_archive_expsym_cmds_CXX # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds_CXX module_expsym_cmds=$lt_module_expsym_cmds_CXX # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld_CXX # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag_CXX # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag_CXX # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct_CXX # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \$shlibpath_var if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute_CXX # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L_CXX # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic_CXX # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath_CXX # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs_CXX # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols_CXX # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds_CXX # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms_CXX # Symbols that must always be exported. include_expsyms=$lt_include_expsyms_CXX # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds_CXX # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds_CXX # Specify filename containing input files. file_list_spec=$lt_file_list_spec_CXX # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action_CXX # The directories searched by this compiler when creating a shared library. compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX # Dependencies to place before and after the objects being linked to # create a shared library. predep_objects=$lt_predep_objects_CXX postdep_objects=$lt_postdep_objects_CXX predeps=$lt_predeps_CXX postdeps=$lt_postdeps_CXX # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path_CXX # ### END LIBTOOL TAG CONFIG: CXX _LT_EOF ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi libopenmpt-0.3.6+release.autotools/build-aux/0000755000372100037210000000000013235362225016233 500000000000000libopenmpt-0.3.6+release.autotools/build-aux/install-sh0000755000372100037210000003546313235362221020166 00000000000000#!/bin/sh # install - install a program, script, or datafile scriptversion=2014-09-12.12; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. tab=' ' nl=' ' IFS=" $tab$nl" # Set DOITPROG to "echo" to test this script. doit=${DOITPROG-} doit_exec=${doit:-exec} # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false is_target_a_directory=possibly usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) is_target_a_directory=always dst_arg=$2 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac shift;; -T) is_target_a_directory=never;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done # We allow the use of options -d and -T together, by making -d # take the precedence; this is for compatibility with GNU install. if test -n "$dir_arg"; then if test -n "$dst_arg"; then echo "$0: target directory not allowed when installing a directory." >&2 exit 1 fi fi if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then if test $# -gt 1 || test "$is_target_a_directory" = always; then if test ! -d "$dst_arg"; then echo "$0: $dst_arg: Is not a directory." >&2 exit 1 fi fi fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test "$is_target_a_directory" = never; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else dstdir=`dirname "$dst"` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) # $RANDOM is not portable (e.g. dash); use it when possible to # lower collision chance tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 # As "mkdir -p" follows symlinks and we work in /tmp possibly; so # create the $tmpdir first (and fail if unsuccessful) to make sure # that nobody tries to guess the $tmpdir name. if (umask $mkdir_umask && $mkdirprog $mkdir_mode "$tmpdir" && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. test_tmpdir="$tmpdir/a" ls_ld_tmpdir=`ls -ld "$test_tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; [-=\(\)!]*) prefix='./';; *) prefix='';; esac oIFS=$IFS IFS=/ set -f set fnord $dstdir shift set +f IFS=$oIFS prefixes= for d do test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: libopenmpt-0.3.6+release.autotools/build-aux/ltmain.sh0000644000372100037210000117147413235362215020011 00000000000000#! /bin/sh ## DO NOT EDIT - This file generated from ./build-aux/ltmain.in ## by inline-source v2014-01-03.01 # libtool (GNU libtool) 2.4.6 # Provide generalized library-building support services. # Written by Gordon Matzigkeit , 1996 # Copyright (C) 1996-2015 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . PROGRAM=libtool PACKAGE=libtool VERSION="2.4.6 Debian-2.4.6-2" package_revision=2.4.6 ## ------ ## ## Usage. ## ## ------ ## # Run './libtool --help' for help with using this script from the # command line. ## ------------------------------- ## ## User overridable command paths. ## ## ------------------------------- ## # After configure completes, it has a better idea of some of the # shell tools we need than the defaults used by the functions shared # with bootstrap, so set those here where they can still be over- # ridden by the user, but otherwise take precedence. : ${AUTOCONF="autoconf"} : ${AUTOMAKE="automake"} ## -------------------------- ## ## Source external libraries. ## ## -------------------------- ## # Much of our low-level functionality needs to be sourced from external # libraries, which are installed to $pkgauxdir. # Set a version string for this script. scriptversion=2015-01-20.17; # UTC # General shell script boiler plate, and helper functions. # Written by Gary V. Vaughan, 2004 # Copyright (C) 2004-2015 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # As a special exception to the GNU General Public License, if you distribute # this file as part of a program or library that is built using GNU Libtool, # you may include this file under the same distribution terms that you use # for the rest of that program. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Please report bugs or propose patches to gary@gnu.org. ## ------ ## ## Usage. ## ## ------ ## # Evaluate this file near the top of your script to gain access to # the functions and variables defined here: # # . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh # # If you need to override any of the default environment variable # settings, do that before evaluating this file. ## -------------------- ## ## Shell normalisation. ## ## -------------------- ## # Some shells need a little help to be as Bourne compatible as possible. # Before doing anything else, make sure all that help has been provided! DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # NLS nuisances: We save the old values in case they are required later. _G_user_locale= _G_safe_locale= for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test set = \"\${$_G_var+set}\"; then save_$_G_var=\$$_G_var $_G_var=C export $_G_var _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\" _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\" fi" done # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Make sure IFS has a sensible default sp=' ' nl=' ' IFS="$sp $nl" # There are apparently some retarded systems that use ';' as a PATH separator! if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi ## ------------------------- ## ## Locate command utilities. ## ## ------------------------- ## # func_executable_p FILE # ---------------------- # Check that FILE is an executable regular file. func_executable_p () { test -f "$1" && test -x "$1" } # func_path_progs PROGS_LIST CHECK_FUNC [PATH] # -------------------------------------------- # Search for either a program that responds to --version with output # containing "GNU", or else returned by CHECK_FUNC otherwise, by # trying all the directories in PATH with each of the elements of # PROGS_LIST. # # CHECK_FUNC should accept the path to a candidate program, and # set $func_check_prog_result if it truncates its output less than # $_G_path_prog_max characters. func_path_progs () { _G_progs_list=$1 _G_check_func=$2 _G_PATH=${3-"$PATH"} _G_path_prog_max=0 _G_path_prog_found=false _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:} for _G_dir in $_G_PATH; do IFS=$_G_save_IFS test -z "$_G_dir" && _G_dir=. for _G_prog_name in $_G_progs_list; do for _exeext in '' .EXE; do _G_path_prog=$_G_dir/$_G_prog_name$_exeext func_executable_p "$_G_path_prog" || continue case `"$_G_path_prog" --version 2>&1` in *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;; *) $_G_check_func $_G_path_prog func_path_progs_result=$func_check_prog_result ;; esac $_G_path_prog_found && break 3 done done done IFS=$_G_save_IFS test -z "$func_path_progs_result" && { echo "no acceptable sed could be found in \$PATH" >&2 exit 1 } } # We want to be able to use the functions in this file before configure # has figured out where the best binaries are kept, which means we have # to search for them ourselves - except when the results are already set # where we skip the searches. # Unless the user overrides by setting SED, search the path for either GNU # sed, or the sed that truncates its output the least. test -z "$SED" && { _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for _G_i in 1 2 3 4 5 6 7; do _G_sed_script=$_G_sed_script$nl$_G_sed_script done echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed _G_sed_script= func_check_prog_sed () { _G_path_prog=$1 _G_count=0 printf 0123456789 >conftest.in while : do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo '' >> conftest.nl "$_G_path_prog" -f conftest.sed conftest.out 2>/dev/null || break diff conftest.out conftest.nl >/dev/null 2>&1 || break _G_count=`expr $_G_count + 1` if test "$_G_count" -gt "$_G_path_prog_max"; then # Best one so far, save it but keep looking for a better one func_check_prog_result=$_G_path_prog _G_path_prog_max=$_G_count fi # 10*(2^10) chars as input seems more than enough test 10 -lt "$_G_count" && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out } func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin rm -f conftest.sed SED=$func_path_progs_result } # Unless the user overrides by setting GREP, search the path for either GNU # grep, or the grep that truncates its output the least. test -z "$GREP" && { func_check_prog_grep () { _G_path_prog=$1 _G_count=0 _G_path_prog_max=0 printf 0123456789 >conftest.in while : do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo 'GREP' >> conftest.nl "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' conftest.out 2>/dev/null || break diff conftest.out conftest.nl >/dev/null 2>&1 || break _G_count=`expr $_G_count + 1` if test "$_G_count" -gt "$_G_path_prog_max"; then # Best one so far, save it but keep looking for a better one func_check_prog_result=$_G_path_prog _G_path_prog_max=$_G_count fi # 10*(2^10) chars as input seems more than enough test 10 -lt "$_G_count" && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out } func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin GREP=$func_path_progs_result } ## ------------------------------- ## ## User overridable command paths. ## ## ------------------------------- ## # All uppercase variable names are used for environment variables. These # variables can be overridden by the user before calling a script that # uses them if a suitable command of that name is not already available # in the command search PATH. : ${CP="cp -f"} : ${ECHO="printf %s\n"} : ${EGREP="$GREP -E"} : ${FGREP="$GREP -F"} : ${LN_S="ln -s"} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} ## -------------------- ## ## Useful sed snippets. ## ## -------------------- ## sed_dirname='s|/[^/]*$||' sed_basename='s|^.*/||' # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='s|\([`"$\\]\)|\\\1|g' # Same as above, but do not quote variable references. sed_double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution that turns a string into a regex matching for the # string literally. sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g' # Sed substitution that converts a w32 file name or path # that contains forward slashes, into one that contains # (escaped) backslashes. A very naive implementation. sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' # Re-'\' parameter expansions in output of sed_double_quote_subst that # were '\'-ed in input to the same. If an odd number of '\' preceded a # '$' in input to sed_double_quote_subst, that '$' was protected from # expansion. Since each input '\' is now two '\'s, look for any number # of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'. _G_bs='\\' _G_bs2='\\\\' _G_bs4='\\\\\\\\' _G_dollar='\$' sed_double_backslash="\ s/$_G_bs4/&\\ /g s/^$_G_bs2$_G_dollar/$_G_bs&/ s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g s/\n//g" ## ----------------- ## ## Global variables. ## ## ----------------- ## # Except for the global variables explicitly listed below, the following # functions in the '^func_' namespace, and the '^require_' namespace # variables initialised in the 'Resource management' section, sourcing # this file will not pollute your global namespace with anything # else. There's no portable way to scope variables in Bourne shell # though, so actually running these functions will sometimes place # results into a variable named after the function, and often use # temporary variables in the '^_G_' namespace. If you are careful to # avoid using those namespaces casually in your sourcing script, things # should continue to work as you expect. And, of course, you can freely # overwrite any of the functions or variables defined here before # calling anything to customize them. EXIT_SUCCESS=0 EXIT_FAILURE=1 EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. # Allow overriding, eg assuming that you follow the convention of # putting '$debug_cmd' at the start of all your functions, you can get # bash to show function call trace with: # # debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name debug_cmd=${debug_cmd-":"} exit_cmd=: # By convention, finish your script with: # # exit $exit_status # # so that you can set exit_status to non-zero if you want to indicate # something went wrong during execution without actually bailing out at # the point of failure. exit_status=$EXIT_SUCCESS # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. progpath=$0 # The name of this program. progname=`$ECHO "$progpath" |$SED "$sed_basename"` # Make sure we have an absolute progpath for reexecution: case $progpath in [\\/]*|[A-Za-z]:\\*) ;; *[\\/]*) progdir=`$ECHO "$progpath" |$SED "$sed_dirname"` progdir=`cd "$progdir" && pwd` progpath=$progdir/$progname ;; *) _G_IFS=$IFS IFS=${PATH_SEPARATOR-:} for progdir in $PATH; do IFS=$_G_IFS test -x "$progdir/$progname" && break done IFS=$_G_IFS test -n "$progdir" || progdir=`pwd` progpath=$progdir/$progname ;; esac ## ----------------- ## ## Standard options. ## ## ----------------- ## # The following options affect the operation of the functions defined # below, and should be set appropriately depending on run-time para- # meters passed on the command line. opt_dry_run=false opt_quiet=false opt_verbose=false # Categories 'all' and 'none' are always available. Append any others # you will pass as the first argument to func_warning from your own # code. warning_categories= # By default, display warnings according to 'opt_warning_types'. Set # 'warning_func' to ':' to elide all warnings, or func_fatal_error to # treat the next displayed warning as a fatal error. warning_func=func_warn_and_continue # Set to 'all' to display all warnings, 'none' to suppress all # warnings, or a space delimited list of some subset of # 'warning_categories' to display only the listed warnings. opt_warning_types=all ## -------------------- ## ## Resource management. ## ## -------------------- ## # This section contains definitions for functions that each ensure a # particular resource (a file, or a non-empty configuration variable for # example) is available, and if appropriate to extract default values # from pertinent package files. Call them using their associated # 'require_*' variable to ensure that they are executed, at most, once. # # It's entirely deliberate that calling these functions can set # variables that don't obey the namespace limitations obeyed by the rest # of this file, in order that that they be as useful as possible to # callers. # require_term_colors # ------------------- # Allow display of bold text on terminals that support it. require_term_colors=func_require_term_colors func_require_term_colors () { $debug_cmd test -t 1 && { # COLORTERM and USE_ANSI_COLORS environment variables take # precedence, because most terminfo databases neglect to describe # whether color sequences are supported. test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"} if test 1 = "$USE_ANSI_COLORS"; then # Standard ANSI escape sequences tc_reset='' tc_bold=''; tc_standout='' tc_red=''; tc_green='' tc_blue=''; tc_cyan='' else # Otherwise trust the terminfo database after all. test -n "`tput sgr0 2>/dev/null`" && { tc_reset=`tput sgr0` test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold` tc_standout=$tc_bold test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso` test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1` test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2` test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4` test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5` } fi } require_term_colors=: } ## ----------------- ## ## Function library. ## ## ----------------- ## # This section contains a variety of useful functions to call in your # scripts. Take note of the portable wrappers for features provided by # some modern shells, which will fall back to slower equivalents on # less featureful shells. # func_append VAR VALUE # --------------------- # Append VALUE onto the existing contents of VAR. # We should try to minimise forks, especially on Windows where they are # unreasonably slow, so skip the feature probes when bash or zsh are # being used: if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then : ${_G_HAVE_ARITH_OP="yes"} : ${_G_HAVE_XSI_OPS="yes"} # The += operator was introduced in bash 3.1 case $BASH_VERSION in [12].* | 3.0 | 3.0*) ;; *) : ${_G_HAVE_PLUSEQ_OP="yes"} ;; esac fi # _G_HAVE_PLUSEQ_OP # Can be empty, in which case the shell is probed, "yes" if += is # useable or anything else if it does not work. test -z "$_G_HAVE_PLUSEQ_OP" \ && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \ && _G_HAVE_PLUSEQ_OP=yes if test yes = "$_G_HAVE_PLUSEQ_OP" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_append () { $debug_cmd eval "$1+=\$2" }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_append () { $debug_cmd eval "$1=\$$1\$2" } fi # func_append_quoted VAR VALUE # ---------------------------- # Quote VALUE and append to the end of shell variable VAR, separated # by a space. if test yes = "$_G_HAVE_PLUSEQ_OP"; then eval 'func_append_quoted () { $debug_cmd func_quote_for_eval "$2" eval "$1+=\\ \$func_quote_for_eval_result" }' else func_append_quoted () { $debug_cmd func_quote_for_eval "$2" eval "$1=\$$1\\ \$func_quote_for_eval_result" } fi # func_append_uniq VAR VALUE # -------------------------- # Append unique VALUE onto the existing contents of VAR, assuming # entries are delimited by the first character of VALUE. For example: # # func_append_uniq options " --another-option option-argument" # # will only append to $options if " --another-option option-argument " # is not already present somewhere in $options already (note spaces at # each end implied by leading space in second argument). func_append_uniq () { $debug_cmd eval _G_current_value='`$ECHO $'$1'`' _G_delim=`expr "$2" : '\(.\)'` case $_G_delim$_G_current_value$_G_delim in *"$2$_G_delim"*) ;; *) func_append "$@" ;; esac } # func_arith TERM... # ------------------ # Set func_arith_result to the result of evaluating TERMs. test -z "$_G_HAVE_ARITH_OP" \ && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \ && _G_HAVE_ARITH_OP=yes if test yes = "$_G_HAVE_ARITH_OP"; then eval 'func_arith () { $debug_cmd func_arith_result=$(( $* )) }' else func_arith () { $debug_cmd func_arith_result=`expr "$@"` } fi # func_basename FILE # ------------------ # Set func_basename_result to FILE with everything up to and including # the last / stripped. if test yes = "$_G_HAVE_XSI_OPS"; then # If this shell supports suffix pattern removal, then use it to avoid # forking. Hide the definitions single quotes in case the shell chokes # on unsupported syntax... _b='func_basename_result=${1##*/}' _d='case $1 in */*) func_dirname_result=${1%/*}$2 ;; * ) func_dirname_result=$3 ;; esac' else # ...otherwise fall back to using sed. _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`' _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"` if test "X$func_dirname_result" = "X$1"; then func_dirname_result=$3 else func_append func_dirname_result "$2" fi' fi eval 'func_basename () { $debug_cmd '"$_b"' }' # func_dirname FILE APPEND NONDIR_REPLACEMENT # ------------------------------------------- # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. eval 'func_dirname () { $debug_cmd '"$_d"' }' # func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT # -------------------------------------------------------- # Perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # For efficiency, we do not delegate to the functions above but instead # duplicate the functionality here. eval 'func_dirname_and_basename () { $debug_cmd '"$_b"' '"$_d"' }' # func_echo ARG... # ---------------- # Echo program name prefixed message. func_echo () { $debug_cmd _G_message=$* func_echo_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_IFS $ECHO "$progname: $_G_line" done IFS=$func_echo_IFS } # func_echo_all ARG... # -------------------- # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } # func_echo_infix_1 INFIX ARG... # ------------------------------ # Echo program name, followed by INFIX on the first line, with any # additional lines not showing INFIX. func_echo_infix_1 () { $debug_cmd $require_term_colors _G_infix=$1; shift _G_indent=$_G_infix _G_prefix="$progname: $_G_infix: " _G_message=$* # Strip color escape sequences before counting printable length for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan" do test -n "$_G_tc" && { _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"` _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"` } done _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes func_echo_infix_1_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_infix_1_IFS $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2 _G_prefix=$_G_indent done IFS=$func_echo_infix_1_IFS } # func_error ARG... # ----------------- # Echo program name prefixed message to standard error. func_error () { $debug_cmd $require_term_colors func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2 } # func_fatal_error ARG... # ----------------------- # Echo program name prefixed message to standard error, and exit. func_fatal_error () { $debug_cmd func_error "$*" exit $EXIT_FAILURE } # func_grep EXPRESSION FILENAME # ----------------------------- # Check whether EXPRESSION matches any line of FILENAME, without output. func_grep () { $debug_cmd $GREP "$1" "$2" >/dev/null 2>&1 } # func_len STRING # --------------- # Set func_len_result to the length of STRING. STRING may not # start with a hyphen. test -z "$_G_HAVE_XSI_OPS" \ && (eval 'x=a/b/c; test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ && _G_HAVE_XSI_OPS=yes if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_len () { $debug_cmd func_len_result=${#1} }' else func_len () { $debug_cmd func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` } fi # func_mkdir_p DIRECTORY-PATH # --------------------------- # Make sure the entire path to DIRECTORY-PATH is available. func_mkdir_p () { $debug_cmd _G_directory_path=$1 _G_dir_list= if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then # Protect directory names starting with '-' case $_G_directory_path in -*) _G_directory_path=./$_G_directory_path ;; esac # While some portion of DIR does not yet exist... while test ! -d "$_G_directory_path"; do # ...make a list in topmost first order. Use a colon delimited # list incase some portion of path contains whitespace. _G_dir_list=$_G_directory_path:$_G_dir_list # If the last portion added has no slash in it, the list is done case $_G_directory_path in */*) ;; *) break ;; esac # ...otherwise throw away the child directory and loop _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"` done _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'` func_mkdir_p_IFS=$IFS; IFS=: for _G_dir in $_G_dir_list; do IFS=$func_mkdir_p_IFS # mkdir can fail with a 'File exist' error if two processes # try to create one of the directories concurrently. Don't # stop in that case! $MKDIR "$_G_dir" 2>/dev/null || : done IFS=$func_mkdir_p_IFS # Bail out if we (or some other process) failed to create a directory. test -d "$_G_directory_path" || \ func_fatal_error "Failed to create '$1'" fi } # func_mktempdir [BASENAME] # ------------------------- # Make a temporary directory that won't clash with other running # libtool processes, and avoids race conditions if possible. If # given, BASENAME is the basename for that directory. func_mktempdir () { $debug_cmd _G_template=${TMPDIR-/tmp}/${1-$progname} if test : = "$opt_dry_run"; then # Return a directory name, but don't create it in dry-run mode _G_tmpdir=$_G_template-$$ else # If mktemp works, use that first and foremost _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null` if test ! -d "$_G_tmpdir"; then # Failing that, at least try and use $RANDOM to avoid a race _G_tmpdir=$_G_template-${RANDOM-0}$$ func_mktempdir_umask=`umask` umask 0077 $MKDIR "$_G_tmpdir" umask $func_mktempdir_umask fi # If we're not in dry-run mode, bomb out on failure test -d "$_G_tmpdir" || \ func_fatal_error "cannot create temporary directory '$_G_tmpdir'" fi $ECHO "$_G_tmpdir" } # func_normal_abspath PATH # ------------------------ # Remove doubled-up and trailing slashes, "." path components, # and cancel out any ".." path components in PATH after making # it an absolute path. func_normal_abspath () { $debug_cmd # These SED scripts presuppose an absolute path with a trailing slash. _G_pathcar='s|^/\([^/]*\).*$|\1|' _G_pathcdr='s|^/[^/]*||' _G_removedotparts=':dotsl s|/\./|/|g t dotsl s|/\.$|/|' _G_collapseslashes='s|/\{1,\}|/|g' _G_finalslash='s|/*$|/|' # Start from root dir and reassemble the path. func_normal_abspath_result= func_normal_abspath_tpath=$1 func_normal_abspath_altnamespace= case $func_normal_abspath_tpath in "") # Empty path, that just means $cwd. func_stripname '' '/' "`pwd`" func_normal_abspath_result=$func_stripname_result return ;; # The next three entries are used to spot a run of precisely # two leading slashes without using negated character classes; # we take advantage of case's first-match behaviour. ///*) # Unusual form of absolute path, do nothing. ;; //*) # Not necessarily an ordinary path; POSIX reserves leading '//' # and for example Cygwin uses it to access remote file shares # over CIFS/SMB, so we conserve a leading double slash if found. func_normal_abspath_altnamespace=/ ;; /*) # Absolute path, do nothing. ;; *) # Relative path, prepend $cwd. func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath ;; esac # Cancel out all the simple stuff to save iterations. We also want # the path to end with a slash for ease of parsing, so make sure # there is one (and only one) here. func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"` while :; do # Processed it all yet? if test / = "$func_normal_abspath_tpath"; then # If we ascended to the root using ".." the result may be empty now. if test -z "$func_normal_abspath_result"; then func_normal_abspath_result=/ fi break fi func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_pathcar"` func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_pathcdr"` # Figure out what to do with it case $func_normal_abspath_tcomponent in "") # Trailing empty path component, ignore it. ;; ..) # Parent dir; strip last assembled component from result. func_dirname "$func_normal_abspath_result" func_normal_abspath_result=$func_dirname_result ;; *) # Actual path component, append it. func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent" ;; esac done # Restore leading double-slash if one was found on entry. func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result } # func_notquiet ARG... # -------------------- # Echo program name prefixed message only when not in quiet mode. func_notquiet () { $debug_cmd $opt_quiet || func_echo ${1+"$@"} # A bug in bash halts the script if the last line of a function # fails when set -e is in force, so we need another command to # work around that: : } # func_relative_path SRCDIR DSTDIR # -------------------------------- # Set func_relative_path_result to the relative path from SRCDIR to DSTDIR. func_relative_path () { $debug_cmd func_relative_path_result= func_normal_abspath "$1" func_relative_path_tlibdir=$func_normal_abspath_result func_normal_abspath "$2" func_relative_path_tbindir=$func_normal_abspath_result # Ascend the tree starting from libdir while :; do # check if we have found a prefix of bindir case $func_relative_path_tbindir in $func_relative_path_tlibdir) # found an exact match func_relative_path_tcancelled= break ;; $func_relative_path_tlibdir*) # found a matching prefix func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" func_relative_path_tcancelled=$func_stripname_result if test -z "$func_relative_path_result"; then func_relative_path_result=. fi break ;; *) func_dirname $func_relative_path_tlibdir func_relative_path_tlibdir=$func_dirname_result if test -z "$func_relative_path_tlibdir"; then # Have to descend all the way to the root! func_relative_path_result=../$func_relative_path_result func_relative_path_tcancelled=$func_relative_path_tbindir break fi func_relative_path_result=../$func_relative_path_result ;; esac done # Now calculate path; take care to avoid doubling-up slashes. func_stripname '' '/' "$func_relative_path_result" func_relative_path_result=$func_stripname_result func_stripname '/' '/' "$func_relative_path_tcancelled" if test -n "$func_stripname_result"; then func_append func_relative_path_result "/$func_stripname_result" fi # Normalisation. If bindir is libdir, return '.' else relative path. if test -n "$func_relative_path_result"; then func_stripname './' '' "$func_relative_path_result" func_relative_path_result=$func_stripname_result fi test -n "$func_relative_path_result" || func_relative_path_result=. : } # func_quote_for_eval ARG... # -------------------------- # Aesthetically quote ARGs to be evaled later. # This function returns two values: # i) func_quote_for_eval_result # double-quoted, suitable for a subsequent eval # ii) func_quote_for_eval_unquoted_result # has all characters that are still active within double # quotes backslashified. func_quote_for_eval () { $debug_cmd func_quote_for_eval_unquoted_result= func_quote_for_eval_result= while test 0 -lt $#; do case $1 in *[\\\`\"\$]*) _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;; *) _G_unquoted_arg=$1 ;; esac if test -n "$func_quote_for_eval_unquoted_result"; then func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg" else func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg" fi case $_G_unquoted_arg in # Double-quote args containing shell metacharacters to delay # word splitting, command substitution and variable expansion # for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") _G_quoted_arg=\"$_G_unquoted_arg\" ;; *) _G_quoted_arg=$_G_unquoted_arg ;; esac if test -n "$func_quote_for_eval_result"; then func_append func_quote_for_eval_result " $_G_quoted_arg" else func_append func_quote_for_eval_result "$_G_quoted_arg" fi shift done } # func_quote_for_expand ARG # ------------------------- # Aesthetically quote ARG to be evaled later; same as above, # but do not quote variable references. func_quote_for_expand () { $debug_cmd case $1 in *[\\\`\"]*) _G_arg=`$ECHO "$1" | $SED \ -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;; *) _G_arg=$1 ;; esac case $_G_arg in # Double-quote args containing shell metacharacters to delay # word splitting and command substitution for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") _G_arg=\"$_G_arg\" ;; esac func_quote_for_expand_result=$_G_arg } # func_stripname PREFIX SUFFIX NAME # --------------------------------- # strip PREFIX and SUFFIX from NAME, and store in func_stripname_result. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_stripname () { $debug_cmd # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary variable first. func_stripname_result=$3 func_stripname_result=${func_stripname_result#"$1"} func_stripname_result=${func_stripname_result%"$2"} }' else func_stripname () { $debug_cmd case $2 in .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;; *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;; esac } fi # func_show_eval CMD [FAIL_EXP] # ----------------------------- # Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. func_show_eval () { $debug_cmd _G_cmd=$1 _G_fail_exp=${2-':'} func_quote_for_expand "$_G_cmd" eval "func_notquiet $func_quote_for_expand_result" $opt_dry_run || { eval "$_G_cmd" _G_status=$? if test 0 -ne "$_G_status"; then eval "(exit $_G_status); $_G_fail_exp" fi } } # func_show_eval_locale CMD [FAIL_EXP] # ------------------------------------ # Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. Use the saved locale for evaluation. func_show_eval_locale () { $debug_cmd _G_cmd=$1 _G_fail_exp=${2-':'} $opt_quiet || { func_quote_for_expand "$_G_cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || { eval "$_G_user_locale $_G_cmd" _G_status=$? eval "$_G_safe_locale" if test 0 -ne "$_G_status"; then eval "(exit $_G_status); $_G_fail_exp" fi } } # func_tr_sh # ---------- # Turn $1 into a string suitable for a shell variable name. # Result is stored in $func_tr_sh_result. All characters # not in the set a-zA-Z0-9_ are replaced with '_'. Further, # if $1 begins with a digit, a '_' is prepended as well. func_tr_sh () { $debug_cmd case $1 in [0-9]* | *[!a-zA-Z0-9_]*) func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'` ;; * ) func_tr_sh_result=$1 ;; esac } # func_verbose ARG... # ------------------- # Echo program name prefixed message in verbose mode only. func_verbose () { $debug_cmd $opt_verbose && func_echo "$*" : } # func_warn_and_continue ARG... # ----------------------------- # Echo program name prefixed warning message to standard error. func_warn_and_continue () { $debug_cmd $require_term_colors func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2 } # func_warning CATEGORY ARG... # ---------------------------- # Echo program name prefixed warning message to standard error. Warning # messages can be filtered according to CATEGORY, where this function # elides messages where CATEGORY is not listed in the global variable # 'opt_warning_types'. func_warning () { $debug_cmd # CATEGORY must be in the warning_categories list! case " $warning_categories " in *" $1 "*) ;; *) func_internal_error "invalid warning category '$1'" ;; esac _G_category=$1 shift case " $opt_warning_types " in *" $_G_category "*) $warning_func ${1+"$@"} ;; esac } # func_sort_ver VER1 VER2 # ----------------------- # 'sort -V' is not generally available. # Note this deviates from the version comparison in automake # in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a # but this should suffice as we won't be specifying old # version formats or redundant trailing .0 in bootstrap.conf. # If we did want full compatibility then we should probably # use m4_version_compare from autoconf. func_sort_ver () { $debug_cmd printf '%s\n%s\n' "$1" "$2" \ | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n } # func_lt_ver PREV CURR # --------------------- # Return true if PREV and CURR are in the correct order according to # func_sort_ver, otherwise false. Use it like this: # # func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..." func_lt_ver () { $debug_cmd test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q` } # Local variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: #! /bin/sh # Set a version string for this script. scriptversion=2014-01-07.03; # UTC # A portable, pluggable option parser for Bourne shell. # Written by Gary V. Vaughan, 2010 # Copyright (C) 2010-2015 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Please report bugs or propose patches to gary@gnu.org. ## ------ ## ## Usage. ## ## ------ ## # This file is a library for parsing options in your shell scripts along # with assorted other useful supporting features that you can make use # of too. # # For the simplest scripts you might need only: # # #!/bin/sh # . relative/path/to/funclib.sh # . relative/path/to/options-parser # scriptversion=1.0 # func_options ${1+"$@"} # eval set dummy "$func_options_result"; shift # ...rest of your script... # # In order for the '--version' option to work, you will need to have a # suitably formatted comment like the one at the top of this file # starting with '# Written by ' and ending with '# warranty; '. # # For '-h' and '--help' to work, you will also need a one line # description of your script's purpose in a comment directly above the # '# Written by ' line, like the one at the top of this file. # # The default options also support '--debug', which will turn on shell # execution tracing (see the comment above debug_cmd below for another # use), and '--verbose' and the func_verbose function to allow your script # to display verbose messages only when your user has specified # '--verbose'. # # After sourcing this file, you can plug processing for additional # options by amending the variables from the 'Configuration' section # below, and following the instructions in the 'Option parsing' # section further down. ## -------------- ## ## Configuration. ## ## -------------- ## # You should override these variables in your script after sourcing this # file so that they reflect the customisations you have added to the # option parser. # The usage line for option parsing errors and the start of '-h' and # '--help' output messages. You can embed shell variables for delayed # expansion at the time the message is displayed, but you will need to # quote other shell meta-characters carefully to prevent them being # expanded when the contents are evaled. usage='$progpath [OPTION]...' # Short help message in response to '-h' and '--help'. Add to this or # override it after sourcing this library to reflect the full set of # options your script accepts. usage_message="\ --debug enable verbose shell tracing -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] -v, --verbose verbosely report processing --version print version information and exit -h, --help print short or long help message and exit " # Additional text appended to 'usage_message' in response to '--help'. long_help_message=" Warning categories include: 'all' show all warnings 'none' turn off all the warnings 'error' warnings are treated as fatal errors" # Help message printed before fatal option parsing errors. fatal_help="Try '\$progname --help' for more information." ## ------------------------- ## ## Hook function management. ## ## ------------------------- ## # This section contains functions for adding, removing, and running hooks # to the main code. A hook is just a named list of of function, that can # be run in order later on. # func_hookable FUNC_NAME # ----------------------- # Declare that FUNC_NAME will run hooks added with # 'func_add_hook FUNC_NAME ...'. func_hookable () { $debug_cmd func_append hookable_fns " $1" } # func_add_hook FUNC_NAME HOOK_FUNC # --------------------------------- # Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must # first have been declared "hookable" by a call to 'func_hookable'. func_add_hook () { $debug_cmd case " $hookable_fns " in *" $1 "*) ;; *) func_fatal_error "'$1' does not accept hook functions." ;; esac eval func_append ${1}_hooks '" $2"' } # func_remove_hook FUNC_NAME HOOK_FUNC # ------------------------------------ # Remove HOOK_FUNC from the list of functions called by FUNC_NAME. func_remove_hook () { $debug_cmd eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`' } # func_run_hooks FUNC_NAME [ARG]... # --------------------------------- # Run all hook functions registered to FUNC_NAME. # It is assumed that the list of hook functions contains nothing more # than a whitespace-delimited list of legal shell function names, and # no effort is wasted trying to catch shell meta-characters or preserve # whitespace. func_run_hooks () { $debug_cmd case " $hookable_fns " in *" $1 "*) ;; *) func_fatal_error "'$1' does not support hook funcions.n" ;; esac eval _G_hook_fns=\$$1_hooks; shift for _G_hook in $_G_hook_fns; do eval $_G_hook '"$@"' # store returned options list back into positional # parameters for next 'cmd' execution. eval _G_hook_result=\$${_G_hook}_result eval set dummy "$_G_hook_result"; shift done func_quote_for_eval ${1+"$@"} func_run_hooks_result=$func_quote_for_eval_result } ## --------------- ## ## Option parsing. ## ## --------------- ## # In order to add your own option parsing hooks, you must accept the # full positional parameter list in your hook function, remove any # options that you action, and then pass back the remaining unprocessed # options in '_result', escaped suitably for # 'eval'. Like this: # # my_options_prep () # { # $debug_cmd # # # Extend the existing usage message. # usage_message=$usage_message' # -s, --silent don'\''t print informational messages # ' # # func_quote_for_eval ${1+"$@"} # my_options_prep_result=$func_quote_for_eval_result # } # func_add_hook func_options_prep my_options_prep # # # my_silent_option () # { # $debug_cmd # # # Note that for efficiency, we parse as many options as we can # # recognise in a loop before passing the remainder back to the # # caller on the first unrecognised argument we encounter. # while test $# -gt 0; do # opt=$1; shift # case $opt in # --silent|-s) opt_silent=: ;; # # Separate non-argument short options: # -s*) func_split_short_opt "$_G_opt" # set dummy "$func_split_short_opt_name" \ # "-$func_split_short_opt_arg" ${1+"$@"} # shift # ;; # *) set dummy "$_G_opt" "$*"; shift; break ;; # esac # done # # func_quote_for_eval ${1+"$@"} # my_silent_option_result=$func_quote_for_eval_result # } # func_add_hook func_parse_options my_silent_option # # # my_option_validation () # { # $debug_cmd # # $opt_silent && $opt_verbose && func_fatal_help "\ # '--silent' and '--verbose' options are mutually exclusive." # # func_quote_for_eval ${1+"$@"} # my_option_validation_result=$func_quote_for_eval_result # } # func_add_hook func_validate_options my_option_validation # # You'll alse need to manually amend $usage_message to reflect the extra # options you parse. It's preferable to append if you can, so that # multiple option parsing hooks can be added safely. # func_options [ARG]... # --------------------- # All the functions called inside func_options are hookable. See the # individual implementations for details. func_hookable func_options func_options () { $debug_cmd func_options_prep ${1+"$@"} eval func_parse_options \ ${func_options_prep_result+"$func_options_prep_result"} eval func_validate_options \ ${func_parse_options_result+"$func_parse_options_result"} eval func_run_hooks func_options \ ${func_validate_options_result+"$func_validate_options_result"} # save modified positional parameters for caller func_options_result=$func_run_hooks_result } # func_options_prep [ARG]... # -------------------------- # All initialisations required before starting the option parse loop. # Note that when calling hook functions, we pass through the list of # positional parameters. If a hook function modifies that list, and # needs to propogate that back to rest of this script, then the complete # modified list must be put in 'func_run_hooks_result' before # returning. func_hookable func_options_prep func_options_prep () { $debug_cmd # Option defaults: opt_verbose=false opt_warning_types= func_run_hooks func_options_prep ${1+"$@"} # save modified positional parameters for caller func_options_prep_result=$func_run_hooks_result } # func_parse_options [ARG]... # --------------------------- # The main option parsing loop. func_hookable func_parse_options func_parse_options () { $debug_cmd func_parse_options_result= # this just eases exit handling while test $# -gt 0; do # Defer to hook functions for initial option parsing, so they # get priority in the event of reusing an option name. func_run_hooks func_parse_options ${1+"$@"} # Adjust func_parse_options positional parameters to match eval set dummy "$func_run_hooks_result"; shift # Break out of the loop if we already parsed every option. test $# -gt 0 || break _G_opt=$1 shift case $_G_opt in --debug|-x) debug_cmd='set -x' func_echo "enabling shell trace mode" $debug_cmd ;; --no-warnings|--no-warning|--no-warn) set dummy --warnings none ${1+"$@"} shift ;; --warnings|--warning|-W) test $# = 0 && func_missing_arg $_G_opt && break case " $warning_categories $1" in *" $1 "*) # trailing space prevents matching last $1 above func_append_uniq opt_warning_types " $1" ;; *all) opt_warning_types=$warning_categories ;; *none) opt_warning_types=none warning_func=: ;; *error) opt_warning_types=$warning_categories warning_func=func_fatal_error ;; *) func_fatal_error \ "unsupported warning category: '$1'" ;; esac shift ;; --verbose|-v) opt_verbose=: ;; --version) func_version ;; -\?|-h) func_usage ;; --help) func_help ;; # Separate optargs to long options (plugins may need this): --*=*) func_split_equals "$_G_opt" set dummy "$func_split_equals_lhs" \ "$func_split_equals_rhs" ${1+"$@"} shift ;; # Separate optargs to short options: -W*) func_split_short_opt "$_G_opt" set dummy "$func_split_short_opt_name" \ "$func_split_short_opt_arg" ${1+"$@"} shift ;; # Separate non-argument short options: -\?*|-h*|-v*|-x*) func_split_short_opt "$_G_opt" set dummy "$func_split_short_opt_name" \ "-$func_split_short_opt_arg" ${1+"$@"} shift ;; --) break ;; -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; esac done # save modified positional parameters for caller func_quote_for_eval ${1+"$@"} func_parse_options_result=$func_quote_for_eval_result } # func_validate_options [ARG]... # ------------------------------ # Perform any sanity checks on option settings and/or unconsumed # arguments. func_hookable func_validate_options func_validate_options () { $debug_cmd # Display all warnings if -W was not given. test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" func_run_hooks func_validate_options ${1+"$@"} # Bail if the options were screwed! $exit_cmd $EXIT_FAILURE # save modified positional parameters for caller func_validate_options_result=$func_run_hooks_result } ## ----------------- ## ## Helper functions. ## ## ----------------- ## # This section contains the helper functions used by the rest of the # hookable option parser framework in ascii-betical order. # func_fatal_help ARG... # ---------------------- # Echo program name prefixed message to standard error, followed by # a help hint, and exit. func_fatal_help () { $debug_cmd eval \$ECHO \""Usage: $usage"\" eval \$ECHO \""$fatal_help"\" func_error ${1+"$@"} exit $EXIT_FAILURE } # func_help # --------- # Echo long help message to standard output and exit. func_help () { $debug_cmd func_usage_message $ECHO "$long_help_message" exit 0 } # func_missing_arg ARGNAME # ------------------------ # Echo program name prefixed message to standard error and set global # exit_cmd. func_missing_arg () { $debug_cmd func_error "Missing argument for '$1'." exit_cmd=exit } # func_split_equals STRING # ------------------------ # Set func_split_equals_lhs and func_split_equals_rhs shell variables after # splitting STRING at the '=' sign. test -z "$_G_HAVE_XSI_OPS" \ && (eval 'x=a/b/c; test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ && _G_HAVE_XSI_OPS=yes if test yes = "$_G_HAVE_XSI_OPS" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_split_equals () { $debug_cmd func_split_equals_lhs=${1%%=*} func_split_equals_rhs=${1#*=} test "x$func_split_equals_lhs" = "x$1" \ && func_split_equals_rhs= }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_split_equals () { $debug_cmd func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'` func_split_equals_rhs= test "x$func_split_equals_lhs" = "x$1" \ || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` } fi #func_split_equals # func_split_short_opt SHORTOPT # ----------------------------- # Set func_split_short_opt_name and func_split_short_opt_arg shell # variables after splitting SHORTOPT after the 2nd character. if test yes = "$_G_HAVE_XSI_OPS" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_split_short_opt () { $debug_cmd func_split_short_opt_arg=${1#??} func_split_short_opt_name=${1%"$func_split_short_opt_arg"} }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_split_short_opt () { $debug_cmd func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'` func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` } fi #func_split_short_opt # func_usage # ---------- # Echo short help message to standard output and exit. func_usage () { $debug_cmd func_usage_message $ECHO "Run '$progname --help |${PAGER-more}' for full usage" exit 0 } # func_usage_message # ------------------ # Echo short help message to standard output. func_usage_message () { $debug_cmd eval \$ECHO \""Usage: $usage"\" echo $SED -n 's|^# || /^Written by/{ x;p;x } h /^Written by/q' < "$progpath" echo eval \$ECHO \""$usage_message"\" } # func_version # ------------ # Echo version message to standard output and exit. func_version () { $debug_cmd printf '%s\n' "$progname $scriptversion" $SED -n ' /(C)/!b go :more /\./!{ N s|\n# | | b more } :go /^# Written by /,/# warranty; / { s|^# || s|^# *$|| s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| p } /^# Written by / { s|^# || p } /^warranty; /q' < "$progpath" exit $? } # Local variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: # Set a version string. scriptversion='(GNU libtool) 2.4.6' # func_echo ARG... # ---------------- # Libtool also displays the current mode in messages, so override # funclib.sh func_echo with this custom definition. func_echo () { $debug_cmd _G_message=$* func_echo_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_IFS $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line" done IFS=$func_echo_IFS } # func_warning ARG... # ------------------- # Libtool warnings are not categorized, so override funclib.sh # func_warning with this simpler definition. func_warning () { $debug_cmd $warning_func ${1+"$@"} } ## ---------------- ## ## Options parsing. ## ## ---------------- ## # Hook in the functions to make sure our own options are parsed during # the option parsing loop. usage='$progpath [OPTION]... [MODE-ARG]...' # Short help message in response to '-h'. usage_message="Options: --config show all configuration variables --debug enable verbose shell tracing -n, --dry-run display commands without modifying any files --features display basic configuration information and exit --mode=MODE use operation mode MODE --no-warnings equivalent to '-Wnone' --preserve-dup-deps don't remove duplicate dependency libraries --quiet, --silent don't print informational messages --tag=TAG use configuration variables from tag TAG -v, --verbose print more informational messages than default --version print version information -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] -h, --help, --help-all print short, long, or detailed help message " # Additional text appended to 'usage_message' in response to '--help'. func_help () { $debug_cmd func_usage_message $ECHO "$long_help_message MODE must be one of the following: clean remove files from the build directory compile compile a source file into a libtool object execute automatically set library path, then run a program finish complete the installation of libtool libraries install install libraries or executables link create a library or an executable uninstall remove libraries from an installed directory MODE-ARGS vary depending on the MODE. When passed as first option, '--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that. Try '$progname --help --mode=MODE' for a more detailed description of MODE. When reporting a bug, please describe a test case to reproduce it and include the following information: host-triplet: $host shell: $SHELL compiler: $LTCC compiler flags: $LTCFLAGS linker: $LD (gnu? $with_gnu_ld) version: $progname $scriptversion Debian-2.4.6-2 automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` Report bugs to . GNU libtool home page: . General help using GNU software: ." exit 0 } # func_lo2o OBJECT-NAME # --------------------- # Transform OBJECT-NAME from a '.lo' suffix to the platform specific # object suffix. lo2o=s/\\.lo\$/.$objext/ o2lo=s/\\.$objext\$/.lo/ if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_lo2o () { case $1 in *.lo) func_lo2o_result=${1%.lo}.$objext ;; * ) func_lo2o_result=$1 ;; esac }' # func_xform LIBOBJ-OR-SOURCE # --------------------------- # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise) # suffix to a '.lo' libtool-object suffix. eval 'func_xform () { func_xform_result=${1%.*}.lo }' else # ...otherwise fall back to using sed. func_lo2o () { func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"` } func_xform () { func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'` } fi # func_fatal_configuration ARG... # ------------------------------- # Echo program name prefixed message to standard error, followed by # a configuration failure hint, and exit. func_fatal_configuration () { func__fatal_error ${1+"$@"} \ "See the $PACKAGE documentation for more information." \ "Fatal configuration error." } # func_config # ----------- # Display the configuration for all the tags in this script. func_config () { re_begincf='^# ### BEGIN LIBTOOL' re_endcf='^# ### END LIBTOOL' # Default configuration. $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" # Now print the configurations for the tags. for tagname in $taglist; do $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" done exit $? } # func_features # ------------- # Display the features supported by this script. func_features () { echo "host: $host" if test yes = "$build_libtool_libs"; then echo "enable shared libraries" else echo "disable shared libraries" fi if test yes = "$build_old_libs"; then echo "enable static libraries" else echo "disable static libraries" fi exit $? } # func_enable_tag TAGNAME # ----------------------- # Verify that TAGNAME is valid, and either flag an error and exit, or # enable the TAGNAME tag. We also add TAGNAME to the global $taglist # variable here. func_enable_tag () { # Global variable: tagname=$1 re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" sed_extractcf=/$re_begincf/,/$re_endcf/p # Validate tagname. case $tagname in *[!-_A-Za-z0-9,/]*) func_fatal_error "invalid tag name: $tagname" ;; esac # Don't test for the "default" C tag, as we know it's # there but not specially marked. case $tagname in CC) ;; *) if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then taglist="$taglist $tagname" # Evaluate the configuration. Be careful to quote the path # and the sed script, to avoid splitting on whitespace, but # also don't use non-portable quotes within backquotes within # quotes we have to do it in 2 steps: extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` eval "$extractedcf" else func_error "ignoring unknown tag $tagname" fi ;; esac } # func_check_version_match # ------------------------ # Ensure that we are using m4 macros, and libtool script from the same # release of libtool. func_check_version_match () { if test "$package_revision" != "$macro_revision"; then if test "$VERSION" != "$macro_version"; then if test -z "$macro_version"; then cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from an older release. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from $PACKAGE $macro_version. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF fi else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, $progname: but the definition of this LT_INIT comes from revision $macro_revision. $progname: You should recreate aclocal.m4 with macros from revision $package_revision $progname: of $PACKAGE $VERSION and run autoconf again. _LT_EOF fi exit $EXIT_MISMATCH fi } # libtool_options_prep [ARG]... # ----------------------------- # Preparation for options parsed by libtool. libtool_options_prep () { $debug_mode # Option defaults: opt_config=false opt_dlopen= opt_dry_run=false opt_help=false opt_mode= opt_preserve_dup_deps=false opt_quiet=false nonopt= preserve_args= # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) shift; set dummy --mode clean ${1+"$@"}; shift ;; compile|compil|compi|comp|com|co|c) shift; set dummy --mode compile ${1+"$@"}; shift ;; execute|execut|execu|exec|exe|ex|e) shift; set dummy --mode execute ${1+"$@"}; shift ;; finish|finis|fini|fin|fi|f) shift; set dummy --mode finish ${1+"$@"}; shift ;; install|instal|insta|inst|ins|in|i) shift; set dummy --mode install ${1+"$@"}; shift ;; link|lin|li|l) shift; set dummy --mode link ${1+"$@"}; shift ;; uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; esac # Pass back the list of options. func_quote_for_eval ${1+"$@"} libtool_options_prep_result=$func_quote_for_eval_result } func_add_hook func_options_prep libtool_options_prep # libtool_parse_options [ARG]... # --------------------------------- # Provide handling for libtool specific options. libtool_parse_options () { $debug_cmd # Perform our own loop to consume as many options as possible in # each iteration. while test $# -gt 0; do _G_opt=$1 shift case $_G_opt in --dry-run|--dryrun|-n) opt_dry_run=: ;; --config) func_config ;; --dlopen|-dlopen) opt_dlopen="${opt_dlopen+$opt_dlopen }$1" shift ;; --preserve-dup-deps) opt_preserve_dup_deps=: ;; --features) func_features ;; --finish) set dummy --mode finish ${1+"$@"}; shift ;; --help) opt_help=: ;; --help-all) opt_help=': help-all' ;; --mode) test $# = 0 && func_missing_arg $_G_opt && break opt_mode=$1 case $1 in # Valid mode arguments: clean|compile|execute|finish|install|link|relink|uninstall) ;; # Catch anything else as an error *) func_error "invalid argument for $_G_opt" exit_cmd=exit break ;; esac shift ;; --no-silent|--no-quiet) opt_quiet=false func_append preserve_args " $_G_opt" ;; --no-warnings|--no-warning|--no-warn) opt_warning=false func_append preserve_args " $_G_opt" ;; --no-verbose) opt_verbose=false func_append preserve_args " $_G_opt" ;; --silent|--quiet) opt_quiet=: opt_verbose=false func_append preserve_args " $_G_opt" ;; --tag) test $# = 0 && func_missing_arg $_G_opt && break opt_tag=$1 func_append preserve_args " $_G_opt $1" func_enable_tag "$1" shift ;; --verbose|-v) opt_quiet=false opt_verbose=: func_append preserve_args " $_G_opt" ;; # An option not handled by this hook function: *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; esac done # save modified positional parameters for caller func_quote_for_eval ${1+"$@"} libtool_parse_options_result=$func_quote_for_eval_result } func_add_hook func_parse_options libtool_parse_options # libtool_validate_options [ARG]... # --------------------------------- # Perform any sanity checks on option settings and/or unconsumed # arguments. libtool_validate_options () { # save first non-option argument if test 0 -lt $#; then nonopt=$1 shift fi # preserve --debug test : = "$debug_cmd" || func_append preserve_args " --debug" case $host in # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452 # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788 *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*) # don't eliminate duplications in $postdeps and $predeps opt_duplicate_compiler_generated_deps=: ;; *) opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps ;; esac $opt_help || { # Sanity checks first: func_check_version_match test yes != "$build_libtool_libs" \ && test yes != "$build_old_libs" \ && func_fatal_configuration "not configured to build any kind of library" # Darwin sucks eval std_shrext=\"$shrext_cmds\" # Only execute mode is allowed to have -dlopen flags. if test -n "$opt_dlopen" && test execute != "$opt_mode"; then func_error "unrecognized option '-dlopen'" $ECHO "$help" 1>&2 exit $EXIT_FAILURE fi # Change the help message to a mode-specific one. generic_help=$help help="Try '$progname --help --mode=$opt_mode' for more information." } # Pass back the unparsed argument list func_quote_for_eval ${1+"$@"} libtool_validate_options_result=$func_quote_for_eval_result } func_add_hook func_validate_options libtool_validate_options # Process options as early as possible so that --help and --version # can return quickly. func_options ${1+"$@"} eval set dummy "$func_options_result"; shift ## ----------- ## ## Main. ## ## ----------- ## magic='%%%MAGIC variable%%%' magic_exe='%%%MAGIC EXE variable%%%' # Global variables. extracted_archives= extracted_serial=0 # If this variable is set in any of the actions, the command in it # will be execed at the end. This prevents here-documents from being # left over by shells. exec_cmd= # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } # func_generated_by_libtool # True iff stdin has been generated by Libtool. This function is only # a basic sanity check; it will hardly flush out determined imposters. func_generated_by_libtool_p () { $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 } # func_lalib_p file # True iff FILE is a libtool '.la' library or '.lo' object file. # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_lalib_p () { test -f "$1" && $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p } # func_lalib_unsafe_p file # True iff FILE is a libtool '.la' library or '.lo' object file. # This function implements the same check as func_lalib_p without # resorting to external programs. To this end, it redirects stdin and # closes it afterwards, without saving the original file descriptor. # As a safety measure, use it only where a negative result would be # fatal anyway. Works if 'file' does not exist. func_lalib_unsafe_p () { lalib_p=no if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then for lalib_p_l in 1 2 3 4 do read lalib_p_line case $lalib_p_line in \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; esac done exec 0<&5 5<&- fi test yes = "$lalib_p" } # func_ltwrapper_script_p file # True iff FILE is a libtool wrapper script # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_script_p () { test -f "$1" && $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p } # func_ltwrapper_executable_p file # True iff FILE is a libtool wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_executable_p () { func_ltwrapper_exec_suffix= case $1 in *.exe) ;; *) func_ltwrapper_exec_suffix=.exe ;; esac $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 } # func_ltwrapper_scriptname file # Assumes file is an ltwrapper_executable # uses $file to determine the appropriate filename for a # temporary ltwrapper_script. func_ltwrapper_scriptname () { func_dirname_and_basename "$1" "" "." func_stripname '' '.exe' "$func_basename_result" func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper } # func_ltwrapper_p file # True iff FILE is a libtool wrapper script or wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_p () { func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" } # func_execute_cmds commands fail_cmd # Execute tilde-delimited COMMANDS. # If FAIL_CMD is given, eval that upon failure. # FAIL_CMD may read-access the current command in variable CMD! func_execute_cmds () { $debug_cmd save_ifs=$IFS; IFS='~' for cmd in $1; do IFS=$sp$nl eval cmd=\"$cmd\" IFS=$save_ifs func_show_eval "$cmd" "${2-:}" done IFS=$save_ifs } # func_source file # Source FILE, adding directory component if necessary. # Note that it is not necessary on cygwin/mingw to append a dot to # FILE even if both FILE and FILE.exe exist: automatic-append-.exe # behavior happens only for exec(3), not for open(2)! Also, sourcing # 'FILE.' does not work on cygwin managed mounts. func_source () { $debug_cmd case $1 in */* | *\\*) . "$1" ;; *) . "./$1" ;; esac } # func_resolve_sysroot PATH # Replace a leading = in PATH with a sysroot. Store the result into # func_resolve_sysroot_result func_resolve_sysroot () { func_resolve_sysroot_result=$1 case $func_resolve_sysroot_result in =*) func_stripname '=' '' "$func_resolve_sysroot_result" func_resolve_sysroot_result=$lt_sysroot$func_stripname_result ;; esac } # func_replace_sysroot PATH # If PATH begins with the sysroot, replace it with = and # store the result into func_replace_sysroot_result. func_replace_sysroot () { case $lt_sysroot:$1 in ?*:"$lt_sysroot"*) func_stripname "$lt_sysroot" '' "$1" func_replace_sysroot_result='='$func_stripname_result ;; *) # Including no sysroot. func_replace_sysroot_result=$1 ;; esac } # func_infer_tag arg # Infer tagged configuration to use if any are available and # if one wasn't chosen via the "--tag" command line option. # Only attempt this if the compiler in the base compile # command doesn't match the default compiler. # arg is usually of the form 'gcc ...' func_infer_tag () { $debug_cmd if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case $@ in # Blanks in the command may have been stripped by the calling shell, # but not from the CC environment variable when configure was run. " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; # Blanks at the start of $base_compile will cause this to fail # if we don't check for them as well. *) for z in $available_tags; do if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case "$@ " in " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) # The compiler in the base compile command matches # the one in the tagged configuration. # Assume this is the tagged configuration we want. tagname=$z break ;; esac fi done # If $tagname still isn't set, then no tagged configuration # was found and let the user know that the "--tag" command # line option must be used. if test -z "$tagname"; then func_echo "unable to infer tagged configuration" func_fatal_error "specify a tag with '--tag'" # else # func_verbose "using $tagname tagged configuration" fi ;; esac fi } # func_write_libtool_object output_name pic_name nonpic_name # Create a libtool object file (analogous to a ".la" file), # but don't create it if we're doing a dry run. func_write_libtool_object () { write_libobj=$1 if test yes = "$build_libtool_libs"; then write_lobj=\'$2\' else write_lobj=none fi if test yes = "$build_old_libs"; then write_oldobj=\'$3\' else write_oldobj=none fi $opt_dry_run || { cat >${write_libobj}T </dev/null` if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | $SED -e "$sed_naive_backslashify"` else func_convert_core_file_wine_to_w32_result= fi fi } # end: func_convert_core_file_wine_to_w32 # func_convert_core_path_wine_to_w32 ARG # Helper function used by path conversion functions when $build is *nix, and # $host is mingw, cygwin, or some other w32 environment. Relies on a correctly # configured wine environment available, with the winepath program in $build's # $PATH. Assumes ARG has no leading or trailing path separator characters. # # ARG is path to be converted from $build format to win32. # Result is available in $func_convert_core_path_wine_to_w32_result. # Unconvertible file (directory) names in ARG are skipped; if no directory names # are convertible, then the result may be empty. func_convert_core_path_wine_to_w32 () { $debug_cmd # unfortunately, winepath doesn't convert paths, only file names func_convert_core_path_wine_to_w32_result= if test -n "$1"; then oldIFS=$IFS IFS=: for func_convert_core_path_wine_to_w32_f in $1; do IFS=$oldIFS func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" if test -n "$func_convert_core_file_wine_to_w32_result"; then if test -z "$func_convert_core_path_wine_to_w32_result"; then func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result else func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" fi fi done IFS=$oldIFS fi } # end: func_convert_core_path_wine_to_w32 # func_cygpath ARGS... # Wrapper around calling the cygpath program via LT_CYGPATH. This is used when # when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) # $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or # (2), returns the Cygwin file name or path in func_cygpath_result (input # file name or path is assumed to be in w32 format, as previously converted # from $build's *nix or MSYS format). In case (3), returns the w32 file name # or path in func_cygpath_result (input file name or path is assumed to be in # Cygwin format). Returns an empty string on error. # # ARGS are passed to cygpath, with the last one being the file name or path to # be converted. # # Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH # environment variable; do not put it in $PATH. func_cygpath () { $debug_cmd if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` if test "$?" -ne 0; then # on failure, ensure result is empty func_cygpath_result= fi else func_cygpath_result= func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'" fi } #end: func_cygpath # func_convert_core_msys_to_w32 ARG # Convert file name or path ARG from MSYS format to w32 format. Return # result in func_convert_core_msys_to_w32_result. func_convert_core_msys_to_w32 () { $debug_cmd # awkward: cmd appends spaces to result func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"` } #end: func_convert_core_msys_to_w32 # func_convert_file_check ARG1 ARG2 # Verify that ARG1 (a file name in $build format) was converted to $host # format in ARG2. Otherwise, emit an error message, but continue (resetting # func_to_host_file_result to ARG1). func_convert_file_check () { $debug_cmd if test -z "$2" && test -n "$1"; then func_error "Could not determine host file name corresponding to" func_error " '$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback: func_to_host_file_result=$1 fi } # end func_convert_file_check # func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH # Verify that FROM_PATH (a path in $build format) was converted to $host # format in TO_PATH. Otherwise, emit an error message, but continue, resetting # func_to_host_file_result to a simplistic fallback value (see below). func_convert_path_check () { $debug_cmd if test -z "$4" && test -n "$3"; then func_error "Could not determine the host path corresponding to" func_error " '$3'" func_error "Continuing, but uninstalled executables may not work." # Fallback. This is a deliberately simplistic "conversion" and # should not be "improved". See libtool.info. if test "x$1" != "x$2"; then lt_replace_pathsep_chars="s|$1|$2|g" func_to_host_path_result=`echo "$3" | $SED -e "$lt_replace_pathsep_chars"` else func_to_host_path_result=$3 fi fi } # end func_convert_path_check # func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG # Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT # and appending REPL if ORIG matches BACKPAT. func_convert_path_front_back_pathsep () { $debug_cmd case $4 in $1 ) func_to_host_path_result=$3$func_to_host_path_result ;; esac case $4 in $2 ) func_append func_to_host_path_result "$3" ;; esac } # end func_convert_path_front_back_pathsep ################################################## # $build to $host FILE NAME CONVERSION FUNCTIONS # ################################################## # invoked via '$to_host_file_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # Result will be available in $func_to_host_file_result. # func_to_host_file ARG # Converts the file name ARG from $build format to $host format. Return result # in func_to_host_file_result. func_to_host_file () { $debug_cmd $to_host_file_cmd "$1" } # end func_to_host_file # func_to_tool_file ARG LAZY # converts the file name ARG from $build format to toolchain format. Return # result in func_to_tool_file_result. If the conversion in use is listed # in (the comma separated) LAZY, no conversion takes place. func_to_tool_file () { $debug_cmd case ,$2, in *,"$to_tool_file_cmd",*) func_to_tool_file_result=$1 ;; *) $to_tool_file_cmd "$1" func_to_tool_file_result=$func_to_host_file_result ;; esac } # end func_to_tool_file # func_convert_file_noop ARG # Copy ARG to func_to_host_file_result. func_convert_file_noop () { func_to_host_file_result=$1 } # end func_convert_file_noop # func_convert_file_msys_to_w32 ARG # Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_file_result. func_convert_file_msys_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_to_host_file_result=$func_convert_core_msys_to_w32_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_w32 # func_convert_file_cygwin_to_w32 ARG # Convert file name ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_file_cygwin_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then # because $build is cygwin, we call "the" cygpath in $PATH; no need to use # LT_CYGPATH in this case. func_to_host_file_result=`cygpath -m "$1"` fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_cygwin_to_w32 # func_convert_file_nix_to_w32 ARG # Convert file name ARG from *nix to w32 format. Requires a wine environment # and a working winepath. Returns result in func_to_host_file_result. func_convert_file_nix_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_file_wine_to_w32 "$1" func_to_host_file_result=$func_convert_core_file_wine_to_w32_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_w32 # func_convert_file_msys_to_cygwin ARG # Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_file_msys_to_cygwin () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_cygpath -u "$func_convert_core_msys_to_w32_result" func_to_host_file_result=$func_cygpath_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_cygwin # func_convert_file_nix_to_cygwin ARG # Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed # in a wine environment, working winepath, and LT_CYGPATH set. Returns result # in func_to_host_file_result. func_convert_file_nix_to_cygwin () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. func_convert_core_file_wine_to_w32 "$1" func_cygpath -u "$func_convert_core_file_wine_to_w32_result" func_to_host_file_result=$func_cygpath_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_cygwin ############################################# # $build to $host PATH CONVERSION FUNCTIONS # ############################################# # invoked via '$to_host_path_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # The result will be available in $func_to_host_path_result. # # Path separators are also converted from $build format to $host format. If # ARG begins or ends with a path separator character, it is preserved (but # converted to $host format) on output. # # All path conversion functions are named using the following convention: # file name conversion function : func_convert_file_X_to_Y () # path conversion function : func_convert_path_X_to_Y () # where, for any given $build/$host combination the 'X_to_Y' value is the # same. If conversion functions are added for new $build/$host combinations, # the two new functions must follow this pattern, or func_init_to_host_path_cmd # will break. # func_init_to_host_path_cmd # Ensures that function "pointer" variable $to_host_path_cmd is set to the # appropriate value, based on the value of $to_host_file_cmd. to_host_path_cmd= func_init_to_host_path_cmd () { $debug_cmd if test -z "$to_host_path_cmd"; then func_stripname 'func_convert_file_' '' "$to_host_file_cmd" to_host_path_cmd=func_convert_path_$func_stripname_result fi } # func_to_host_path ARG # Converts the path ARG from $build format to $host format. Return result # in func_to_host_path_result. func_to_host_path () { $debug_cmd func_init_to_host_path_cmd $to_host_path_cmd "$1" } # end func_to_host_path # func_convert_path_noop ARG # Copy ARG to func_to_host_path_result. func_convert_path_noop () { func_to_host_path_result=$1 } # end func_convert_path_noop # func_convert_path_msys_to_w32 ARG # Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_path_result. func_convert_path_msys_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # Remove leading and trailing path separator characters from ARG. MSYS # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; # and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result=$func_convert_core_msys_to_w32_result func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_msys_to_w32 # func_convert_path_cygwin_to_w32 ARG # Convert path ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_path_cygwin_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_cygwin_to_w32 # func_convert_path_nix_to_w32 ARG # Convert path ARG from *nix to w32 format. Requires a wine environment and # a working winepath. Returns result in func_to_host_file_result. func_convert_path_nix_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result=$func_convert_core_path_wine_to_w32_result func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_nix_to_w32 # func_convert_path_msys_to_cygwin ARG # Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_path_msys_to_cygwin () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_msys_to_w32_result" func_to_host_path_result=$func_cygpath_result func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_msys_to_cygwin # func_convert_path_nix_to_cygwin ARG # Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a # a wine environment, working winepath, and LT_CYGPATH set. Returns result in # func_to_host_file_result. func_convert_path_nix_to_cygwin () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # Remove leading and trailing path separator characters from # ARG. msys behavior is inconsistent here, cygpath turns them # into '.;' and ';.', and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" func_to_host_path_result=$func_cygpath_result func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_nix_to_cygwin # func_dll_def_p FILE # True iff FILE is a Windows DLL '.def' file. # Keep in sync with _LT_DLL_DEF_P in libtool.m4 func_dll_def_p () { $debug_cmd func_dll_def_p_tmp=`$SED -n \ -e 's/^[ ]*//' \ -e '/^\(;.*\)*$/d' \ -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \ -e q \ "$1"` test DEF = "$func_dll_def_p_tmp" } # func_mode_compile arg... func_mode_compile () { $debug_cmd # Get the compilation command and the source file. base_compile= srcfile=$nonopt # always keep a non-empty value in "srcfile" suppress_opt=yes suppress_output= arg_mode=normal libobj= later= pie_flag= for arg do case $arg_mode in arg ) # do not "continue". Instead, add this to base_compile lastarg=$arg arg_mode=normal ;; target ) libobj=$arg arg_mode=normal continue ;; normal ) # Accept any command-line options. case $arg in -o) test -n "$libobj" && \ func_fatal_error "you cannot specify '-o' more than once" arg_mode=target continue ;; -pie | -fpie | -fPIE) func_append pie_flag " $arg" continue ;; -shared | -static | -prefer-pic | -prefer-non-pic) func_append later " $arg" continue ;; -no-suppress) suppress_opt=no continue ;; -Xcompiler) arg_mode=arg # the next one goes into the "base_compile" arg list continue # The current "srcfile" will either be retained or ;; # replaced later. I would guess that would be a bug. -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result lastarg= save_ifs=$IFS; IFS=, for arg in $args; do IFS=$save_ifs func_append_quoted lastarg "$arg" done IFS=$save_ifs func_stripname ' ' '' "$lastarg" lastarg=$func_stripname_result # Add the arguments to base_compile. func_append base_compile " $lastarg" continue ;; *) # Accept the current argument as the source file. # The previous "srcfile" becomes the current argument. # lastarg=$srcfile srcfile=$arg ;; esac # case $arg ;; esac # case $arg_mode # Aesthetically quote the previous argument. func_append_quoted base_compile "$lastarg" done # for arg case $arg_mode in arg) func_fatal_error "you must specify an argument for -Xcompile" ;; target) func_fatal_error "you must specify a target with '-o'" ;; *) # Get the name of the library object. test -z "$libobj" && { func_basename "$srcfile" libobj=$func_basename_result } ;; esac # Recognize several different file suffixes. # If the user specifies -o file.o, it is replaced with file.lo case $libobj in *.[cCFSifmso] | \ *.ada | *.adb | *.ads | *.asm | \ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) func_xform "$libobj" libobj=$func_xform_result ;; esac case $libobj in *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; *) func_fatal_error "cannot determine name of library object from '$libobj'" ;; esac func_infer_tag $base_compile for arg in $later; do case $arg in -shared) test yes = "$build_libtool_libs" \ || func_fatal_configuration "cannot build a shared library" build_old_libs=no continue ;; -static) build_libtool_libs=no build_old_libs=yes continue ;; -prefer-pic) pic_mode=yes continue ;; -prefer-non-pic) pic_mode=no continue ;; esac done func_quote_for_eval "$libobj" test "X$libobj" != "X$func_quote_for_eval_result" \ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ && func_warning "libobj name '$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" objname=$func_basename_result xdir=$func_dirname_result lobj=$xdir$objdir/$objname test -z "$base_compile" && \ func_fatal_help "you must specify a compilation command" # Delete any leftover library objects. if test yes = "$build_old_libs"; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" fi # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | pw32* | os2* | cegcc*) pic_mode=default ;; esac if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c if test no = "$compiler_c_o"; then output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext lockfile=$output_obj.lock else output_obj= need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test yes = "$need_locks"; then until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done elif test warn = "$need_locks"; then if test -f "$lockfile"; then $ECHO "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi func_append removelist " $output_obj" $ECHO "$srcfile" > "$lockfile" fi $opt_dry_run || $RM $removelist func_append removelist " $lockfile" trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 srcfile=$func_to_tool_file_result func_quote_for_eval "$srcfile" qsrcfile=$func_quote_for_eval_result # Only build a PIC object if we are building libtool libraries. if test yes = "$build_libtool_libs"; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile if test no != "$pic_mode"; then command="$base_compile $qsrcfile $pic_flag" else # Don't build PIC code command="$base_compile $qsrcfile" fi func_mkdir_p "$xdir$objdir" if test -z "$output_obj"; then # Place PIC objects in $objdir func_append command " -o $lobj" fi func_show_eval_locale "$command" \ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' if test warn = "$need_locks" && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed, then go on to compile the next one if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then func_show_eval '$MV "$output_obj" "$lobj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi # Allow error messages only from the first compilation. if test yes = "$suppress_opt"; then suppress_output=' >/dev/null 2>&1' fi fi # Only build a position-dependent object if we build old libraries. if test yes = "$build_old_libs"; then if test yes != "$pic_mode"; then # Don't build PIC code command="$base_compile $qsrcfile$pie_flag" else command="$base_compile $qsrcfile $pic_flag" fi if test yes = "$compiler_c_o"; then func_append command " -o $obj" fi # Suppress compiler output if we already did a PIC compilation. func_append command "$suppress_output" func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' if test warn = "$need_locks" && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then func_show_eval '$MV "$output_obj" "$obj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi fi $opt_dry_run || { func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" # Unlock the critical section if it was locked if test no != "$need_locks"; then removelist=$lockfile $RM "$lockfile" fi } exit $EXIT_SUCCESS } $opt_help || { test compile = "$opt_mode" && func_mode_compile ${1+"$@"} } func_mode_help () { # We need to display help for each of the modes. case $opt_mode in "") # Generic help is extracted from the usage comments # at the start of this file. func_help ;; clean) $ECHO \ "Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE (typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; compile) $ECHO \ "Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -no-suppress do not suppress compiler output for multiple passes -prefer-pic try to build PIC objects only -prefer-non-pic try to build non-PIC objects only -shared do not build a '.o' file suitable for static linking -static only build a '.o' file suitable for static linking -Wc,FLAG pass FLAG directly to the compiler COMPILE-COMMAND is a command to be used in creating a 'standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix '.c' with the library object suffix, '.lo'." ;; execute) $ECHO \ "Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to '-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $ECHO \ "Usage: $progname [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the '--dry-run' option if you just want to see what would be executed." ;; install) $ECHO \ "Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the 'install' or 'cp' program. The following components of INSTALL-COMMAND are treated specially: -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $ECHO \ "Usage: $progname [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -bindir BINDIR specify path to binaries directory (for systems where libraries must be found in the PATH setting at runtime) -dlopen FILE '-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-fast-install disable the fast-install mode -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -objectlist FILE use a list of object files found in FILE to specify objects -os2dllname NAME force a short DLL name on OS/2 (no effect on other OSes) -precious-files-regex REGEX don't remove output files matching REGEX -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -shared only do dynamic linking of libtool libraries -shrext SUFFIX override the standard shared library file extension -static do not do any dynamic linking of uninstalled libtool libraries -static-libtool-libs do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] -weak LIBNAME declare that the target provides the LIBNAME interface -Wc,FLAG -Xcompiler FLAG pass linker-specific FLAG directly to the compiler -Wl,FLAG -Xlinker FLAG pass linker-specific FLAG directly to the linker -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) All other options (arguments beginning with '-') are ignored. Every other argument is treated as a filename. Files ending in '.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in '.la', then a libtool library is created, only library objects ('.lo' files) may be specified, and '-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created using 'ar' and 'ranlib', or on Windows using 'lib'. If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $ECHO \ "Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) func_fatal_help "invalid operation mode '$opt_mode'" ;; esac echo $ECHO "Try '$progname --help' for more information about other modes." } # Now that we've collected a possible --mode arg, show help if necessary if $opt_help; then if test : = "$opt_help"; then func_mode_help else { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do func_mode_help done } | $SED -n '1p; 2,$s/^Usage:/ or: /p' { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do echo func_mode_help done } | $SED '1d /^When reporting/,/^Report/{ H d } $x /information about other modes/d /more detailed .*MODE/d s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' fi exit $? fi # func_mode_execute arg... func_mode_execute () { $debug_cmd # The first argument is the command name. cmd=$nonopt test -z "$cmd" && \ func_fatal_help "you must specify a COMMAND" # Handle -dlopen flags immediately. for file in $opt_dlopen; do test -f "$file" \ || func_fatal_help "'$file' is not a file" dir= case $file in *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "'$lib' is not a valid libtool archive" # Read the libtool library. dlname= library_names= func_source "$file" # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && \ func_warning "'$file' was not linked with '-export-dynamic'" continue fi func_dirname "$file" "" "." dir=$func_dirname_result if test -f "$dir/$objdir/$dlname"; then func_append dir "/$objdir" else if test ! -f "$dir/$dlname"; then func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'" fi fi ;; *.lo) # Just add the directory containing the .lo file. func_dirname "$file" "" "." dir=$func_dirname_result ;; *) func_warning "'-dlopen' is ignored for non-libtool libraries and objects" continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir=$absdir # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic=$magic # Check if any of the arguments is a wrapper script. args= for file do case $file in -* | *.la | *.lo ) ;; *) # Do a test to see if this is really a libtool program. if func_ltwrapper_script_p "$file"; then func_source "$file" # Transform arg to wrapped name. file=$progdir/$program elif func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" func_source "$func_ltwrapper_scriptname_result" # Transform arg to wrapped name. file=$progdir/$program fi ;; esac # Quote arguments (to preserve shell metacharacters). func_append_quoted args "$file" done if $opt_dry_run; then # Display what would be done. if test -n "$shlibpath_var"; then eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" echo "export $shlibpath_var" fi $ECHO "$cmd$args" exit $EXIT_SUCCESS else if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" fi # Restore saved environment variables for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${save_$lt_var+set}\" = set; then $lt_var=\$save_$lt_var; export $lt_var else $lt_unset $lt_var fi" done # Now prepare to actually exec the command. exec_cmd=\$cmd$args fi } test execute = "$opt_mode" && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { $debug_cmd libs= libdirs= admincmds= for opt in "$nonopt" ${1+"$@"} do if test -d "$opt"; then func_append libdirs " $opt" elif test -f "$opt"; then if func_lalib_unsafe_p "$opt"; then func_append libs " $opt" else func_warning "'$opt' is not a valid libtool archive" fi else func_fatal_error "invalid argument '$opt'" fi done if test -n "$libs"; then if test -n "$lt_sysroot"; then sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" else sysroot_cmd= fi # Remove sysroot references if $opt_dry_run; then for lib in $libs; do echo "removing references to $lt_sysroot and '=' prefixes from $lib" done else tmpdir=`func_mktempdir` for lib in $libs; do $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ > $tmpdir/tmp-la mv -f $tmpdir/tmp-la $lib done ${RM}r "$tmpdir" fi fi if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. func_execute_cmds "$finish_cmds" 'admincmds="$admincmds '"$cmd"'"' fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $opt_dry_run || eval "$cmds" || func_append admincmds " $cmds" fi done fi # Exit here if they wanted silent mode. $opt_quiet && exit $EXIT_SUCCESS if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then echo "----------------------------------------------------------------------" echo "Libraries have been installed in:" for libdir in $libdirs; do $ECHO " $libdir" done echo echo "If you ever happen to want to link against installed libraries" echo "in a given directory, LIBDIR, you must either use libtool, and" echo "specify the full pathname of the library, or use the '-LLIBDIR'" echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then echo " - add LIBDIR to the '$shlibpath_var' environment variable" echo " during execution" fi if test -n "$runpath_var"; then echo " - add LIBDIR to the '$runpath_var' environment variable" echo " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" $ECHO " - use the '$flag' linker flag" fi if test -n "$admincmds"; then $ECHO " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then echo " - have your system administrator add LIBDIR to '/etc/ld.so.conf'" fi echo echo "See any operating system documentation about shared libraries for" case $host in solaris2.[6789]|solaris2.1[0-9]) echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" echo "pages." ;; *) echo "more information, such as the ld(1) and ld.so(8) manual pages." ;; esac echo "----------------------------------------------------------------------" fi exit $EXIT_SUCCESS } test finish = "$opt_mode" && func_mode_finish ${1+"$@"} # func_mode_install arg... func_mode_install () { $debug_cmd # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" || # Allow the use of GNU shtool's install command. case $nonopt in *shtool*) :;; *) false;; esac then # Aesthetically quote it. func_quote_for_eval "$nonopt" install_prog="$func_quote_for_eval_result " arg=$1 shift else install_prog= arg=$nonopt fi # The real first argument should be the name of the installation program. # Aesthetically quote it. func_quote_for_eval "$arg" func_append install_prog "$func_quote_for_eval_result" install_shared_prog=$install_prog case " $install_prog " in *[\\\ /]cp\ *) install_cp=: ;; *) install_cp=false ;; esac # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=false stripme= no_mode=: for arg do arg2= if test -n "$dest"; then func_append files " $dest" dest=$arg continue fi case $arg in -d) isdir=: ;; -f) if $install_cp; then :; else prev=$arg fi ;; -g | -m | -o) prev=$arg ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then if test X-m = "X$prev" && test -n "$install_override_mode"; then arg2=$install_override_mode no_mode=false fi prev= else dest=$arg continue fi ;; esac # Aesthetically quote the argument. func_quote_for_eval "$arg" func_append install_prog " $func_quote_for_eval_result" if test -n "$arg2"; then func_quote_for_eval "$arg2" fi func_append install_shared_prog " $func_quote_for_eval_result" done test -z "$install_prog" && \ func_fatal_help "you must specify an install program" test -n "$prev" && \ func_fatal_help "the '$prev' option requires an argument" if test -n "$install_override_mode" && $no_mode; then if $install_cp; then :; else func_quote_for_eval "$install_override_mode" func_append install_shared_prog " -m $func_quote_for_eval_result" fi fi if test -z "$files"; then if test -z "$dest"; then func_fatal_help "no file or destination specified" else func_fatal_help "you must specify a destination" fi fi # Strip any trailing slash from the destination. func_stripname '' '/' "$dest" dest=$func_stripname_result # Check to see that the destination is a directory. test -d "$dest" && isdir=: if $isdir; then destdir=$dest destname= else func_dirname_and_basename "$dest" "" "." destdir=$func_dirname_result destname=$func_basename_result # Not a directory, so check to see that there is only one file specified. set dummy $files; shift test "$#" -gt 1 && \ func_fatal_help "'$dest' is not a directory" fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) func_fatal_help "'$destdir' must be an absolute directory name" ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic=$magic staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case $file in *.$libext) # Do the static libraries later. func_append staticlibs " $file" ;; *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "'$file' is not a valid libtool archive" library_names= old_library= relink_command= func_source "$file" # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) func_append current_libdirs " $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) func_append future_libdirs " $libdir" ;; esac fi func_dirname "$file" "/" "" dir=$func_dirname_result func_append dir "$objdir" if test -n "$relink_command"; then # Determine the prefix the user has applied to our future dir. inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that # are installed to the same prefix. # At present, this check doesn't affect windows .dll's that # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. test "$inst_prefix_dir" = "$destdir" && \ func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir" if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` fi func_warning "relinking '$file'" func_show_eval "$relink_command" \ 'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"' fi # See the names of the shared library. set dummy $library_names; shift if test -n "$1"; then realname=$1 shift srcname=$realname test -n "$relink_command" && srcname=${realname}T # Install the shared library and build the symlinks. func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ 'exit $?' tstripme=$stripme case $host_os in cygwin* | mingw* | pw32* | cegcc*) case $realname in *.dll.a) tstripme= ;; esac ;; os2*) case $realname in *_dll.a) tstripme= ;; esac ;; esac if test -n "$tstripme" && test -n "$striplib"; then func_show_eval "$striplib $destdir/$realname" 'exit $?' fi if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. # Try 'ln -sf' first, because the 'ln' binary might depend on # the symlink we replace! Solaris /bin/ln does not understand -f, # so we also need to try rm && ln -s. for linkname do test "$linkname" != "$realname" \ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" done fi # Do each command in the postinstall commands. lib=$destdir/$realname func_execute_cmds "$postinstall_cmds" 'exit $?' fi # Install the pseudo-library for information purposes. func_basename "$file" name=$func_basename_result instname=$dir/${name}i func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' # Maybe install the static library, too. test -n "$old_library" && func_append staticlibs " $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile=$destdir/$destname else func_basename "$file" destfile=$func_basename_result destfile=$destdir/$destfile fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) func_lo2o "$destfile" staticdest=$func_lo2o_result ;; *.$objext) staticdest=$destfile destfile= ;; *) func_fatal_help "cannot copy a libtool object to '$destfile'" ;; esac # Install the libtool object if requested. test -n "$destfile" && \ func_show_eval "$install_prog $file $destfile" 'exit $?' # Install the old object if enabled. if test yes = "$build_old_libs"; then # Deduce the name of the old-style object file. func_lo2o "$file" staticobj=$func_lo2o_result func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' fi exit $EXIT_SUCCESS ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile=$destdir/$destname else func_basename "$file" destfile=$func_basename_result destfile=$destdir/$destfile fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install stripped_ext= case $file in *.exe) if test ! -f "$file"; then func_stripname '' '.exe' "$file" file=$func_stripname_result stripped_ext=.exe fi ;; esac # Do a test to see if this is really a libtool program. case $host in *cygwin* | *mingw*) if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" wrapper=$func_ltwrapper_scriptname_result else func_stripname '' '.exe' "$file" wrapper=$func_stripname_result fi ;; *) wrapper=$file ;; esac if func_ltwrapper_script_p "$wrapper"; then notinst_deplibs= relink_command= func_source "$wrapper" # Check the variables that should have been set. test -z "$generated_by_libtool_version" && \ func_fatal_error "invalid libtool wrapper script '$wrapper'" finalize=: for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then func_source "$lib" fi libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'` if test -n "$libdir" && test ! -f "$libfile"; then func_warning "'$lib' has not been installed in '$libdir'" finalize=false fi done relink_command= func_source "$wrapper" outputname= if test no = "$fast_install" && test -n "$relink_command"; then $opt_dry_run || { if $finalize; then tmpdir=`func_mktempdir` func_basename "$file$stripped_ext" file=$func_basename_result outputname=$tmpdir/$file # Replace the output file specification. relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` $opt_quiet || { func_quote_for_expand "$relink_command" eval "func_echo $func_quote_for_expand_result" } if eval "$relink_command"; then : else func_error "error: relink '$file' with the above command before installing it" $opt_dry_run || ${RM}r "$tmpdir" continue fi file=$outputname else func_warning "cannot relink '$file'" fi } else # Install the binary that we compiled earlier. file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` fi fi # remove .exe since cygwin /usr/bin/install will append another # one anyway case $install_prog,$host in */usr/bin/install*,*cygwin*) case $file:$destfile in *.exe:*.exe) # this is ok ;; *.exe:*) destfile=$destfile.exe ;; *:*.exe) func_stripname '' '.exe' "$destfile" destfile=$func_stripname_result ;; esac ;; esac func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' $opt_dry_run || if test -n "$outputname"; then ${RM}r "$tmpdir" fi ;; esac done for file in $staticlibs; do func_basename "$file" name=$func_basename_result # Set up the ranlib parameters. oldlib=$destdir/$name func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result func_show_eval "$install_prog \$file \$oldlib" 'exit $?' if test -n "$stripme" && test -n "$old_striplib"; then func_show_eval "$old_striplib $tool_oldlib" 'exit $?' fi # Do each command in the postinstall commands. func_execute_cmds "$old_postinstall_cmds" 'exit $?' done test -n "$future_libdirs" && \ func_warning "remember to run '$progname --finish$future_libdirs'" if test -n "$current_libdirs"; then # Maybe just do a dry run. $opt_dry_run && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi } test install = "$opt_mode" && func_mode_install ${1+"$@"} # func_generate_dlsyms outputname originator pic_p # Extract symbols from dlprefiles and create ${outputname}S.o with # a dlpreopen symbol table. func_generate_dlsyms () { $debug_cmd my_outputname=$1 my_originator=$2 my_pic_p=${3-false} my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'` my_dlsyms= if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then if test -n "$NM" && test -n "$global_symbol_pipe"; then my_dlsyms=${my_outputname}S.c else func_error "not configured to extract global symbols from dlpreopened files" fi fi if test -n "$my_dlsyms"; then case $my_dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist=$output_objdir/$my_outputname.nm func_show_eval "$RM $nlist ${nlist}S ${nlist}T" # Parse the name list into a source file. func_verbose "creating $output_objdir/$my_dlsyms" $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ /* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */ /* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */ #ifdef __cplusplus extern \"C\" { #endif #if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) #pragma GCC diagnostic ignored \"-Wstrict-prototypes\" #endif /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) /* External symbol declarations for the compiler. */\ " if test yes = "$dlself"; then func_verbose "generating symbol list for '$output'" $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` for progfile in $progfiles; do func_to_tool_file "$progfile" func_convert_file_msys_to_w32 func_verbose "extracting global C symbols from '$func_to_tool_file_result'" $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $opt_dry_run || { eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi if test -n "$export_symbols_regex"; then $opt_dry_run || { eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols=$output_objdir/$outputname.exp $opt_dry_run || { $RM $export_symbols eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; esac } else $opt_dry_run || { eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; esac } fi fi for dlprefile in $dlprefiles; do func_verbose "extracting global C symbols from '$dlprefile'" func_basename "$dlprefile" name=$func_basename_result case $host in *cygwin* | *mingw* | *cegcc* ) # if an import library, we need to obtain dlname if func_win32_import_lib_p "$dlprefile"; then func_tr_sh "$dlprefile" eval "curr_lafile=\$libfile_$func_tr_sh_result" dlprefile_dlbasename= if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then # Use subshell, to avoid clobbering current variable values dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` if test -n "$dlprefile_dlname"; then func_basename "$dlprefile_dlname" dlprefile_dlbasename=$func_basename_result else # no lafile. user explicitly requested -dlpreopen . $sharedlib_from_linklib_cmd "$dlprefile" dlprefile_dlbasename=$sharedlib_from_linklib_result fi fi $opt_dry_run || { if test -n "$dlprefile_dlbasename"; then eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' else func_warning "Could not compute DLL name from $name" eval '$ECHO ": $name " >> "$nlist"' fi func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" } else # not an import lib $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } fi ;; *) $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } ;; esac done $opt_dry_run || { # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $MV "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if $GREP -v "^: " < "$nlist" | if sort -k 3 /dev/null 2>&1; then sort -k 3 else sort +2 fi | uniq > "$nlist"S; then : else $GREP -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' else echo '/* NONE */' >> "$output_objdir/$my_dlsyms" fi func_show_eval '$RM "${nlist}I"' if test -n "$global_symbol_to_import"; then eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I' fi echo >> "$output_objdir/$my_dlsyms" "\ /* The mapping between symbol names and symbols. */ typedef struct { const char *name; void *address; } lt_dlsymlist; extern LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[];\ " if test -s "$nlist"I; then echo >> "$output_objdir/$my_dlsyms" "\ static void lt_syminit(void) { LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols; for (; symbol->name; ++symbol) {" $SED 's/.*/ if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms" echo >> "$output_objdir/$my_dlsyms" "\ } }" fi echo >> "$output_objdir/$my_dlsyms" "\ LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = { {\"$my_originator\", (void *) 0}," if test -s "$nlist"I; then echo >> "$output_objdir/$my_dlsyms" "\ {\"@INIT@\", (void *) <_syminit}," fi case $need_lib_prefix in no) eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; *) eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; esac echo >> "$output_objdir/$my_dlsyms" "\ {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_${my_prefix}_LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " } # !$opt_dry_run pic_flag_for_symtable= case "$compile_command " in *" -static "*) ;; *) case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; *) $my_pic_p && pic_flag_for_symtable=" $pic_flag" ;; esac ;; esac symtab_cflags= for arg in $LTCFLAGS; do case $arg in -pie | -fpie | -fPIE) ;; *) func_append symtab_cflags " $arg" ;; esac done # Now compile the dynamic symbol file. func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' # Clean up the generated files. func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"' # Transform the symbol file into the correct name. symfileobj=$output_objdir/${my_outputname}S.$objext case $host in *cygwin* | *mingw* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` else compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` fi ;; *) compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` ;; esac ;; *) func_fatal_error "unknown suffix for '$my_dlsyms'" ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` fi } # func_cygming_gnu_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is a GNU/binutils-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_gnu_implib_p () { $debug_cmd func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` test -n "$func_cygming_gnu_implib_tmp" } # func_cygming_ms_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is an MS-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_ms_implib_p () { $debug_cmd func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` test -n "$func_cygming_ms_implib_tmp" } # func_win32_libid arg # return the library type of file 'arg' # # Need a lot of goo to handle *both* DLLs and import libs # Has to be a shell function in order to 'eat' the argument # that is supplied when $file_magic_command is called. # Despite the name, also deal with 64 bit binaries. func_win32_libid () { $debug_cmd win32_libid_type=unknown win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import win32_libid_type="x86 archive import" ;; *ar\ archive*) # could be an import, or static # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then case $nm_interface in "MS dumpbin") if func_cygming_ms_implib_p "$1" || func_cygming_gnu_implib_p "$1" then win32_nmres=import else win32_nmres= fi ;; *) func_to_tool_file "$1" func_convert_file_msys_to_w32 win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | $SED -n -e ' 1,100{ / I /{ s|.*|import| p q } }'` ;; esac case $win32_nmres in import*) win32_libid_type="x86 archive import";; *) win32_libid_type="x86 archive static";; esac fi ;; *DLL*) win32_libid_type="x86 DLL" ;; *executable*) # but shell scripts are "executable" too... case $win32_fileres in *MS\ Windows\ PE\ Intel*) win32_libid_type="x86 DLL" ;; esac ;; esac $ECHO "$win32_libid_type" } # func_cygming_dll_for_implib ARG # # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib () { $debug_cmd sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` } # func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs # # The is the core of a fallback implementation of a # platform-specific function to extract the name of the # DLL associated with the specified import library LIBNAME. # # SECTION_NAME is either .idata$6 or .idata$7, depending # on the platform and compiler that created the implib. # # Echos the name of the DLL associated with the # specified import library. func_cygming_dll_for_implib_fallback_core () { $debug_cmd match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` $OBJDUMP -s --section "$1" "$2" 2>/dev/null | $SED '/^Contents of section '"$match_literal"':/{ # Place marker at beginning of archive member dllname section s/.*/====MARK====/ p d } # These lines can sometimes be longer than 43 characters, but # are always uninteresting /:[ ]*file format pe[i]\{,1\}-/d /^In archive [^:]*:/d # Ensure marker is printed /^====MARK====/p # Remove all lines with less than 43 characters /^.\{43\}/!d # From remaining lines, remove first 43 characters s/^.\{43\}//' | $SED -n ' # Join marker and all lines until next marker into a single line /^====MARK====/ b para H $ b para b :para x s/\n//g # Remove the marker s/^====MARK====// # Remove trailing dots and whitespace s/[\. \t]*$// # Print /./p' | # we now have a list, one entry per line, of the stringified # contents of the appropriate section of all members of the # archive that possess that section. Heuristic: eliminate # all those that have a first or second character that is # a '.' (that is, objdump's representation of an unprintable # character.) This should work for all archives with less than # 0x302f exports -- but will fail for DLLs whose name actually # begins with a literal '.' or a single character followed by # a '.'. # # Of those that remain, print the first one. $SED -e '/^\./d;/^.\./d;q' } # func_cygming_dll_for_implib_fallback ARG # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # # This fallback implementation is for use when $DLLTOOL # does not support the --identify-strict option. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib_fallback () { $debug_cmd if func_cygming_gnu_implib_p "$1"; then # binutils import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` elif func_cygming_ms_implib_p "$1"; then # ms-generated import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` else # unknown sharedlib_from_linklib_result= fi } # func_extract_an_archive dir oldlib func_extract_an_archive () { $debug_cmd f_ex_an_ar_dir=$1; shift f_ex_an_ar_oldlib=$1 if test yes = "$lock_old_archive_extraction"; then lockfile=$f_ex_an_ar_oldlib.lock until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done fi func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ 'stat=$?; rm -f "$lockfile"; exit $stat' if test yes = "$lock_old_archive_extraction"; then $opt_dry_run || rm -f "$lockfile" fi if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then : else func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" fi } # func_extract_archives gentop oldlib ... func_extract_archives () { $debug_cmd my_gentop=$1; shift my_oldlibs=${1+"$@"} my_oldobjs= my_xlib= my_xabs= my_xdir= for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in [\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac func_basename "$my_xlib" my_xlib=$func_basename_result my_xlib_u=$my_xlib while :; do case " $extracted_archives " in *" $my_xlib_u "*) func_arith $extracted_serial + 1 extracted_serial=$func_arith_result my_xlib_u=lt$extracted_serial-$my_xlib ;; *) break ;; esac done extracted_archives="$extracted_archives $my_xlib_u" my_xdir=$my_gentop/$my_xlib_u func_mkdir_p "$my_xdir" case $host in *-darwin*) func_verbose "Extracting $my_xabs" # Do not bother doing anything if just a dry run $opt_dry_run || { darwin_orig_dir=`pwd` cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` func_basename "$darwin_archive" darwin_base_archive=$func_basename_result darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` if test -n "$darwin_arches"; then darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" for darwin_arch in $darwin_arches; do func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch" $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive" cd "unfat-$$/$darwin_base_archive-$darwin_arch" func_extract_an_archive "`pwd`" "$darwin_base_archive" cd "$darwin_curdir" $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" done # $darwin_arches ## Okay now we've a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` $LIPO -create -output "$darwin_file" $darwin_files done # $darwin_filelist $RM -rf unfat-$$ cd "$darwin_orig_dir" else cd $darwin_orig_dir func_extract_an_archive "$my_xdir" "$my_xabs" fi # $darwin_arches } # !$opt_dry_run ;; *) func_extract_an_archive "$my_xdir" "$my_xabs" ;; esac my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` done func_extract_archives_result=$my_oldobjs } # func_emit_wrapper [arg=no] # # Emit a libtool wrapper script on stdout. # Don't directly open a file because we may want to # incorporate the script contents within a cygwin/mingw # wrapper executable. Must ONLY be called from within # func_mode_link because it depends on a number of variables # set therein. # # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script # will assume that the directory where it is stored is # the $objdir directory. This is a cygwin/mingw-specific # behavior. func_emit_wrapper () { func_emit_wrapper_arg1=${1-no} $ECHO "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM (GNU $PACKAGE) $VERSION # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='$sed_quote_subst' # Be Bourne compatible if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variables: generated_by_libtool_version='$macro_version' notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$ECHO are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then file=\"\$0\"" qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` $ECHO "\ # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } ECHO=\"$qECHO\" fi # Very basic option parsing. These options are (a) specific to # the libtool wrapper, (b) are identical between the wrapper # /script/ and the wrapper /executable/ that is used only on # windows platforms, and (c) all begin with the string "--lt-" # (application programs are unlikely to have options that match # this pattern). # # There are only two supported options: --lt-debug and # --lt-dump-script. There is, deliberately, no --lt-help. # # The first argument to this parsing function should be the # script's $0 value, followed by "$@". lt_option_debug= func_parse_lt_options () { lt_script_arg0=\$0 shift for lt_opt do case \"\$lt_opt\" in --lt-debug) lt_option_debug=1 ;; --lt-dump-script) lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` cat \"\$lt_dump_D/\$lt_dump_F\" exit 0 ;; --lt-*) \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 exit 1 ;; esac done # Print the debug banner immediately: if test -n \"\$lt_option_debug\"; then echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2 fi } # Used when --lt-debug. Prints its arguments to stdout # (redirection is the responsibility of the caller) func_lt_dump_args () { lt_dump_args_N=1; for lt_arg do \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\" lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` done } # Core function for launching the target application func_exec_program_core () { " case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2* | *-cegcc*) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} " ;; *) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir/\$program\" \${1+\"\$@\"} " ;; esac $ECHO "\ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 exit 1 } # A function to encapsulate launching the target application # Strips options in the --lt-* namespace from \$@ and # launches target application with the remaining arguments. func_exec_program () { case \" \$* \" in *\\ --lt-*) for lt_wr_arg do case \$lt_wr_arg in --lt-*) ;; *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; esac shift done ;; esac func_exec_program_core \${1+\"\$@\"} } # Parse options func_parse_lt_options \"\$0\" \${1+\"\$@\"} # Find the directory that this script lives in. thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` done # Usually 'no', except on cygwin/mingw when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then # special case for '.' if test \"\$thisdir\" = \".\"; then thisdir=\`pwd\` fi # remove .libs from thisdir case \"\$thisdir\" in *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; $objdir ) thisdir=. ;; esac fi # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test yes = "$fast_install"; then $ECHO "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $MKDIR \"\$progdir\" else $RM \"\$progdir/\$file\" fi" $ECHO "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else \$ECHO \"\$relink_command_output\" >&2 $RM \"\$progdir/\$file\" exit 1 fi fi $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $RM \"\$progdir/\$program\"; $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } $RM \"\$progdir/\$file\" fi" else $ECHO "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi $ECHO "\ if test -f \"\$progdir/\$program\"; then" # fixup the dll searchpath if we need to. # # Fix the DLL searchpath if we need to. Do this before prepending # to shlibpath, because on Windows, both are PATH and uninstalled # libraries must come first. if test -n "$dllsearchpath"; then $ECHO "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi # Export our shlibpath_var if we have one. if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $ECHO "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` export $shlibpath_var " fi $ECHO "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. func_exec_program \${1+\"\$@\"} fi else # The program doesn't exist. \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2 \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 fi fi\ " } # func_emit_cwrapperexe_src # emit the source code for a wrapper executable on stdout # Must ONLY be called from within func_mode_link because # it depends on a number of variable set therein. func_emit_cwrapperexe_src () { cat < #include #ifdef _MSC_VER # include # include # include #else # include # include # ifdef __CYGWIN__ # include # endif #endif #include #include #include #include #include #include #include #include #define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) /* declarations of non-ANSI functions */ #if defined __MINGW32__ # ifdef __STRICT_ANSI__ int _putenv (const char *); # endif #elif defined __CYGWIN__ # ifdef __STRICT_ANSI__ char *realpath (const char *, char *); int putenv (char *); int setenv (const char *, const char *, int); # endif /* #elif defined other_platform || defined ... */ #endif /* portability defines, excluding path handling macros */ #if defined _MSC_VER # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv # define S_IXUSR _S_IEXEC #elif defined __MINGW32__ # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv #elif defined __CYGWIN__ # define HAVE_SETENV # define FOPEN_WB "wb" /* #elif defined other platforms ... */ #endif #if defined PATH_MAX # define LT_PATHMAX PATH_MAX #elif defined MAXPATHLEN # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 #endif #ifndef S_IXOTH # define S_IXOTH 0 #endif #ifndef S_IXGRP # define S_IXGRP 0 #endif /* path handling portability macros */ #ifndef DIR_SEPARATOR # define DIR_SEPARATOR '/' # define PATH_SEPARATOR ':' #endif #if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \ defined __OS2__ # define HAVE_DOS_BASED_FILE_SYSTEM # define FOPEN_WB "wb" # ifndef DIR_SEPARATOR_2 # define DIR_SEPARATOR_2 '\\' # endif # ifndef PATH_SEPARATOR_2 # define PATH_SEPARATOR_2 ';' # endif #endif #ifndef DIR_SEPARATOR_2 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) #else /* DIR_SEPARATOR_2 */ # define IS_DIR_SEPARATOR(ch) \ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) #endif /* DIR_SEPARATOR_2 */ #ifndef PATH_SEPARATOR_2 # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) #else /* PATH_SEPARATOR_2 */ # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) #endif /* PATH_SEPARATOR_2 */ #ifndef FOPEN_WB # define FOPEN_WB "w" #endif #ifndef _O_BINARY # define _O_BINARY 0 #endif #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free (stale); stale = 0; } \ } while (0) #if defined LT_DEBUGWRAPPER static int lt_debug = 1; #else static int lt_debug = 0; #endif const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ void *xmalloc (size_t num); char *xstrdup (const char *string); const char *base_name (const char *name); char *find_executable (const char *wrapper); char *chase_symlinks (const char *pathspec); int make_executable (const char *path); int check_executable (const char *path); char *strendzap (char *str, const char *pat); void lt_debugprintf (const char *file, int line, const char *fmt, ...); void lt_fatal (const char *file, int line, const char *message, ...); static const char *nonnull (const char *s); static const char *nonempty (const char *s); void lt_setenv (const char *name, const char *value); char *lt_extend_str (const char *orig_value, const char *add, int to_end); void lt_update_exe_path (const char *name, const char *value); void lt_update_lib_path (const char *name, const char *value); char **prepare_spawn (char **argv); void lt_dump_script (FILE *f); EOF cat <= 0) && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return 1; else return 0; } int make_executable (const char *path) { int rval = 0; struct stat st; lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", nonempty (path)); if ((!path) || (!*path)) return 0; if (stat (path, &st) >= 0) { rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); } return rval; } /* Searches for the full path of the wrapper. Returns newly allocated full path name if found, NULL otherwise Does not chase symlinks, even on platforms that support them. */ char * find_executable (const char *wrapper) { int has_slash = 0; const char *p; const char *p_next; /* static buffer for getcwd */ char tmp[LT_PATHMAX + 1]; size_t tmp_len; char *concat_name; lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", nonempty (wrapper)); if ((wrapper == NULL) || (*wrapper == '\0')) return NULL; /* Absolute path? */ #if defined HAVE_DOS_BASED_FILE_SYSTEM if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } else { #endif if (IS_DIR_SEPARATOR (wrapper[0])) { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } #if defined HAVE_DOS_BASED_FILE_SYSTEM } #endif for (p = wrapper; *p; p++) if (*p == '/') { has_slash = 1; break; } if (!has_slash) { /* no slashes; search PATH */ const char *path = getenv ("PATH"); if (path != NULL) { for (p = path; *p; p = p_next) { const char *q; size_t p_len; for (q = p; *q; q++) if (IS_PATH_SEPARATOR (*q)) break; p_len = (size_t) (q - p); p_next = (*q == '\0' ? q : q + 1); if (p_len == 0) { /* empty path: current directory */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); } else { concat_name = XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, p, p_len); concat_name[p_len] = '/'; strcpy (concat_name + p_len + 1, wrapper); } if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } } /* not found in PATH; assume curdir */ } /* Relative path | not found in path: prepend cwd */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); return NULL; } char * chase_symlinks (const char *pathspec) { #ifndef S_ISLNK return xstrdup (pathspec); #else char buf[LT_PATHMAX]; struct stat s; char *tmp_pathspec = xstrdup (pathspec); char *p; int has_symlinks = 0; while (strlen (tmp_pathspec) && !has_symlinks) { lt_debugprintf (__FILE__, __LINE__, "checking path component for symlinks: %s\n", tmp_pathspec); if (lstat (tmp_pathspec, &s) == 0) { if (S_ISLNK (s.st_mode) != 0) { has_symlinks = 1; break; } /* search backwards for last DIR_SEPARATOR */ p = tmp_pathspec + strlen (tmp_pathspec) - 1; while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) p--; if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) { /* no more DIR_SEPARATORS left */ break; } *p = '\0'; } else { lt_fatal (__FILE__, __LINE__, "error accessing file \"%s\": %s", tmp_pathspec, nonnull (strerror (errno))); } } XFREE (tmp_pathspec); if (!has_symlinks) { return xstrdup (pathspec); } tmp_pathspec = realpath (pathspec, buf); if (tmp_pathspec == 0) { lt_fatal (__FILE__, __LINE__, "could not follow symlinks for %s", pathspec); } return xstrdup (tmp_pathspec); #endif } char * strendzap (char *str, const char *pat) { size_t len, patlen; assert (str != NULL); assert (pat != NULL); len = strlen (str); patlen = strlen (pat); if (patlen <= len) { str += len - patlen; if (STREQ (str, pat)) *str = '\0'; } return str; } void lt_debugprintf (const char *file, int line, const char *fmt, ...) { va_list args; if (lt_debug) { (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); va_start (args, fmt); (void) vfprintf (stderr, fmt, args); va_end (args); } } static void lt_error_core (int exit_status, const char *file, int line, const char *mode, const char *message, va_list ap) { fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *file, int line, const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); va_end (ap); } static const char * nonnull (const char *s) { return s ? s : "(null)"; } static const char * nonempty (const char *s) { return (s && !*s) ? "(empty)" : nonnull (s); } void lt_setenv (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_setenv) setting '%s' to '%s'\n", nonnull (name), nonnull (value)); { #ifdef HAVE_SETENV /* always make a copy, for consistency with !HAVE_SETENV */ char *str = xstrdup (value); setenv (name, str, 1); #else size_t len = strlen (name) + 1 + strlen (value) + 1; char *str = XMALLOC (char, len); sprintf (str, "%s=%s", name, value); if (putenv (str) != EXIT_SUCCESS) { XFREE (str); } #endif } } char * lt_extend_str (const char *orig_value, const char *add, int to_end) { char *new_value; if (orig_value && *orig_value) { size_t orig_value_len = strlen (orig_value); size_t add_len = strlen (add); new_value = XMALLOC (char, add_len + orig_value_len + 1); if (to_end) { strcpy (new_value, orig_value); strcpy (new_value + orig_value_len, add); } else { strcpy (new_value, add); strcpy (new_value + add_len, orig_value); } } else { new_value = xstrdup (add); } return new_value; } void lt_update_exe_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); /* some systems can't cope with a ':'-terminated path #' */ size_t len = strlen (new_value); while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1])) { new_value[--len] = '\0'; } lt_setenv (name, new_value); XFREE (new_value); } } void lt_update_lib_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); } } EOF case $host_os in mingw*) cat <<"EOF" /* Prepares an argument vector before calling spawn(). Note that spawn() does not by itself call the command interpreter (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&v); v.dwPlatformId == VER_PLATFORM_WIN32_NT; }) ? "cmd.exe" : "command.com"). Instead it simply concatenates the arguments, separated by ' ', and calls CreateProcess(). We must quote the arguments since Win32 CreateProcess() interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a special way: - Space and tab are interpreted as delimiters. They are not treated as delimiters if they are surrounded by double quotes: "...". - Unescaped double quotes are removed from the input. Their only effect is that within double quotes, space and tab are treated like normal characters. - Backslashes not followed by double quotes are not special. - But 2*n+1 backslashes followed by a double quote become n backslashes followed by a double quote (n >= 0): \" -> " \\\" -> \" \\\\\" -> \\" */ #define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" #define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" char ** prepare_spawn (char **argv) { size_t argc; char **new_argv; size_t i; /* Count number of arguments. */ for (argc = 0; argv[argc] != NULL; argc++) ; /* Allocate new argument vector. */ new_argv = XMALLOC (char *, argc + 1); /* Put quoted arguments into the new argument vector. */ for (i = 0; i < argc; i++) { const char *string = argv[i]; if (string[0] == '\0') new_argv[i] = xstrdup ("\"\""); else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) { int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); size_t length; unsigned int backslashes; const char *s; char *quoted_string; char *p; length = 0; backslashes = 0; if (quote_around) length++; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') length += backslashes + 1; length++; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) length += backslashes + 1; quoted_string = XMALLOC (char, length + 1); p = quoted_string; backslashes = 0; if (quote_around) *p++ = '"'; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') { unsigned int j; for (j = backslashes + 1; j > 0; j--) *p++ = '\\'; } *p++ = c; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) { unsigned int j; for (j = backslashes; j > 0; j--) *p++ = '\\'; *p++ = '"'; } *p = '\0'; new_argv[i] = quoted_string; } else new_argv[i] = (char *) string; } new_argv[argc] = NULL; return new_argv; } EOF ;; esac cat <<"EOF" void lt_dump_script (FILE* f) { EOF func_emit_wrapper yes | $SED -n -e ' s/^\(.\{79\}\)\(..*\)/\1\ \2/ h s/\([\\"]\)/\\\1/g s/$/\\n/ s/\([^\n]*\).*/ fputs ("\1", f);/p g D' cat <<"EOF" } EOF } # end: func_emit_cwrapperexe_src # func_win32_import_lib_p ARG # True if ARG is an import lib, as indicated by $file_magic_cmd func_win32_import_lib_p () { $debug_cmd case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in *import*) : ;; *) false ;; esac } # func_suncc_cstd_abi # !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!! # Several compiler flags select an ABI that is incompatible with the # Cstd library. Avoid specifying it if any are in CXXFLAGS. func_suncc_cstd_abi () { $debug_cmd case " $compile_command " in *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*) suncc_use_cstd_abi=no ;; *) suncc_use_cstd_abi=yes ;; esac } # func_mode_link arg... func_mode_link () { $debug_cmd case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # what system we are compiling for in order to pass an extra # flag for every libtool invocation. # allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying # to make a dll that has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. allow_undefined=yes ;; *) allow_undefined=yes ;; esac libtool_args=$nonopt base_compile="$nonopt $@" compile_command=$nonopt finalize_command=$nonopt compile_rpath= finalize_rpath= compile_shlibpath= finalize_shlibpath= convenience= old_convenience= deplibs= old_deplibs= compiler_flags= linker_flags= dllsearchpath= lib_search_path=`pwd` inst_prefix_dir= new_inherited_linker_flags= avoid_version=no bindir= dlfiles= dlprefiles= dlself=no export_dynamic=no export_symbols= export_symbols_regex= generated= libobjs= ltlibs= module=no no_install=no objs= os2dllname= non_pic_objects= precious_files_regex= prefer_static_libs=no preload=false prev= prevarg= release= rpath= xrpath= perm_rpath= temp_rpath= thread_safe=no vinfo= vinfo_number=no weak_libs= single_module=$wl-single_module func_infer_tag $base_compile # We need to know -static, to get the right output filenames. for arg do case $arg in -shared) test yes != "$build_libtool_libs" \ && func_fatal_configuration "cannot build a shared library" build_old_libs=no break ;; -all-static | -static | -static-libtool-libs) case $arg in -all-static) if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then func_warning "complete static linking is impossible in this configuration" fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; -static) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=built ;; -static-libtool-libs) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; esac build_libtool_libs=no build_old_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do arg=$1 shift func_quote_for_eval "$arg" qarg=$func_quote_for_eval_unquoted_result func_append libtool_args " $func_quote_for_eval_result" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) func_append compile_command " @OUTPUT@" func_append finalize_command " @OUTPUT@" ;; esac case $prev in bindir) bindir=$arg prev= continue ;; dlfiles|dlprefiles) $preload || { # Add the symbol object into the linking commands. func_append compile_command " @SYMFILE@" func_append finalize_command " @SYMFILE@" preload=: } case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test no = "$dlself"; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test dlprefiles = "$prev"; then dlself=yes elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test dlfiles = "$prev"; then func_append dlfiles " $arg" else func_append dlprefiles " $arg" fi prev= continue ;; esac ;; expsyms) export_symbols=$arg test -f "$arg" \ || func_fatal_error "symbol file '$arg' does not exist" prev= continue ;; expsyms_regex) export_symbols_regex=$arg prev= continue ;; framework) case $host in *-*-darwin*) case "$deplibs " in *" $qarg.ltframework "*) ;; *) func_append deplibs " $qarg.ltframework" # this is fixed later ;; esac ;; esac prev= continue ;; inst_prefix) inst_prefix_dir=$arg prev= continue ;; mllvm) # Clang does not use LLVM to link, so we can simply discard any # '-mllvm $arg' options when doing the link step. prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat "$save_arg"` do # func_append moreargs " $fil" arg=$fil # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test none = "$pic_object" && test none = "$non_pic_object"; then func_fatal_error "cannot find name of object for '$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result if test none != "$pic_object"; then # Prepend the subdirectory the object is found in. pic_object=$xdir$pic_object if test dlfiles = "$prev"; then if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test dlprefiles = "$prev"; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg=$pic_object fi # Non-PIC object. if test none != "$non_pic_object"; then # Prepend the subdirectory the object is found in. non_pic_object=$xdir$non_pic_object # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test none = "$pic_object"; then arg=$non_pic_object fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object=$pic_object func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "'$arg' is not a valid libtool object" fi fi done else func_fatal_error "link input file '$arg' does not exist" fi arg=$save_arg prev= continue ;; os2dllname) os2dllname=$arg prev= continue ;; precious_regex) precious_files_regex=$arg prev= continue ;; release) release=-$arg prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac if test rpath = "$prev"; then case "$rpath " in *" $arg "*) ;; *) func_append rpath " $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) func_append xrpath " $arg" ;; esac fi prev= continue ;; shrext) shrext_cmds=$arg prev= continue ;; weak) func_append weak_libs " $arg" prev= continue ;; xcclinker) func_append linker_flags " $qarg" func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xcompiler) func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xlinker) func_append linker_flags " $qarg" func_append compiler_flags " $wl$qarg" prev= func_append compile_command " $wl$qarg" func_append finalize_command " $wl$qarg" continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n "$prev" prevarg=$arg case $arg in -all-static) if test -n "$link_static_flag"; then # See comment for -static flag below, for more details. func_append compile_command " $link_static_flag" func_append finalize_command " $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. func_fatal_error "'-allow-undefined' must not be used because it is the default" ;; -avoid-version) avoid_version=yes continue ;; -bindir) prev=bindir continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then func_fatal_error "more than one -exported-symbols argument is not allowed" fi if test X-export-symbols = "X$arg"; then prev=expsyms else prev=expsyms_regex fi continue ;; -framework) prev=framework continue ;; -inst-prefix-dir) prev=inst_prefix continue ;; # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* # so, if we see these flags be careful not to treat them like -L -L[A-Z][A-Z]*:*) case $with_gcc/$host in no/*-*-irix* | /*-*-irix*) func_append compile_command " $arg" func_append finalize_command " $arg" ;; esac continue ;; -L*) func_stripname "-L" '' "$arg" if test -z "$func_stripname_result"; then if test "$#" -gt 0; then func_fatal_error "require no space between '-L' and '$1'" else func_fatal_error "need path for '-L' option" fi fi func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` test -z "$absdir" && \ func_fatal_error "cannot determine absolute directory name of '$dir'" dir=$absdir ;; esac case "$deplibs " in *" -L$dir "* | *" $arg "*) # Will only happen for absolute or sysroot arguments ;; *) # Preserve sysroot, but never include relative directories case $dir in [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; *) func_append deplibs " -L$dir" ;; esac func_append lib_search_path " $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; ::) dllsearchpath=$dir;; *) func_append dllsearchpath ":$dir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac continue ;; -l*) if test X-lc = "X$arg" || test X-lm = "X$arg"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) # These systems don't actually have a C or math library (as such) continue ;; *-*-os2*) # These systems don't actually have a C library (as such) test X-lc = "X$arg" && continue ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) # Do not include libc due to us having libc/libc_r. test X-lc = "X$arg" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework func_append deplibs " System.ltframework" continue ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype test X-lc = "X$arg" && continue ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work test X-lc = "X$arg" && continue ;; esac elif test X-lc_r = "X$arg"; then case $host in *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi func_append deplibs " $arg" continue ;; -mllvm) prev=mllvm continue ;; -module) module=yes continue ;; # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. # Darwin uses the -arch flag to determine output architecture. -model|-arch|-isysroot|--sysroot) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" prev=xcompiler continue ;; -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case "$new_inherited_linker_flags " in *" $arg "*) ;; * ) func_append new_inherited_linker_flags " $arg" ;; esac continue ;; -multi_module) single_module=$wl-multi_module continue ;; -no-fast-install) fast_install=no continue ;; -no-install) case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) # The PATH hackery in wrapper scripts is required on Windows # and Darwin in order for the loader to find any dlls it needs. func_warning "'-no-install' is ignored for $host" func_warning "assuming '-no-fast-install' instead" fast_install=no ;; *) no_install=yes ;; esac continue ;; -no-undefined) allow_undefined=no continue ;; -objectlist) prev=objectlist continue ;; -os2dllname) prev=os2dllname continue ;; -o) prev=output ;; -precious-files-regex) prev=precious_regex continue ;; -release) prev=release continue ;; -rpath) prev=rpath continue ;; -R) prev=xrpath continue ;; -R*) func_stripname '-R' '' "$arg" dir=$func_stripname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; =*) func_stripname '=' '' "$dir" dir=$lt_sysroot$func_stripname_result ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac continue ;; -shared) # The effects of -shared are defined in a previous loop. continue ;; -shrext) prev=shrext continue ;; -static | -static-libtool-libs) # The effects of -static are defined in a previous loop. # We used to do the same as -all-static on platforms that # didn't have a PIC flag, but the assumption that the effects # would be equivalent was wrong. It would break on at least # Digital Unix and AIX. continue ;; -thread-safe) thread_safe=yes continue ;; -version-info) prev=vinfo continue ;; -version-number) prev=vinfo vinfo_number=yes continue ;; -weak) prev=weak continue ;; -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result arg= save_ifs=$IFS; IFS=, for flag in $args; do IFS=$save_ifs func_quote_for_eval "$flag" func_append arg " $func_quote_for_eval_result" func_append compiler_flags " $func_quote_for_eval_result" done IFS=$save_ifs func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Wl,*) func_stripname '-Wl,' '' "$arg" args=$func_stripname_result arg= save_ifs=$IFS; IFS=, for flag in $args; do IFS=$save_ifs func_quote_for_eval "$flag" func_append arg " $wl$func_quote_for_eval_result" func_append compiler_flags " $wl$func_quote_for_eval_result" func_append linker_flags " $func_quote_for_eval_result" done IFS=$save_ifs func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; -XCClinker) prev=xcclinker continue ;; # -msg_* for osf cc -msg_*) func_quote_for_eval "$arg" arg=$func_quote_for_eval_result ;; # Flags to be passed through unchanged, with rationale: # -64, -mips[0-9] enable 64-bit mode for the SGI compiler # -r[0-9][0-9]* specify processor for the SGI compiler # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler # +DA*, +DD* enable 64-bit mode for the HP compiler # -q* compiler args for the IBM compiler # -m*, -t[45]*, -txscale* architecture-specific flags for GCC # -F/path path to uninstalled frameworks, gcc on darwin # -p, -pg, --coverage, -fprofile-* profiling flags for GCC # -fstack-protector* stack protector flags for GCC # @file GCC response files # -tp=* Portland pgcc target processor selection # --sysroot=* for sysroot support # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization # -specs=* GCC specs files # -stdlib=* select c++ std lib with clang # -fsanitize=* Clang/GCC memory and address sanitizer -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \ -specs=*|-fsanitize=*) func_quote_for_eval "$arg" arg=$func_quote_for_eval_result func_append compile_command " $arg" func_append finalize_command " $arg" func_append compiler_flags " $arg" continue ;; -Z*) if test os2 = "`expr $host : '.*\(os2\)'`"; then # OS/2 uses -Zxxx to specify OS/2-specific options compiler_flags="$compiler_flags $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case $arg in -Zlinker | -Zstack) prev=xcompiler ;; esac continue else # Otherwise treat like 'Some other compiler flag' below func_quote_for_eval "$arg" arg=$func_quote_for_eval_result fi ;; # Some other compiler flag. -* | +*) func_quote_for_eval "$arg" arg=$func_quote_for_eval_result ;; *.$objext) # A standard object. func_append objs " $arg" ;; *.lo) # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test none = "$pic_object" && test none = "$non_pic_object"; then func_fatal_error "cannot find name of object for '$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result test none = "$pic_object" || { # Prepend the subdirectory the object is found in. pic_object=$xdir$pic_object if test dlfiles = "$prev"; then if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test dlprefiles = "$prev"; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg=$pic_object } # Non-PIC object. if test none != "$non_pic_object"; then # Prepend the subdirectory the object is found in. non_pic_object=$xdir$non_pic_object # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test none = "$pic_object"; then arg=$non_pic_object fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object=$pic_object func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "'$arg' is not a valid libtool object" fi fi ;; *.$libext) # An archive. func_append deplibs " $arg" func_append old_deplibs " $arg" continue ;; *.la) # A libtool-controlled library. func_resolve_sysroot "$arg" if test dlfiles = "$prev"; then # This library was specified with -dlopen. func_append dlfiles " $func_resolve_sysroot_result" prev= elif test dlprefiles = "$prev"; then # The library was specified with -dlpreopen. func_append dlprefiles " $func_resolve_sysroot_result" prev= else func_append deplibs " $func_resolve_sysroot_result" fi continue ;; # Some other compiler argument. *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. func_quote_for_eval "$arg" arg=$func_quote_for_eval_result ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then func_append compile_command " $arg" func_append finalize_command " $arg" fi done # argument parsing loop test -n "$prev" && \ func_fatal_help "the '$prevarg' option requires an argument" if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" func_append compile_command " $arg" func_append finalize_command " $arg" fi oldlibs= # calculate the name of the file, without its directory func_basename "$output" outputname=$func_basename_result libobjs_save=$libobjs if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\` else shlib_search_path= fi eval sys_lib_search_path=\"$sys_lib_search_path_spec\" eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" # Definition is injected by LT_CONFIG during libtool generation. func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH" func_dirname "$output" "/" "" output_objdir=$func_dirname_result$objdir func_to_tool_file "$output_objdir/" tool_output_objdir=$func_to_tool_file_result # Create the object directory. func_mkdir_p "$output_objdir" # Determine the type of output case $output in "") func_fatal_help "you must specify an output file" ;; *.$libext) linkmode=oldlib ;; *.lo | *.$objext) linkmode=obj ;; *.la) linkmode=lib ;; *) linkmode=prog ;; # Anything else should be a program. esac specialdeplibs= libs= # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do if $opt_preserve_dup_deps; then case "$libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append libs " $deplib" done if test lib = "$linkmode"; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps # $postdeps and mark them as special (i.e., whose duplicates are # not to be eliminated). pre_post_deps= if $opt_duplicate_compiler_generated_deps; then for pre_post_dep in $predeps $postdeps; do case "$pre_post_deps " in *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; esac func_append pre_post_deps " $pre_post_dep" done fi pre_post_deps= fi deplibs= newdependency_libs= newlib_search_path= need_relink=no # whether we're linking any uninstalled libtool libraries notinst_deplibs= # not-installed libtool libraries notinst_path= # paths that contain not-installed libtool libraries case $linkmode in lib) passes="conv dlpreopen link" for file in $dlfiles $dlprefiles; do case $file in *.la) ;; *) func_fatal_help "libraries can '-dlopen' only libtool libraries: $file" ;; esac done ;; prog) compile_deplibs= finalize_deplibs= alldeplibs=false newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" ;; *) passes="conv" ;; esac for pass in $passes; do # The preopen pass in lib mode reverses $deplibs; put it back here # so that -L comes before libs that need it for instance... if test lib,link = "$linkmode,$pass"; then ## FIXME: Find the place where the list is rebuilt in the wrong ## order, and fix it there properly tmp_deplibs= for deplib in $deplibs; do tmp_deplibs="$deplib $tmp_deplibs" done deplibs=$tmp_deplibs fi if test lib,link = "$linkmode,$pass" || test prog,scan = "$linkmode,$pass"; then libs=$deplibs deplibs= fi if test prog = "$linkmode"; then case $pass in dlopen) libs=$dlfiles ;; dlpreopen) libs=$dlprefiles ;; link) libs="$deplibs %DEPLIBS%" test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" ;; esac fi if test lib,dlpreopen = "$linkmode,$pass"; then # Collect and forward deplibs of preopened libtool libs for lib in $dlprefiles; do # Ignore non-libtool-libs dependency_libs= func_resolve_sysroot "$lib" case $lib in *.la) func_source "$func_resolve_sysroot_result" ;; esac # Collect preopened libtool deplibs, except any this library # has declared as weak libs for deplib in $dependency_libs; do func_basename "$deplib" deplib_base=$func_basename_result case " $weak_libs " in *" $deplib_base "*) ;; *) func_append deplibs " $deplib" ;; esac done done libs=$dlprefiles fi if test dlopen = "$pass"; then # Collect dlpreopened libraries save_deplibs=$deplibs deplibs= fi for deplib in $libs; do lib= found=false case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append compiler_flags " $deplib" if test lib = "$linkmode"; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -l*) if test lib != "$linkmode" && test prog != "$linkmode"; then func_warning "'-l' is ignored for archives/objects" continue fi func_stripname '-l' '' "$deplib" name=$func_stripname_result if test lib = "$linkmode"; then searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" else searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" fi for searchdir in $searchdirs; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library lib=$searchdir/lib$name$search_ext if test -f "$lib"; then if test .la = "$search_ext"; then found=: else found=false fi break 2 fi done done if $found; then # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $deplib "*) if func_lalib_p "$lib"; then library_names= old_library= func_source "$lib" for l in $old_library $library_names; do ll=$l done if test "X$ll" = "X$old_library"; then # only static version available found=false func_dirname "$lib" "" "." ladir=$func_dirname_result lib=$ladir/$old_library if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" fi continue fi fi ;; *) ;; esac fi else # deplib doesn't seem to be a libtool library if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" fi continue fi ;; # -l *.ltframework) if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" if test lib = "$linkmode"; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test conv = "$pass" && continue newdependency_libs="$deplib $newdependency_libs" func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; prog) if test conv = "$pass"; then deplibs="$deplib $deplibs" continue fi if test scan = "$pass"; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; *) func_warning "'-L' is ignored for archives/objects" ;; esac # linkmode continue ;; # -L -R*) if test link = "$pass"; then func_stripname '-R' '' "$deplib" func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) func_resolve_sysroot "$deplib" lib=$func_resolve_sysroot_result ;; *.$libext) if test conv = "$pass"; then deplibs="$deplib $deplibs" continue fi case $linkmode in lib) # Linking convenience modules into shared libraries is allowed, # but linking other static libraries is non-portable. case " $dlpreconveniencelibs " in *" $deplib "*) ;; *) valid_a_lib=false case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then valid_a_lib=: fi ;; pass_all) valid_a_lib=: ;; esac if $valid_a_lib; then echo $ECHO "*** Warning: Linking the shared library $output against the" $ECHO "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" else echo $ECHO "*** Warning: Trying to link with static lib archive $deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because the file extensions .$libext of this argument makes me believe" echo "*** that it is just a static archive that I should not use here." fi ;; esac continue ;; prog) if test link != "$pass"; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi continue ;; esac # linkmode ;; # *.$libext *.lo | *.$objext) if test conv = "$pass"; then deplibs="$deplib $deplibs" elif test prog = "$linkmode"; then if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then # If there is no dlopen support or we're linking statically, # we need to preload. func_append newdlprefiles " $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append newdlfiles " $deplib" fi fi continue ;; %DEPLIBS%) alldeplibs=: continue ;; esac # case $deplib $found || test -f "$lib" \ || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'" # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$lib" \ || func_fatal_error "'$lib' is not a valid libtool archive" func_dirname "$lib" "" "." ladir=$func_dirname_result dlname= dlopen= dlpreopen= libdir= library_names= old_library= inherited_linker_flags= # If the library was installed with an old release of libtool, # it will not redefine variables installed, or shouldnotlink installed=yes shouldnotlink=no avoidtemprpath= # Read the .la file func_source "$lib" # Convert "-framework foo" to "foo.ltframework" if test -n "$inherited_linker_flags"; then tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do case " $new_inherited_linker_flags " in *" $tmp_inherited_linker_flag "*) ;; *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; esac done fi dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` if test lib,link = "$linkmode,$pass" || test prog,scan = "$linkmode,$pass" || { test prog != "$linkmode" && test lib != "$linkmode"; }; then test -n "$dlopen" && func_append dlfiles " $dlopen" test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" fi if test conv = "$pass"; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then func_fatal_error "cannot find name of link library for '$lib'" fi # It is a libtool convenience library, so add in its objects. func_append convenience " $ladir/$objdir/$old_library" func_append old_convenience " $ladir/$objdir/$old_library" tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done elif test prog != "$linkmode" && test lib != "$linkmode"; then func_fatal_error "'$lib' is not a convenience library" fi continue fi # $pass = conv # Get the name of the library we link against. linklib= if test -n "$old_library" && { test yes = "$prefer_static_libs" || test built,no = "$prefer_static_libs,$installed"; }; then linklib=$old_library else for l in $old_library $library_names; do linklib=$l done fi if test -z "$linklib"; then func_fatal_error "cannot find name of link library for '$lib'" fi # This library was specified with -dlopen. if test dlopen = "$pass"; then test -z "$libdir" \ && func_fatal_error "cannot -dlopen a convenience library: '$lib'" if test -z "$dlname" || test yes != "$dlopen_support" || test no = "$build_libtool_libs" then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't # bomb out in the load deplibs phase. func_append dlprefiles " $lib $dependency_libs" else func_append newdlfiles " $lib" fi continue fi # $pass = dlopen # We need an absolute path. case $ladir in [\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then func_warning "cannot determine absolute directory name of '$ladir'" func_warning "passing it literally to the linker, although it might fail" abs_ladir=$ladir fi ;; esac func_basename "$lib" laname=$func_basename_result # Find the relevant object directory and library name. if test yes = "$installed"; then if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then func_warning "library '$lib' was moved." dir=$ladir absdir=$abs_ladir libdir=$abs_ladir else dir=$lt_sysroot$libdir absdir=$lt_sysroot$libdir fi test yes = "$hardcode_automatic" && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then dir=$ladir absdir=$abs_ladir # Remove this search path later func_append notinst_path " $abs_ladir" else dir=$ladir/$objdir absdir=$abs_ladir/$objdir # Remove this search path later func_append notinst_path " $abs_ladir" fi fi # $installed = yes func_stripname 'lib' '.la' "$laname" name=$func_stripname_result # This library was specified with -dlpreopen. if test dlpreopen = "$pass"; then if test -z "$libdir" && test prog = "$linkmode"; then func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'" fi case $host in # special handling for platforms with PE-DLLs. *cygwin* | *mingw* | *cegcc* ) # Linker will automatically link against shared library if both # static and shared are present. Therefore, ensure we extract # symbols from the import library if a shared library is present # (otherwise, the dlopen module name will be incorrect). We do # this by putting the import library name into $newdlprefiles. # We recover the dlopen module name by 'saving' the la file # name in a special purpose variable, and (later) extracting the # dlname from the la file. if test -n "$dlname"; then func_tr_sh "$dir/$linklib" eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" func_append newdlprefiles " $dir/$linklib" else func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" fi ;; * ) # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then func_append newdlprefiles " $dir/$dlname" else func_append newdlprefiles " $dir/$linklib" fi ;; esac fi # $pass = dlpreopen if test -z "$libdir"; then # Link the convenience library if test lib = "$linkmode"; then deplibs="$dir/$old_library $deplibs" elif test prog,link = "$linkmode,$pass"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else deplibs="$lib $deplibs" # used for prog,scan pass fi continue fi if test prog = "$linkmode" && test link != "$pass"; then func_append newlib_search_path " $ladir" deplibs="$lib $deplibs" linkalldeplibs=false if test no != "$link_all_deplibs" || test -z "$library_names" || test no = "$build_libtool_libs"; then linkalldeplibs=: fi tmp_libs= for deplib in $dependency_libs; do case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; esac # Need to link against all dependency_libs? if $linkalldeplibs; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done # for deplib continue fi # $linkmode = prog... if test prog,link = "$linkmode,$pass"; then if test -n "$library_names" && { { test no = "$prefer_static_libs" || test built,yes = "$prefer_static_libs,$installed"; } || test -z "$old_library"; }; then # We need to hardcode the library path if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then # Make sure the rpath contains only unique directories. case $temp_rpath: in *"$absdir:"*) ;; *) func_append temp_rpath "$absdir:" ;; esac fi # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi # $linkmode,$pass = prog,link... if $alldeplibs && { test pass_all = "$deplibs_check_method" || { test yes = "$build_libtool_libs" && test -n "$library_names"; }; }; then # We only need to search for static libraries continue fi fi link_static=no # Whether the deplib will be linked statically use_static_libs=$prefer_static_libs if test built = "$use_static_libs" && test yes = "$installed"; then use_static_libs=no fi if test -n "$library_names" && { test no = "$use_static_libs" || test -z "$old_library"; }; then case $host in *cygwin* | *mingw* | *cegcc* | *os2*) # No point in relinking DLLs because paths are not encoded func_append notinst_deplibs " $lib" need_relink=no ;; *) if test no = "$installed"; then func_append notinst_deplibs " $lib" need_relink=yes fi ;; esac # This is a shared library # Warn about portability, can't link against -module's on some # systems (darwin). Don't bleat about dlopened modules though! dlopenmodule= for dlpremoduletest in $dlprefiles; do if test "X$dlpremoduletest" = "X$lib"; then dlopenmodule=$dlpremoduletest break fi done if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then echo if test prog = "$linkmode"; then $ECHO "*** Warning: Linking the executable $output against the loadable module" else $ECHO "*** Warning: Linking the shared library $output against the loadable module" fi $ECHO "*** $linklib is not portable!" fi if test lib = "$linkmode" && test yes = "$hardcode_into_libs"; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi if test -n "$old_archive_from_expsyms_cmds"; then # figure out the soname set dummy $library_names shift realname=$1 shift libname=`eval "\\$ECHO \"$libname_spec\""` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then soname=$dlname elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin* | mingw* | *cegcc* | *os2*) func_arith $current - $age major=$func_arith_result versuffix=-$major ;; esac eval soname=\"$soname_spec\" else soname=$realname fi # Make a new name for the extract_expsyms_cmds to use soroot=$soname func_basename "$soroot" soname=$func_basename_result func_stripname 'lib' '.dll' "$soname" newlib=libimp-$func_stripname_result.a # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else func_verbose "extracting exported symbol list from '$soname'" func_execute_cmds "$extract_expsyms_cmds" 'exit $?' fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else func_verbose "generating import library for '$soname'" func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' fi # make sure the library variables are pointing to the new library dir=$output_objdir linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" if test prog = "$linkmode" || test relink != "$opt_mode"; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) if test no = "$hardcode_direct"; then add=$dir/$linklib case $host in *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;; *-*-sysv4*uw2*) add_dir=-L$dir ;; *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ *-*-unixware7*) add_dir=-L$dir ;; *-*-darwin* ) # if the lib is a (non-dlopened) module then we cannot # link against it, someone is ignoring the earlier warnings if /usr/bin/file -L $add 2> /dev/null | $GREP ": [^:]* bundle" >/dev/null; then if test "X$dlopenmodule" != "X$lib"; then $ECHO "*** Warning: lib $linklib is a module, not a shared library" if test -z "$old_library"; then echo echo "*** And there doesn't seem to be a static archive available" echo "*** The link will probably fail, sorry" else add=$dir/$old_library fi elif test -n "$old_library"; then add=$dir/$old_library fi fi esac elif test no = "$hardcode_minus_L"; then case $host in *-*-sunos*) add_shlibpath=$dir ;; esac add_dir=-L$dir add=-l$name elif test no = "$hardcode_shlibpath_var"; then add_shlibpath=$dir add=-l$name else lib_linked=no fi ;; relink) if test yes = "$hardcode_direct" && test no = "$hardcode_direct_absolute"; then add=$dir/$linklib elif test yes = "$hardcode_minus_L"; then add_dir=-L$absdir # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add=-l$name elif test yes = "$hardcode_shlibpath_var"; then add_shlibpath=$dir add=-l$name else lib_linked=no fi ;; *) lib_linked=no ;; esac if test yes != "$lib_linked"; then func_fatal_configuration "unsupported hardcode properties" fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) func_append compile_shlibpath "$add_shlibpath:" ;; esac fi if test prog = "$linkmode"; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" if test yes != "$hardcode_direct" && test yes != "$hardcode_minus_L" && test yes = "$hardcode_shlibpath_var"; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac fi fi fi if test prog = "$linkmode" || test relink = "$opt_mode"; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test yes = "$hardcode_direct" && test no = "$hardcode_direct_absolute"; then add=$libdir/$linklib elif test yes = "$hardcode_minus_L"; then add_dir=-L$libdir add=-l$name elif test yes = "$hardcode_shlibpath_var"; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac add=-l$name elif test yes = "$hardcode_automatic"; then if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib"; then add=$inst_prefix_dir$libdir/$linklib else add=$libdir/$linklib fi else # We cannot seem to hardcode it, guess we'll fake it. add_dir=-L$libdir # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add=-l$name fi if test prog = "$linkmode"; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" fi fi elif test prog = "$linkmode"; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. if test unsupported != "$hardcode_direct"; then test -n "$old_library" && linklib=$old_library compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi elif test yes = "$build_libtool_libs"; then # Not a shared library if test pass_all != "$deplibs_check_method"; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. echo $ECHO "*** Warning: This system cannot link to static lib archive $lib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have." if test yes = "$module"; then echo "*** But as you try to build a module library, libtool will still create " echo "*** a static module, that should work as long as the dlopening application" echo "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using 'nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** 'nm' from GNU binutils and a full rebuild may help." fi if test no = "$build_old_libs"; then build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi else deplibs="$dir/$old_library $deplibs" link_static=yes fi fi # link shared/static library? if test lib = "$linkmode"; then if test -n "$dependency_libs" && { test yes != "$hardcode_into_libs" || test yes = "$build_old_libs" || test yes = "$link_static"; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do case $libdir in -R*) func_stripname '-R' '' "$libdir" temp_xrpath=$func_stripname_result case " $xrpath " in *" $temp_xrpath "*) ;; *) func_append xrpath " $temp_xrpath";; esac;; *) func_append temp_deplibs " $libdir";; esac done dependency_libs=$temp_deplibs fi func_append newlib_search_path " $absdir" # Link against this library test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do newdependency_libs="$deplib $newdependency_libs" case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result";; *) func_resolve_sysroot "$deplib" ;; esac if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $func_resolve_sysroot_result "*) func_append specialdeplibs " $func_resolve_sysroot_result" ;; esac fi func_append tmp_libs " $func_resolve_sysroot_result" done if test no != "$link_all_deplibs"; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do path= case $deplib in -L*) path=$deplib ;; *.la) func_resolve_sysroot "$deplib" deplib=$func_resolve_sysroot_result func_dirname "$deplib" "" "." dir=$func_dirname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then func_warning "cannot determine absolute directory name of '$dir'" absdir=$dir fi ;; esac if $GREP "^installed=no" $deplib > /dev/null; then case $host in *-*-darwin*) depdepl= eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` if test -n "$deplibrary_names"; then for tmp in $deplibrary_names; do depdepl=$tmp done if test -f "$absdir/$objdir/$depdepl"; then depdepl=$absdir/$objdir/$depdepl darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` if test -z "$darwin_install_name"; then darwin_install_name=`$OTOOL64 -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` fi func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl" func_append linker_flags " -dylib_file $darwin_install_name:$depdepl" path= fi fi ;; *) path=-L$absdir/$objdir ;; esac else eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "'$deplib' is not a valid libtool archive" test "$absdir" != "$libdir" && \ func_warning "'$deplib' seems to be moved" path=-L$absdir fi ;; esac case " $deplibs " in *" $path "*) ;; *) deplibs="$path $deplibs" ;; esac done fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs if test link = "$pass"; then if test prog = "$linkmode"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" else compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` fi fi dependency_libs=$newdependency_libs if test dlpreopen = "$pass"; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi if test dlopen != "$pass"; then test conv = "$pass" || { # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do case "$lib_search_path " in *" $dir "*) ;; *) func_append lib_search_path " $dir" ;; esac done newlib_search_path= } if test prog,link = "$linkmode,$pass"; then vars="compile_deplibs finalize_deplibs" else vars=deplibs fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order eval tmp_libs=\"\$$var\" new_libs= for deplib in $tmp_libs; do # FIXME: Pedantically, this is the right thing to do, so # that some nasty dependency loop isn't accidentally # broken: #new_libs="$deplib $new_libs" # Pragmatically, this seems to cause very few problems in # practice: case $deplib in -L*) new_libs="$deplib $new_libs" ;; -R*) ;; *) # And here is the reason: when a library appears more # than once as an explicit dependence of a library, or # is implicitly linked in more than once by the # compiler, it is considered special, and multiple # occurrences thereof are not removed. Compare this # with having the same library being listed as a # dependency of multiple other libraries: in this case, # we know (pedantically, we assume) the library does not # need to be listed more than once, so we keep only the # last copy. This is not always right, but it is rare # enough that we require users that really mean to play # such unportable linking tricks to link the library # using -Wl,-lname, so that libtool does not consider it # for duplicate removal. case " $specialdeplibs " in *" $deplib "*) new_libs="$deplib $new_libs" ;; *) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$deplib $new_libs" ;; esac ;; esac ;; esac done tmp_libs= for deplib in $new_libs; do case $deplib in -L*) case " $tmp_libs " in *" $deplib "*) ;; *) func_append tmp_libs " $deplib" ;; esac ;; *) func_append tmp_libs " $deplib" ;; esac done eval $var=\"$tmp_libs\" done # for var fi # Add Sun CC postdeps if required: test CXX = "$tagname" && { case $host_os in linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 func_suncc_cstd_abi if test no != "$suncc_use_cstd_abi"; then func_append postdeps ' -library=Cstd -library=Crun' fi ;; esac ;; solaris*) func_cc_basename "$CC" case $func_cc_basename_result in CC* | sunCC*) func_suncc_cstd_abi if test no != "$suncc_use_cstd_abi"; then func_append postdeps ' -library=Cstd -library=Crun' fi ;; esac ;; esac } # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= for i in $dependency_libs; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) i= ;; esac if test -n "$i"; then func_append tmp_libs " $i" fi done dependency_libs=$tmp_libs done # for pass if test prog = "$linkmode"; then dlfiles=$newdlfiles fi if test prog = "$linkmode" || test lib = "$linkmode"; then dlprefiles=$newdlprefiles fi case $linkmode in oldlib) if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then func_warning "'-dlopen' is ignored for archives" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "'-l' and '-L' are ignored for archives" ;; esac test -n "$rpath" && \ func_warning "'-rpath' is ignored for archives" test -n "$xrpath" && \ func_warning "'-R' is ignored for archives" test -n "$vinfo" && \ func_warning "'-version-info/-version-number' is ignored for archives" test -n "$release" && \ func_warning "'-release' is ignored for archives" test -n "$export_symbols$export_symbols_regex" && \ func_warning "'-export-symbols' is ignored for archives" # Now set the variables for building old libraries. build_libtool_libs=no oldlibs=$output func_append objs "$old_deplibs" ;; lib) # Make sure we only generate libraries of the form 'libNAME.la'. case $outputname in lib*) func_stripname 'lib' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" ;; *) test no = "$module" \ && func_fatal_help "libtool library '$output' must begin with 'lib'" if test no != "$need_lib_prefix"; then # Add the "lib" prefix for modules if required func_stripname '' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" else func_stripname '' '.la' "$outputname" libname=$func_stripname_result fi ;; esac if test -n "$objs"; then if test pass_all != "$deplibs_check_method"; then func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs" else echo $ECHO "*** Warning: Linking the shared library $output against the non-libtool" $ECHO "*** objects $objs is not portable!" func_append libobjs " $objs" fi fi test no = "$dlself" \ || func_warning "'-dlopen self' is ignored for libtool libraries" set dummy $rpath shift test 1 -lt "$#" \ && func_warning "ignoring multiple '-rpath's for a libtool library" install_libdir=$1 oldlibs= if test -z "$rpath"; then if test yes = "$build_libtool_libs"; then # Building a libtool convenience library. # Some compilers have problems with a '.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" build_libtool_libs=convenience build_old_libs=yes fi test -n "$vinfo" && \ func_warning "'-version-info/-version-number' is ignored for convenience libraries" test -n "$release" && \ func_warning "'-release' is ignored for convenience libraries" else # Parse the version information argument. save_ifs=$IFS; IFS=: set dummy $vinfo 0 0 0 shift IFS=$save_ifs test -n "$7" && \ func_fatal_help "too many parameters to '-version-info'" # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts # to make the code below a bit more comprehensible case $vinfo_number in yes) number_major=$1 number_minor=$2 number_revision=$3 # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix # that has an extra 1 added just for fun # case $version_type in # correct linux to gnu/linux during the next big refactor darwin|freebsd-elf|linux|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result age=$number_minor revision=$number_revision ;; freebsd-aout|qnx|sunos) current=$number_major revision=$number_minor age=0 ;; irix|nonstopux) func_arith $number_major + $number_minor current=$func_arith_result age=$number_minor revision=$number_minor lt_irix_increment=no ;; *) func_fatal_configuration "$modename: unknown library version type '$version_type'" ;; esac ;; no) current=$1 revision=$2 age=$3 ;; esac # Check that each of the things are valid numbers. case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "CURRENT '$current' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "REVISION '$revision' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "AGE '$age' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac if test "$age" -gt "$current"; then func_error "AGE '$age' is greater than the current interface number '$current'" func_fatal_error "'$vinfo' is not valid version information" fi # Calculate the version variables. major= versuffix= verstring= case $version_type in none) ;; darwin) # Like Linux, but with the current version available in # verstring for coding it into the library header func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision # Darwin ld doesn't like 0 for these options... func_arith $current + 1 minor_current=$func_arith_result xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" # On Darwin other compilers case $CC in nagfor*) verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" ;; *) verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" ;; esac ;; freebsd-aout) major=.$current versuffix=.$current.$revision ;; freebsd-elf) func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision ;; irix | nonstopux) if test no = "$lt_irix_increment"; then func_arith $current - $age else func_arith $current - $age + 1 fi major=$func_arith_result case $version_type in nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac verstring=$verstring_prefix$major.$revision # Add in all the interfaces that we are compatible with. loop=$revision while test 0 -ne "$loop"; do func_arith $revision - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring=$verstring_prefix$major.$iface:$verstring done # Before this point, $major must not contain '.'. major=.$major versuffix=$major.$revision ;; linux) # correct to gnu/linux during the next big refactor func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision ;; osf) func_arith $current - $age major=.$func_arith_result versuffix=.$current.$age.$revision verstring=$current.$age.$revision # Add in all the interfaces that we are compatible with. loop=$age while test 0 -ne "$loop"; do func_arith $current - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring=$verstring:$iface.0 done # Make executables depend on our current version. func_append verstring ":$current.0" ;; qnx) major=.$current versuffix=.$current ;; sco) major=.$current versuffix=.$current ;; sunos) major=.$current versuffix=.$current.$revision ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 file systems. func_arith $current - $age major=$func_arith_result versuffix=-$major ;; *) func_fatal_configuration "unknown library version type '$version_type'" ;; esac # Clear the version info if we defaulted, and they specified a release. if test -z "$vinfo" && test -n "$release"; then major= case $version_type in darwin) # we can't check for "0.0" in archive_cmds due to quoting # problems, so we reset it completely verstring= ;; *) verstring=0.0 ;; esac if test no = "$need_version"; then versuffix= else versuffix=.0.0 fi fi # Remove version info from name if versioning should be avoided if test yes,no = "$avoid_version,$need_version"; then major= versuffix= verstring= fi # Check to see if the archive will have undefined symbols. if test yes = "$allow_undefined"; then if test unsupported = "$allow_undefined_flag"; then if test yes = "$build_old_libs"; then func_warning "undefined symbols not allowed in $host shared libraries; building static only" build_libtool_libs=no else func_fatal_error "can't build $host shared library unless -no-undefined is specified" fi fi else # Don't allow undefined symbols. allow_undefined_flag=$no_undefined_flag fi fi func_generate_dlsyms "$libname" "$libname" : func_append libobjs " $symfileobj" test " " = "$libobjs" && libobjs= if test relink != "$opt_mode"; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= tempremovelist=`$ECHO "$output_objdir/*"` for p in $tempremovelist; do case $p in *.$objext | *.gcno) ;; $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*) if test -n "$precious_files_regex"; then if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue fi fi func_append removelist " $p" ;; *) ;; esac done test -n "$removelist" && \ func_show_eval "${RM}r \$removelist" fi # Now set the variables for building old libraries. if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then func_append oldlibs " $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP` fi # Eliminate all temporary directories. #for path in $notinst_path; do # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` #done if test -n "$xrpath"; then # If the user specified any rpath flags, then add them. temp_xrpath= for libdir in $xrpath; do func_replace_sysroot "$libdir" func_append temp_xrpath " -R$func_replace_sysroot_result" case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened old_dlfiles=$dlfiles dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in *" $lib "*) ;; *) func_append dlfiles " $lib" ;; esac done # Make sure dlprefiles contains only unique files old_dlprefiles=$dlprefiles dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in *" $lib "*) ;; *) func_append dlprefiles " $lib" ;; esac done if test yes = "$build_libtool_libs"; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework func_append deplibs " System.ltframework" ;; *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work ;; *) # Add libc to deplibs on all other systems if necessary. if test yes = "$build_libtool_need_lc"; then func_append deplibs " -lc" fi ;; esac fi # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname release_save=$release versuffix_save=$versuffix major_save=$major # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? release= versuffix= major= newdeplibs= droppeddeps=no case $deplibs_check_method in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check # whether the library exists or not. But this is on # osf3 & osf4 and I'm not really sure... Just # implementing what was already the behavior. newdeplibs=$deplibs ;; test_compile) # This code stresses the "libraries are programs" paradigm to its # limits. Maybe even breaks it. We compile a program, linking it # against the deplibs as a proxy for the library. Then we can check # whether they linked in statically or dynamically with ldd. $opt_dry_run || $RM conftest.c cat > conftest.c </dev/null` $nocaseglob else potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` fi for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null | $GREP " -> " >/dev/null; then continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? potlib=$potent_lib while test -h "$potlib" 2>/dev/null; do potliblink=`ls -ld $potlib | $SED 's/.* -> //'` case $potliblink in [\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;; *) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | $SED -e 10q | $EGREP "$file_magic_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib= break 2 fi done done fi if test -n "$a_deplib"; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib"; then $ECHO "*** with $libname but no candidates were found. (...for file magic test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a file magic. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` for a_deplib in $deplibs; do case $a_deplib in -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $a_deplib "*) func_append newdeplibs " $a_deplib" a_deplib= ;; esac fi if test -n "$a_deplib"; then libname=`eval "\\$ECHO \"$libname_spec\""` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do potlib=$potent_lib # see symlink-check above in file_magic test if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ $EGREP "$match_pattern_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib= break 2 fi done done fi if test -n "$a_deplib"; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib"; then $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a regex pattern. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; none | unknown | *) newdeplibs= tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` if test yes = "$allow_libtool_libs_with_static_runtimes"; then for i in $predeps $postdeps; do # can't use Xsed below, because $i might contain '/' tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"` done fi case $tmp_deplibs in *[!\ \ ]*) echo if test none = "$deplibs_check_method"; then echo "*** Warning: inter-library dependencies are not supported in this platform." else echo "*** Warning: inter-library dependencies are not known to be supported." fi echo "*** All declared inter-library dependencies are being dropped." droppeddeps=yes ;; esac ;; esac versuffix=$versuffix_save major=$major_save release=$release_save libname=$libname_save name=$name_save case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library with the System framework newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac if test yes = "$droppeddeps"; then if test yes = "$module"; then echo echo "*** Warning: libtool could not satisfy all declared inter-library" $ECHO "*** dependencies of module $libname. Therefore, libtool will create" echo "*** a static module, that should work as long as the dlopening" echo "*** application is linked with the -dlopen flag." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using 'nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** 'nm' from GNU binutils and a full rebuild may help." fi if test no = "$build_old_libs"; then oldlibs=$output_objdir/$libname.$libext build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi else echo "*** The inter-library dependencies that have been dropped here will be" echo "*** automatically added whenever a program is linked with this library" echo "*** or is declared to -dlopen it." if test no = "$allow_undefined"; then echo echo "*** Since this library must not contain undefined symbols," echo "*** because either the platform does not support them or" echo "*** it was explicitly requested with -no-undefined," echo "*** libtool will only create a static version of it." if test no = "$build_old_libs"; then oldlibs=$output_objdir/$libname.$libext build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi fi fi # Done checking deplibs! deplibs=$newdeplibs fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" case $host in *-*-darwin*) newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done deplibs=$new_libs # All the library-specific variables (install_libdir is set above). library_names= old_library= dlname= # Test again, we may have decided not to build it any more if test yes = "$build_libtool_libs"; then # Remove $wl instances when linking with ld. # FIXME: should test the right _cmds variable. case $archive_cmds in *\$LD\ *) wl= ;; esac if test yes = "$hardcode_into_libs"; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath=$finalize_rpath test relink = "$opt_mode" || rpath=$compile_rpath$rpath for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then func_replace_sysroot "$libdir" libdir=$func_replace_sysroot_result if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append dep_rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" fi test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi shlibpath=$finalize_shlibpath test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi # Get the real and link names of the library. eval shared_ext=\"$shrext_cmds\" eval library_names=\"$library_names_spec\" set dummy $library_names shift realname=$1 shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else soname=$realname fi if test -z "$dlname"; then dlname=$soname fi lib=$output_objdir/$realname linknames= for link do func_append linknames " $link" done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` test "X$libobjs" = "X " && libobjs= delfiles= if test -n "$export_symbols" && test -n "$include_expsyms"; then $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" export_symbols=$output_objdir/$libname.uexp func_append delfiles " $export_symbols" fi orig_export_symbols= case $host_os in cygwin* | mingw* | cegcc*) if test -n "$export_symbols" && test -z "$export_symbols_regex"; then # exporting using user supplied symfile func_dll_def_p "$export_symbols" || { # and it's NOT already a .def file. Must figure out # which of the given symbols are data symbols and tag # them as such. So, trigger use of export_symbols_cmds. # export_symbols gets reassigned inside the "prepare # the list of exported symbols" if statement, so the # include_expsyms logic still works. orig_export_symbols=$export_symbols export_symbols= always_export_symbols=yes } fi ;; esac # Prepare the list of exported symbols if test -z "$export_symbols"; then if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then func_verbose "generating symbol list for '$libname.la'" export_symbols=$output_objdir/$libname.exp $opt_dry_run || $RM $export_symbols cmds=$export_symbols_cmds save_ifs=$IFS; IFS='~' for cmd1 in $cmds; do IFS=$save_ifs # Take the normal branch if the nm_file_list_spec branch # doesn't work or if tool conversion is not needed. case $nm_file_list_spec~$to_tool_file_cmd in *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) try_normal_branch=yes eval cmd=\"$cmd1\" func_len " $cmd" len=$func_len_result ;; *) try_normal_branch=no ;; esac if test yes = "$try_normal_branch" \ && { test "$len" -lt "$max_cmd_len" \ || test "$max_cmd_len" -le -1; } then func_show_eval "$cmd" 'exit $?' skipped_export=false elif test -n "$nm_file_list_spec"; then func_basename "$output" output_la=$func_basename_result save_libobjs=$libobjs save_output=$output output=$output_objdir/$output_la.nm func_to_tool_file "$output" libobjs=$nm_file_list_spec$func_to_tool_file_result func_append delfiles " $output" func_verbose "creating $NM input file list: $output" for obj in $save_libobjs; do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > "$output" eval cmd=\"$cmd1\" func_show_eval "$cmd" 'exit $?' output=$save_output libobjs=$save_libobjs skipped_export=false else # The command line is too long to execute in one step. func_verbose "using reloadable object file for export list..." skipped_export=: # Break out early, otherwise skipped_export may be # set to false by a later but shorter cmd. break fi done IFS=$save_ifs if test -n "$export_symbols_regex" && test : != "$skipped_export"; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols=$export_symbols test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test : != "$skipped_export" && test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for '$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands, which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi tmp_deplibs= for test_deplib in $deplibs; do case " $convenience " in *" $test_deplib "*) ;; *) func_append tmp_deplibs " $test_deplib" ;; esac done deplibs=$tmp_deplibs if test -n "$convenience"; then if test -n "$whole_archive_flag_spec" && test yes = "$compiler_needs_object" && test -z "$libobjs"; then # extract the archives, so we have objects to list. # TODO: could optimize this to just extract one archive. whole_archive_flag_spec= fi if test -n "$whole_archive_flag_spec"; then save_libobjs=$libobjs eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= else gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $convenience func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi fi if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" func_append linker_flags " $flag" fi # Make a backup of the uninstalled library when relinking if test relink = "$opt_mode"; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? fi # Do each of the archive commands. if test yes = "$module" && test -n "$module_cmds"; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds else eval test_cmds=\"$module_cmds\" cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval test_cmds=\"$archive_expsym_cmds\" cmds=$archive_expsym_cmds else eval test_cmds=\"$archive_cmds\" cmds=$archive_cmds fi fi if test : != "$skipped_export" && func_len " $test_cmds" && len=$func_len_result && test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise # or, if using GNU ld and skipped_export is not :, use a linker # script. # Save the value of $output and $libobjs because we want to # use them later. If we have whole_archive_flag_spec, we # want to use save_libobjs as it was before # whole_archive_flag_spec was expanded, because we can't # assume the linker understands whole_archive_flag_spec. # This may have to be revisited, in case too many # convenience libraries get linked in and end up exceeding # the spec. if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then save_libobjs=$libobjs fi save_output=$output func_basename "$output" output_la=$func_basename_result # Clear the reloadable object creation command queue and # initialize k to one. test_cmds= concat_cmds= objlist= last_robj= k=1 if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then output=$output_objdir/$output_la.lnkscript func_verbose "creating GNU ld script: $output" echo 'INPUT (' > $output for obj in $save_libobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done echo ')' >> $output func_append delfiles " $output" func_to_tool_file "$output" output=$func_to_tool_file_result elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then output=$output_objdir/$output_la.lnk func_verbose "creating linker input file list: $output" : > $output set x $save_libobjs shift firstobj= if test yes = "$compiler_needs_object"; then firstobj="$1 " shift fi for obj do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done func_append delfiles " $output" func_to_tool_file "$output" output=$firstobj\"$file_list_spec$func_to_tool_file_result\" else if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." output=$output_objdir/$output_la-$k.$objext eval test_cmds=\"$reload_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 # Loop over the list of objects to be linked. for obj in $save_libobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result if test -z "$objlist" || test "$len" -lt "$max_cmd_len"; then func_append objlist " $obj" else # The command $test_cmds is almost too long, add a # command to the queue. if test 1 -eq "$k"; then # The first file doesn't have a previous command to add. reload_objs=$objlist eval concat_cmds=\"$reload_cmds\" else # All subsequent reloadable object files will link in # the last one created. reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" fi last_robj=$output_objdir/$output_la-$k.$objext func_arith $k + 1 k=$func_arith_result output=$output_objdir/$output_la-$k.$objext objlist=" $obj" func_len " $last_robj" func_arith $len0 + $func_len_result len=$func_arith_result fi done # Handle the remaining objects by creating one last # reloadable object file. All subsequent reloadable object # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds$reload_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi func_append delfiles " $output" else output= fi ${skipped_export-false} && { func_verbose "generating symbol list for '$libname.la'" export_symbols=$output_objdir/$libname.exp $opt_dry_run || $RM $export_symbols libobjs=$output # Append the command to create the export file. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi } test -n "$save_libobjs" && func_verbose "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. save_ifs=$IFS; IFS='~' for cmd in $concat_cmds; do IFS=$save_ifs $opt_quiet || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test relink = "$opt_mode"; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS=$save_ifs if test -n "$export_symbols_regex" && ${skipped_export-false}; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi ${skipped_export-false} && { if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols=$export_symbols test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for '$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands, which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi } libobjs=$output # Restore the value of output. output=$save_output if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= fi # Expand the library linking commands again to reset the # value of $libobjs for piecewise linking. # Do each of the archive commands. if test yes = "$module" && test -n "$module_cmds"; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then cmds=$archive_expsym_cmds else cmds=$archive_cmds fi fi fi if test -n "$delfiles"; then # Append the command to remove temporary files to $cmds. eval cmds=\"\$cmds~\$RM $delfiles\" fi # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi save_ifs=$IFS; IFS='~' for cmd in $cmds; do IFS=$sp$nl eval cmd=\"$cmd\" IFS=$save_ifs $opt_quiet || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test relink = "$opt_mode"; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS=$save_ifs # Restore the uninstalled library and exit if test relink = "$opt_mode"; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? if test -n "$convenience"; then if test -z "$whole_archive_flag_spec"; then func_show_eval '${RM}r "$gentop"' fi fi exit $EXIT_SUCCESS fi # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' fi done # If -module or -export-dynamic was specified, set the dlname. if test yes = "$module" || test yes = "$export_dynamic"; then # On all known operating systems, these are identical. dlname=$soname fi fi ;; obj) if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then func_warning "'-dlopen' is ignored for objects" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "'-l' and '-L' are ignored for objects" ;; esac test -n "$rpath" && \ func_warning "'-rpath' is ignored for objects" test -n "$xrpath" && \ func_warning "'-R' is ignored for objects" test -n "$vinfo" && \ func_warning "'-version-info' is ignored for objects" test -n "$release" && \ func_warning "'-release' is ignored for objects" case $output in *.lo) test -n "$objs$old_deplibs" && \ func_fatal_error "cannot build library object '$output' from non-libtool objects" libobj=$output func_lo2o "$libobj" obj=$func_lo2o_result ;; *) libobj= obj=$output ;; esac # Delete the old objects. $opt_dry_run || $RM $obj $libobj # Objects from convenience libraries. This assumes # single-version convenience libraries. Whenever we create # different ones for PIC/non-PIC, this we'll have to duplicate # the extraction. reload_conv_objs= gentop= # if reload_cmds runs $LD directly, get rid of -Wl from # whole_archive_flag_spec and hope we can get by with turning comma # into space. case $reload_cmds in *\$LD[\ \$]*) wl= ;; esac if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags else gentop=$output_objdir/${obj}x func_append generated " $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi # If we're not building shared, we need to use non_pic_objs test yes = "$build_libtool_libs" || libobjs=$non_pic_objects # Create the old-style object. reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs output=$obj func_execute_cmds "$reload_cmds" 'exit $?' # Exit if we aren't doing a library object file. if test -z "$libobj"; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS fi test yes = "$build_libtool_libs" || { if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi # Create an invalid libtool object if no PIC, so that we don't # accidentally link it into a program. # $show "echo timestamp > $libobj" # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS } if test -n "$pic_flag" || test default != "$pic_mode"; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" output=$libobj func_execute_cmds "$reload_cmds" 'exit $?' fi if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS ;; prog) case $host in *cygwin*) func_stripname '' '.exe' "$output" output=$func_stripname_result.exe;; esac test -n "$vinfo" && \ func_warning "'-version-info' is ignored for programs" test -n "$release" && \ func_warning "'-release' is ignored for programs" $preload \ && test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \ && func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support." case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac case $host in *-*-darwin*) # Don't allow lazy linking, it breaks C++ global constructors # But is supposedly fixed on 10.4 or later (yay!). if test CXX = "$tagname"; then case ${MACOSX_DEPLOYMENT_TARGET-10.0} in 10.[0123]) func_append compile_command " $wl-bind_at_load" func_append finalize_command " $wl-bind_at_load" ;; esac fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $compile_deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $compile_deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done compile_deplibs=$new_libs func_append compile_command " $compile_deplibs" func_append finalize_command " $finalize_deplibs" if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done fi # Now hardcode the library paths rpath= hardcode_libdirs= for libdir in $compile_rpath $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$libdir:"*) ;; ::) dllsearchpath=$libdir;; *) func_append dllsearchpath ":$libdir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval rpath=\" $hardcode_libdir_flag_spec\" fi compile_rpath=$rpath rpath= hardcode_libdirs= for libdir in $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) func_append finalize_perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval rpath=\" $hardcode_libdir_flag_spec\" fi finalize_rpath=$rpath if test -n "$libobjs" && test yes = "$build_old_libs"; then # Transform all the library objects into standard objects. compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` fi func_generate_dlsyms "$outputname" "@PROGRAM@" false # template prelinking step if test -n "$prelink_cmds"; then func_execute_cmds "$prelink_cmds" 'exit $?' fi wrappers_required=: case $host in *cegcc* | *mingw32ce*) # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. wrappers_required=false ;; *cygwin* | *mingw* ) test yes = "$build_libtool_libs" || wrappers_required=false ;; *) if test no = "$need_relink" || test yes != "$build_libtool_libs"; then wrappers_required=false fi ;; esac $wrappers_required || { # Replace the output file specification. compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` link_command=$compile_command$compile_rpath # We have no uninstalled library dependencies, so finalize right now. exit_status=0 func_show_eval "$link_command" 'exit_status=$?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Delete the generated files. if test -f "$output_objdir/${outputname}S.$objext"; then func_show_eval '$RM "$output_objdir/${outputname}S.$objext"' fi exit $exit_status } if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" fi if test -n "$finalize_shlibpath"; then finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" fi compile_var= finalize_var= if test -n "$runpath_var"; then if test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi if test -n "$finalize_perm_rpath"; then # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do func_append rpath "$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test yes = "$no_install"; then # We don't need to create a wrapper script. link_command=$compile_var$compile_command$compile_rpath # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. $opt_dry_run || $RM $output # Link the executable and exit func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi exit $EXIT_SUCCESS fi case $hardcode_action,$fast_install in relink,*) # Fast installation is not supported link_command=$compile_var$compile_command$compile_rpath relink_command=$finalize_var$finalize_command$finalize_rpath func_warning "this platform does not like uninstalled shared libraries" func_warning "'$output' will be relinked during installation" ;; *,yes) link_command=$finalize_var$compile_command$finalize_rpath relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` ;; *,no) link_command=$compile_var$compile_command$compile_rpath relink_command=$finalize_var$finalize_command$finalize_rpath ;; *,needless) link_command=$finalize_var$compile_command$finalize_rpath relink_command= ;; esac # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output_objdir/$outputname" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Now create the wrapper script. func_verbose "creating $output" # Quote the relink command for shipping. if test -n "$relink_command"; then # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done relink_command="(cd `pwd`; $relink_command)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` fi # Only actually do things if not in dry run mode. $opt_dry_run || { # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) func_stripname '' '.exe' "$output" output=$func_stripname_result ;; esac # test for cygwin because mv fails w/o .exe extensions case $host in *cygwin*) exeext=.exe func_stripname '' '.exe' "$outputname" outputname=$func_stripname_result ;; *) exeext= ;; esac case $host in *cygwin* | *mingw* ) func_dirname_and_basename "$output" "" "." output_name=$func_basename_result output_path=$func_dirname_result cwrappersource=$output_path/$objdir/lt-$output_name.c cwrapper=$output_path/$output_name.exe $RM $cwrappersource $cwrapper trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 func_emit_cwrapperexe_src > $cwrappersource # The wrapper executable is built using the $host compiler, # because it contains $host paths and files. If cross- # compiling, it, like the target executable, must be # executed on the $host or under an emulation environment. $opt_dry_run || { $LTCC $LTCFLAGS -o $cwrapper $cwrappersource $STRIP $cwrapper } # Now, create the wrapper script for func_source use: func_ltwrapper_scriptname $cwrapper $RM $func_ltwrapper_scriptname_result trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 $opt_dry_run || { # note: this script will not be executed, so do not chmod. if test "x$build" = "x$host"; then $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result else func_emit_wrapper no > $func_ltwrapper_scriptname_result fi } ;; * ) $RM $output trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 func_emit_wrapper no > $output chmod +x $output ;; esac } exit $EXIT_SUCCESS ;; esac # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do case $build_libtool_libs in convenience) oldobjs="$libobjs_save $symfileobj" addlibs=$convenience build_libtool_libs=no ;; module) oldobjs=$libobjs_save addlibs=$old_convenience build_libtool_libs=no ;; *) oldobjs="$old_deplibs $non_pic_objects" $preload && test -f "$symfileobj" \ && func_append oldobjs " $symfileobj" addlibs=$old_convenience ;; esac if test -n "$addlibs"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $addlibs func_append oldobjs " $func_extract_archives_result" fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then cmds=$old_archive_from_new_cmds else # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append oldobjs " $func_extract_archives_result" fi # POSIX demands no paths to be encoded in archives. We have # to avoid creating archives with duplicate basenames if we # might have to extract them afterwards, e.g., when creating a # static archive out of a convenience library, or when linking # the entirety of a libtool archive into another (currently # not supported by libtool). if (for obj in $oldobjs do func_basename "$obj" $ECHO "$func_basename_result" done | sort | sort -uc >/dev/null 2>&1); then : else echo "copying selected object files to avoid basename conflicts..." gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_mkdir_p "$gentop" save_oldobjs=$oldobjs oldobjs= counter=1 for obj in $save_oldobjs do func_basename "$obj" objbase=$func_basename_result case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) while :; do # Make sure we don't pick an alternate name that also # overlaps. newobj=lt$counter-$objbase func_arith $counter + 1 counter=$func_arith_result case " $oldobjs " in *[\ /]"$newobj "*) ;; *) if test ! -f "$gentop/$newobj"; then break; fi ;; esac done func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" func_append oldobjs " $gentop/$newobj" ;; *) func_append oldobjs " $obj" ;; esac done fi func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result eval cmds=\"$old_archive_cmds\" func_len " $cmds" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds elif test -n "$archiver_list_spec"; then func_verbose "using command file archive linking..." for obj in $oldobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > $output_objdir/$libname.libcmd func_to_tool_file "$output_objdir/$libname.libcmd" oldobjs=" $archiver_list_spec$func_to_tool_file_result" cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts func_verbose "using piecewise archive linking..." save_RANLIB=$RANLIB RANLIB=: objlist= concat_cmds= save_oldobjs=$oldobjs oldobjs= # Is there a better way of finding the last object in the list? for obj in $save_oldobjs do last_oldobj=$obj done eval test_cmds=\"$old_archive_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 for obj in $save_oldobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result func_append objlist " $obj" if test "$len" -lt "$max_cmd_len"; then : else # the above command should be used before it gets too long oldobjs=$objlist if test "$obj" = "$last_oldobj"; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$old_archive_cmds\" objlist= len=$len0 fi done RANLIB=$save_RANLIB oldobjs=$objlist if test -z "$oldobjs"; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" fi fi fi func_execute_cmds "$cmds" 'exit $?' done test -n "$generated" && \ func_show_eval "${RM}r$generated" # Now create the libtool archive. case $output in *.la) old_library= test yes = "$build_old_libs" && old_library=$libname.$libext func_verbose "creating $output" # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done # Quote the link command for shipping. relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` if test yes = "$hardcode_automatic"; then relink_command= fi # Only create the output if not a dry run. $opt_dry_run || { for installed in no yes; do if test yes = "$installed"; then if test -z "$install_libdir"; then break fi output=$output_objdir/${outputname}i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) func_basename "$deplib" name=$func_basename_result func_resolve_sysroot "$deplib" eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` test -z "$libdir" && \ func_fatal_error "'$deplib' is not a valid libtool archive" func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" ;; -L*) func_stripname -L '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -L$func_replace_sysroot_result" ;; -R*) func_stripname -R '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -R$func_replace_sysroot_result" ;; *) func_append newdependency_libs " $deplib" ;; esac done dependency_libs=$newdependency_libs newdlfiles= for lib in $dlfiles; do case $lib in *.la) func_basename "$lib" name=$func_basename_result eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "'$lib' is not a valid libtool archive" func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" ;; *) func_append newdlfiles " $lib" ;; esac done dlfiles=$newdlfiles newdlprefiles= for lib in $dlprefiles; do case $lib in *.la) # Only pass preopened files to the pseudo-archive (for # eventual linking with the app. that links it) if we # didn't already link the preopened objects directly into # the library: func_basename "$lib" name=$func_basename_result eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "'$lib' is not a valid libtool archive" func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" ;; esac done dlprefiles=$newdlprefiles else newdlfiles= for lib in $dlfiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlfiles " $abs" done dlfiles=$newdlfiles newdlprefiles= for lib in $dlprefiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlprefiles " $abs" done dlprefiles=$newdlprefiles fi $RM $output # place dlname in correct position for cygwin # In fact, it would be nice if we could use this code for all target # systems that can't hard-code library paths into their executables # and that have no shared library path variable independent of PATH, # but it turns out we can't easily determine that from inspecting # libtool variables, so we have to hard-code the OSs to which it # applies here; at the moment, that means platforms that use the PE # object format with DLL files. See the long comment at the top of # tests/bindir.at for full details. tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) # If a -bindir argument was supplied, place the dll there. if test -n "$bindir"; then func_relative_path "$install_libdir" "$bindir" tdlname=$func_relative_path_result/$dlname else # Otherwise fall back on heuristic. tdlname=../bin/$dlname fi ;; esac $ECHO > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM (GNU $PACKAGE) $VERSION # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='$tdlname' # Names of this library. library_names='$library_names' # The name of the static archive. old_library='$old_library' # Linker flags that cannot go in dependency_libs. inherited_linker_flags='$new_inherited_linker_flags' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Names of additional weak libraries provided by this library weak_library_names='$weak_libs' # Version information for $libname. current=$current age=$age revision=$revision # Is this an already installed library? installed=$installed # Should we warn about portability when linking against -modules? shouldnotlink=$module # Files to dlopen/dlpreopen dlopen='$dlfiles' dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" if test no,yes = "$installed,$need_relink"; then $ECHO >> $output "\ relink_command=\"$relink_command\"" fi done } # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' ;; esac exit $EXIT_SUCCESS } if test link = "$opt_mode" || test relink = "$opt_mode"; then func_mode_link ${1+"$@"} fi # func_mode_uninstall arg... func_mode_uninstall () { $debug_cmd RM=$nonopt files= rmforce=false exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic=$magic for arg do case $arg in -f) func_append RM " $arg"; rmforce=: ;; -*) func_append RM " $arg" ;; *) func_append files " $arg" ;; esac done test -z "$RM" && \ func_fatal_help "you must specify an RM program" rmdirs= for file in $files; do func_dirname "$file" "" "." dir=$func_dirname_result if test . = "$dir"; then odir=$objdir else odir=$dir/$objdir fi func_basename "$file" name=$func_basename_result test uninstall = "$opt_mode" && odir=$dir # Remember odir for removal later, being careful to avoid duplicates if test clean = "$opt_mode"; then case " $rmdirs " in *" $odir "*) ;; *) func_append rmdirs " $odir" ;; esac fi # Don't error if the file doesn't exist and rm -f was used. if { test -L "$file"; } >/dev/null 2>&1 || { test -h "$file"; } >/dev/null 2>&1 || test -f "$file"; then : elif test -d "$file"; then exit_status=1 continue elif $rmforce; then continue fi rmfiles=$file case $name in *.la) # Possibly a libtool archive, so verify it. if func_lalib_p "$file"; then func_source $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do func_append rmfiles " $odir/$n" done test -n "$old_library" && func_append rmfiles " $odir/$old_library" case $opt_mode in clean) case " $library_names " in *" $dlname "*) ;; *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; esac test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" ;; uninstall) if test -n "$library_names"; then # Do each command in the postuninstall commands. func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1' fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1' fi # FIXME: should reinstall the best remaining shared library. ;; esac fi ;; *.lo) # Possibly a libtool object, so verify it. if func_lalib_p "$file"; then # Read the .lo file func_source $dir/$name # Add PIC object to the list of files to remove. if test -n "$pic_object" && test none != "$pic_object"; then func_append rmfiles " $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. if test -n "$non_pic_object" && test none != "$non_pic_object"; then func_append rmfiles " $dir/$non_pic_object" fi fi ;; *) if test clean = "$opt_mode"; then noexename=$name case $file in *.exe) func_stripname '' '.exe' "$file" file=$func_stripname_result func_stripname '' '.exe' "$name" noexename=$func_stripname_result # $file with .exe has already been added to rmfiles, # add $file without .exe func_append rmfiles " $file" ;; esac # Do a test to see if this is a libtool program. if func_ltwrapper_p "$file"; then if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" relink_command= func_source $func_ltwrapper_scriptname_result func_append rmfiles " $func_ltwrapper_scriptname_result" else relink_command= func_source $dir/$noexename fi # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles func_append rmfiles " $odir/$name $odir/${name}S.$objext" if test yes = "$fast_install" && test -n "$relink_command"; then func_append rmfiles " $odir/lt-$name" fi if test "X$noexename" != "X$name"; then func_append rmfiles " $odir/lt-$noexename.c" fi fi fi ;; esac func_show_eval "$RM $rmfiles" 'exit_status=1' done # Try to remove the $objdir's in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then func_show_eval "rmdir $dir >/dev/null 2>&1" fi done exit $exit_status } if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then func_mode_uninstall ${1+"$@"} fi test -z "$opt_mode" && { help=$generic_help func_fatal_help "you must specify a MODE" } test -z "$exec_cmd" && \ func_fatal_help "invalid operation mode '$opt_mode'" if test -n "$exec_cmd"; then eval exec "$exec_cmd" exit $EXIT_FAILURE fi exit $exit_status # The TAGs below are defined such that we never get into a situation # where we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support # them. This is particularly important on AIX, because we don't # support having both static and shared libraries enabled at the same # time on that platform, so we default to a shared-only configuration. # If a disable-shared tag is given, we'll fallback to a static-only # configuration. But we'll never go from static-only to shared-only. # ### BEGIN LIBTOOL TAG CONFIG: disable-shared build_libtool_libs=no build_old_libs=yes # ### END LIBTOOL TAG CONFIG: disable-shared # ### BEGIN LIBTOOL TAG CONFIG: disable-static build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: libopenmpt-0.3.6+release.autotools/build-aux/config.guess0000755000372100037210000012564413235362221020503 00000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2016 Free Software Foundation, Inc. timestamp='2016-10-02' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess # # Please send patches to . me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2016 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case "${UNAME_SYSTEM}" in Linux|GNU|GNU/*) # If the system lacks a compiler, then just pick glibc. # We could probably try harder. LIBC=gnu eval $set_cc_for_build cat <<-EOF > $dummy.c #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #else LIBC=gnu #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` ;; esac # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ /sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || \ echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'` endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'` machine=${arch}${endian}-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently (or will in the future) and ABI. case "${UNAME_MACHINE_ARCH}" in earm*) os=netbsdelf ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # Determine ABI tags. case "${UNAME_MACHINE_ARCH}" in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"` ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}${abi}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:LibertyBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; *:Sortix:*:*) echo ${UNAME_MACHINE}-unknown-sortix exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE=alpha ;; "EV4.5 (21064)") UNAME_MACHINE=alpha ;; "LCA4 (21066/21068)") UNAME_MACHINE=alpha ;; "EV5 (21164)") UNAME_MACHINE=alphaev5 ;; "EV5.6 (21164A)") UNAME_MACHINE=alphaev56 ;; "EV5.6 (21164PC)") UNAME_MACHINE=alphapca56 ;; "EV5.7 (21164PC)") UNAME_MACHINE=alphapca57 ;; "EV6 (21264)") UNAME_MACHINE=alphaev6 ;; "EV6.7 (21264A)") UNAME_MACHINE=alphaev67 ;; "EV6.8CB (21264C)") UNAME_MACHINE=alphaev68 ;; "EV6.8AL (21264B)") UNAME_MACHINE=alphaev68 ;; "EV6.8CX (21264D)") UNAME_MACHINE=alphaev68 ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE=alphaev69 ;; "EV7 (21364)") UNAME_MACHINE=alphaev7 ;; "EV7.9 (21364A)") UNAME_MACHINE=alphaev79 ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux${UNAME_RELEASE} exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH=x86_64 fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/lslpp ] ; then IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH=hppa2.0n ;; 64) HP_ARCH=hppa2.0w ;; '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = hppa2.0w ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH=hppa2.0w else HP_ARCH=hppa64 fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case ${UNAME_PROCESSOR} in amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW64*:*) echo ${UNAME_MACHINE}-pc-mingw64 exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; *:MSYS*:*) echo ${UNAME_MACHINE}-pc-msys exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; 8664:Windows_NT:*) echo x86_64-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; aarch64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC=gnulibc1 ; fi echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arc:Linux:*:* | arceb:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-${LIBC} else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi else echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf fi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; cris:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; crisv32:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; e2k:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; frv:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; hexagon:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:Linux:*:*) echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; k1om:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ;; mips64el:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; openrisc*:Linux:*:*) echo or1k-unknown-linux-${LIBC} exit ;; or32:Linux:*:* | or1k*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; padre:Linux:*:*) echo sparc-unknown-linux-${LIBC} exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-${LIBC} exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; *) echo hppa-unknown-linux-${LIBC} ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-${LIBC} exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-${LIBC} exit ;; ppc64le:Linux:*:*) echo powerpc64le-unknown-linux-${LIBC} exit ;; ppcle:Linux:*:*) echo powerpcle-unknown-linux-${LIBC} exit ;; riscv32:Linux:*:* | riscv64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux-${LIBC} exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; tile*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; x86_64:Haiku:*:*) echo x86_64-unknown-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; SX-ACE:SUPER-UX:*:*) echo sxace-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown eval $set_cc_for_build if test "$UNAME_PROCESSOR" = unknown ; then UNAME_PROCESSOR=powerpc fi if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi fi elif test "$UNAME_PROCESSOR" = i386 ; then # Avoid executing cc on OS X 10.9, as it ships with a stub # that puts up a graphical alert prompting to install # developer tools. Any system running Mac OS X 10.7 or # later (Darwin 11 and later) is required to have a 64-bit # processor. This is not true of the ARM version of Darwin # that Apple uses in portable devices. UNAME_PROCESSOR=x86_64 fi echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-?:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} exit ;; NSE-*:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = 386; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'` exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; x86_64:VMkernel:*:*) echo ${UNAME_MACHINE}-unknown-esx exit ;; amd64:Isilon\ OneFS:*:*) echo x86_64-unknown-onefs exit ;; esac cat >&2 </dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: libopenmpt-0.3.6+release.autotools/build-aux/test-driver0000755000372100037210000001104013235362221020341 00000000000000#! /bin/sh # test-driver - basic testsuite driver script. scriptversion=2013-07-13.22; # UTC # Copyright (C) 2011-2014 Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . # Make unconditional expansion of undefined variables an error. This # helps a lot in preventing typo-related bugs. set -u usage_error () { echo "$0: $*" >&2 print_usage >&2 exit 2 } print_usage () { cat <$log_file 2>&1 estatus=$? if test $enable_hard_errors = no && test $estatus -eq 99; then tweaked_estatus=1 else tweaked_estatus=$estatus fi case $tweaked_estatus:$expect_failure in 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; 0:*) col=$grn res=PASS recheck=no gcopy=no;; 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; *:*) col=$red res=FAIL recheck=yes gcopy=yes;; esac # Report the test outcome and exit status in the logs, so that one can # know whether the test passed or failed simply by looking at the '.log' # file, without the need of also peaking into the corresponding '.trs' # file (automake bug#11814). echo "$res $test_name (exit status: $estatus)" >>$log_file # Report outcome to console. echo "${col}${res}${std}: $test_name" # Register the test result, and other relevant metadata. echo ":test-result: $res" > $trs_file echo ":global-test-result: $res" >> $trs_file echo ":recheck: $recheck" >> $trs_file echo ":copy-in-global-log: $gcopy" >> $trs_file # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: libopenmpt-0.3.6+release.autotools/build-aux/depcomp0000755000372100037210000005601613235362221017534 00000000000000#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2013-05-30.07; # UTC # Copyright (C) 1999-2014 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by 'PROGRAMS ARGS'. object Object file output by 'PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputting dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac # Get the directory component of the given path, and save it in the # global variables '$dir'. Note that this directory component will # be either empty or ending with a '/' character. This is deliberate. set_dir_from () { case $1 in */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; *) dir=;; esac } # Get the suffix-stripped basename of the given path, and save it the # global variable '$base'. set_base_from () { base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` } # If no dependency file was actually created by the compiler invocation, # we still have to create a dummy depfile, to avoid errors with the # Makefile "include basename.Plo" scheme. make_dummy_depfile () { echo "#dummy" > "$depfile" } # Factor out some common post-processing of the generated depfile. # Requires the auxiliary global variable '$tmpdepfile' to be set. aix_post_process_depfile () { # If the compiler actually managed to produce a dependency file, # post-process it. if test -f "$tmpdepfile"; then # Each line is of the form 'foo.o: dependency.h'. # Do two passes, one to just change these to # $object: dependency.h # and one to simply output # dependency.h: # which is needed to avoid the deleted-header problem. { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" } > "$depfile" rm -f "$tmpdepfile" else make_dummy_depfile fi } # A tabulation character. tab=' ' # A newline character. nl=' ' # Character ranges might be problematic outside the C locale. # These definitions help. upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ lower=abcdefghijklmnopqrstuvwxyz digits=0123456789 alpha=${upper}${lower} if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Avoid interferences from the environment. gccflag= dashmflag= # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then # This is just like msvisualcpp but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvisualcpp fi if test "$depmode" = msvc7msys; then # This is just like msvc7 but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvc7 fi if test "$depmode" = xlc; then # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. gccflag=-qmakedep=gcc,-MF depmode=gcc fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. ## Unfortunately, FreeBSD c89 acceptance of flags depends upon ## the command line argument order; so add the flags where they ## appear in depend2.am. Note that the slowdown incurred here ## affects only configure: in makefiles, %FASTDEP% shortcuts this. for arg do case $arg in -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; *) set fnord "$@" "$arg" ;; esac shift # fnord shift # $arg done "$@" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. ## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. ## (see the conditional assignment to $gccflag above). ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). Also, it might not be ## supported by the other compilers which use the 'gcc' depmode. ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The second -e expression handles DOS-style file names with drive # letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the "deleted header file" problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. ## Some versions of gcc put a space before the ':'. On the theory ## that the space means something, we add a space to the output as ## well. hp depmode also adds that space, but also prefixes the VPATH ## to the object. Take care to not repeat it in the output. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like '#:fec' to the end of the # dependency line. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ | tr "$nl" ' ' >> "$depfile" echo >> "$depfile" # The second pass generates a dummy entry for each header file. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" ;; xlc) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts '$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else tmpdepfile1=$dir$base.u tmpdepfile2=$dir$base.u tmpdepfile3=$dir$base.u "$@" -M fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done aix_post_process_depfile ;; tcc) # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 # FIXME: That version still under development at the moment of writing. # Make that this statement remains true also for stable, released # versions. # It will wrap lines (doesn't matter whether long or short) with a # trailing '\', as in: # # foo.o : \ # foo.c \ # foo.h \ # # It will put a trailing '\' even on the last line, and will use leading # spaces rather than leading tabs (at least since its commit 0394caf7 # "Emit spaces for -MD"). "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. # We have to change lines of the first kind to '$object: \'. sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" # And for each line of the second kind, we have to emit a 'dep.h:' # dummy dependency, to avoid the deleted-header problem. sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" rm -f "$tmpdepfile" ;; ## The order of this option in the case statement is important, since the ## shell code in configure will try each of these formats in the order ## listed in this file. A plain '-MD' option would be understood by many ## compilers, so we must ensure this comes after the gcc and icc options. pgcc) # Portland's C compiler understands '-MD'. # Will always output deps to 'file.d' where file is the root name of the # source file under compilation, even if file resides in a subdirectory. # The object file name does not affect the name of the '.d' file. # pgcc 10.2 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using '\' : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... set_dir_from "$object" # Use the source, not the object, to determine the base name, since # that's sadly what pgcc will do too. set_base_from "$source" tmpdepfile=$base.d # For projects that build the same source file twice into different object # files, the pgcc approach of using the *source* file root name can cause # problems in parallel builds. Use a locking strategy to avoid stomping on # the same $tmpdepfile. lockdir=$base.d-lock trap " echo '$0: caught signal, cleaning up...' >&2 rmdir '$lockdir' exit 1 " 1 2 13 15 numtries=100 i=$numtries while test $i -gt 0; do # mkdir is a portable test-and-set. if mkdir "$lockdir" 2>/dev/null; then # This process acquired the lock. "$@" -MD stat=$? # Release the lock. rmdir "$lockdir" break else # If the lock is being held by a different process, wait # until the winning process is done or we timeout. while test -d "$lockdir" && test $i -gt 0; do sleep 1 i=`expr $i - 1` done fi i=`expr $i - 1` done trap - 1 2 13 15 if test $i -le 0; then echo "$0: failed to acquire lock after $numtries attempts" >&2 echo "$0: check lockdir '$lockdir'" >&2 exit 1 fi if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp2) # The "hp" stanza above does not work with aCC (C++) and HP's ia64 # compilers, which have integrated preprocessors. The correct option # to use with these is +Maked; it writes dependencies to a file named # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d "$@" -Wc,+Maked else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d "$@" +Maked fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" # Add 'dependent.h:' lines. sed -ne '2,${ s/^ *// s/ \\*$// s/$/:/ p }' "$tmpdepfile" >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in 'foo.d' instead, so we check for that too. # Subdirectories are respected. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then # Libtool generates 2 separate objects for the 2 libraries. These # two compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir$base.o.d # libtool 1.5 tmpdepfile2=$dir.libs/$base.o.d # Likewise. tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d "$@" -MD fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done # Same post-processing that is required for AIX mode. aix_post_process_depfile ;; msvc7) if test "$libtool" = yes; then showIncludes=-Wc,-showIncludes else showIncludes=-showIncludes fi "$@" $showIncludes > "$tmpdepfile" stat=$? grep -v '^Note: including file: ' "$tmpdepfile" if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The first sed program below extracts the file names and escapes # backslashes for cygpath. The second sed program outputs the file # name when reading, but also accumulates all include files in the # hold buffer in order to output them again at the end. This only # works with sed implementations that can handle large buffers. sed < "$tmpdepfile" -n ' /^Note: including file: *\(.*\)/ { s//\1/ s/\\/\\\\/g p }' | $cygpath_u | sort -u | sed -n ' s/ /\\ /g s/\(.*\)/'"$tab"'\1 \\/p s/.\(.*\) \\/\1:/ H $ { s/.*/'"$tab"'/ G p }' >> "$depfile" echo >> "$depfile" # make sure the fragment doesn't end with a backslash rm -f "$tmpdepfile" ;; msvc7msys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for ':' # in the target name. This is to cope with DOS-style filenames: # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. "$@" $dashmflag | sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this sed invocation # correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # X makedepend shift cleared=no eat=no for arg do case $cleared in no) set ""; shift cleared=yes ;; esac if test $eat = yes; then eat=no continue fi case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -arch) eat=yes ;; -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix=`echo "$object" | sed 's/^.*\././'` touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" # makedepend may prepend the VPATH from the source file name to the object. # No need to regex-escape $object, excess matching of '.' is harmless. sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process the last invocation # correctly. Breaking it into two sed invocations is a workaround. sed '1,2d' "$tmpdepfile" \ | tr ' ' "$nl" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E \ | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi IFS=" " for arg do case "$arg" in -o) shift ;; $object) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" echo "$tab" >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; msvcmsys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: libopenmpt-0.3.6+release.autotools/build-aux/missing0000755000372100037210000001533013235362221017550 00000000000000#! /bin/sh # Common wrapper for a few potentially missing GNU programs. scriptversion=2013-10-28.13; # UTC # Copyright (C) 1996-2014 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try '$0 --help' for more information" exit 1 fi case $1 in --is-lightweight) # Used by our autoconf macros to check whether the available missing # script is modern enough. exit 0 ;; --run) # Back-compat with the calling convention used by older automake. shift ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit Supported PROGRAM values: aclocal autoconf autoheader autom4te automake makeinfo bison yacc flex lex help2man Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and 'g' are ignored when checking the name. Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: unknown '$1' option" echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac # Run the given program, remember its exit status. "$@"; st=$? # If it succeeded, we are done. test $st -eq 0 && exit 0 # Also exit now if we it failed (or wasn't found), and '--version' was # passed; such an option is passed most likely to detect whether the # program is present and works. case $2 in --version|--help) exit $st;; esac # Exit code 63 means version mismatch. This often happens when the user # tries to use an ancient version of a tool on a file that requires a # minimum version. if test $st -eq 63; then msg="probably too old" elif test $st -eq 127; then # Program was missing. msg="missing on your system" else # Program was found and executed, but failed. Give up. exit $st fi perl_URL=http://www.perl.org/ flex_URL=http://flex.sourceforge.net/ gnu_software_URL=http://www.gnu.org/software program_details () { case $1 in aclocal|automake) echo "The '$1' program is part of the GNU Automake package:" echo "<$gnu_software_URL/automake>" echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/autoconf>" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; autoconf|autom4te|autoheader) echo "The '$1' program is part of the GNU Autoconf package:" echo "<$gnu_software_URL/autoconf/>" echo "It also requires GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; esac } give_advice () { # Normalize program name to check for. normalized_program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` printf '%s\n' "'$1' is $msg." configure_deps="'configure.ac' or m4 files included by 'configure.ac'" case $normalized_program in autoconf*) echo "You should only need it if you modified 'configure.ac'," echo "or m4 files included by it." program_details 'autoconf' ;; autoheader*) echo "You should only need it if you modified 'acconfig.h' or" echo "$configure_deps." program_details 'autoheader' ;; automake*) echo "You should only need it if you modified 'Makefile.am' or" echo "$configure_deps." program_details 'automake' ;; aclocal*) echo "You should only need it if you modified 'acinclude.m4' or" echo "$configure_deps." program_details 'aclocal' ;; autom4te*) echo "You might have modified some maintainer files that require" echo "the 'autom4te' program to be rebuilt." program_details 'autom4te' ;; bison*|yacc*) echo "You should only need it if you modified a '.y' file." echo "You may want to install the GNU Bison package:" echo "<$gnu_software_URL/bison/>" ;; lex*|flex*) echo "You should only need it if you modified a '.l' file." echo "You may want to install the Fast Lexical Analyzer package:" echo "<$flex_URL>" ;; help2man*) echo "You should only need it if you modified a dependency" \ "of a man page." echo "You may want to install the GNU Help2man package:" echo "<$gnu_software_URL/help2man/>" ;; makeinfo*) echo "You should only need it if you modified a '.texi' file, or" echo "any other file indirectly affecting the aspect of the manual." echo "You might want to install the Texinfo package:" echo "<$gnu_software_URL/texinfo/>" echo "The spurious makeinfo call might also be the consequence of" echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" echo "want to install GNU make:" echo "<$gnu_software_URL/make/>" ;; *) echo "You might have modified some files without having the proper" echo "tools for further handling them. Check the 'README' file, it" echo "often tells you about the needed prerequisites for installing" echo "this package. You may also peek at any GNU archive site, in" echo "case some other package contains this missing '$1' program." ;; esac } give_advice "$1" | sed -e '1s/^/WARNING: /' \ -e '2,$s/^/ /' >&2 # Propagate the correct exit status (expected to be 127 for a program # not found, 63 for a program that failed due to version mismatch). exit $st # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: libopenmpt-0.3.6+release.autotools/build-aux/ar-lib0000755000372100037210000001330213235362221017242 00000000000000#! /bin/sh # Wrapper for Microsoft lib.exe me=ar-lib scriptversion=2012-03-01.08; # UTC # Copyright (C) 2010-2014 Free Software Foundation, Inc. # Written by Peter Rosin . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . # func_error message func_error () { echo "$me: $1" 1>&2 exit 1 } file_conv= # func_file_conv build_file # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv in mingw) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin) file=`cygpath -m "$file" || echo "$file"` ;; wine) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_at_file at_file operation archive # Iterate over all members in AT_FILE performing OPERATION on ARCHIVE # for each of them. # When interpreting the content of the @FILE, do NOT use func_file_conv, # since the user would need to supply preconverted file names to # binutils ar, at least for MinGW. func_at_file () { operation=$2 archive=$3 at_file_contents=`cat "$1"` eval set x "$at_file_contents" shift for member do $AR -NOLOGO $operation:"$member" "$archive" || exit $? done } case $1 in '') func_error "no command. Try '$0 --help' for more information." ;; -h | --h*) cat <. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches to . # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright 1992-2016 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ kopensolaris*-gnu* | cloudabi*-eabi* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray | -microblaze*) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*178) os=-lynxos178 ;; -lynx*5) os=-lynxos5 ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arceb \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ | ba \ | be32 | be64 \ | bfin \ | c4x | c8051 | clipper \ | d10v | d30v | dlx | dsp16xx \ | e2k | epiphany \ | fido | fr30 | frv | ft32 \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | k1om \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa32r6 | mipsisa32r6el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64r6 | mipsisa64r6el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 | or1k | or1knd | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pru \ | pyramid \ | riscv32 | riscv64 \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | visium \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; leon|leon[3-9]) basic_machine=sparc-$basic_machine ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; strongarm | thumb | xscale) basic_machine=arm-unknown ;; xgate) basic_machine=$basic_machine-unknown os=-none ;; xscaleeb) basic_machine=armeb-unknown ;; xscaleel) basic_machine=armel-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | ba-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | c8051-* | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | e2k-* | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | k1om-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | microblaze-* | microblazeel-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa32r6-* | mipsisa32r6el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64r6-* | mipsisa64r6el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipsr5900-* | mipsr5900el-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* | nios2eb-* | nios2el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | or1k*-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pru-* \ | pyramid-* \ | riscv32-* | riscv64-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | visium-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; asmjs) basic_machine=asmjs-unknown ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c54x-*) basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16 | cr16-*) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; e500v[12]) basic_machine=powerpc-unknown os=$os"spe" ;; e500v[12]-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` os=$os"spe" ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; leon-*|leon[3-9]-*) basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze*) basic_machine=microblaze-xilinx ;; mingw64) basic_machine=x86_64-pc os=-mingw64 ;; mingw32) basic_machine=i686-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; moxiebox) basic_machine=moxie-unknown os=-moxiebox ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i686-pc os=-msys ;; mvs) basic_machine=i370-ibm os=-mvs ;; nacl) basic_machine=le32-unknown os=-nacl ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos | rdos64) basic_machine=x86_64-pc os=-rdos ;; rdos32) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; strongarm-* | thumb-*) basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tile*) basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* | -cloudabi* | -sortix* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ | -onefs* | -tirtos* | -phoenix* | -fuchsia*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -nacl*) ;; -ios) ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; c8051-*) os=-elf ;; hexagon-*) os=-elf ;; tic54x-*) os=-coff ;; tic55x-*) os=-coff ;; tic6x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: libopenmpt-0.3.6+release.autotools/build-aux/compile0000755000372100037210000001624513235362221017535 00000000000000#! /bin/sh # Wrapper for compilers which do not understand '-c -o'. scriptversion=2012-10-14.11; # UTC # Copyright (C) 1999-2014 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . nl=' ' # We need space, tab and new line, in precisely that order. Quoting is # there to prevent tools from complaining about whitespace usage. IFS=" "" $nl" file_conv= # func_file_conv build_file lazy # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. If the determined conversion # type is listed in (the comma separated) LAZY, no conversion will # take place. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv/,$2, in *,$file_conv,*) ;; mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_cl_dashL linkdir # Make cl look for libraries in LINKDIR func_cl_dashL () { func_file_conv "$1" if test -z "$lib_path"; then lib_path=$file else lib_path="$lib_path;$file" fi linker_opts="$linker_opts -LIBPATH:$file" } # func_cl_dashl library # Do a library search-path lookup for cl func_cl_dashl () { lib=$1 found=no save_IFS=$IFS IFS=';' for dir in $lib_path $LIB do IFS=$save_IFS if $shared && test -f "$dir/$lib.dll.lib"; then found=yes lib=$dir/$lib.dll.lib break fi if test -f "$dir/$lib.lib"; then found=yes lib=$dir/$lib.lib break fi if test -f "$dir/lib$lib.a"; then found=yes lib=$dir/lib$lib.a break fi done IFS=$save_IFS if test "$found" != yes; then lib=$lib.lib fi } # func_cl_wrapper cl arg... # Adjust compile command to suit cl func_cl_wrapper () { # Assume a capable shell lib_path= shared=: linker_opts= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. eat=1 case $2 in *.o | *.[oO][bB][jJ]) func_file_conv "$2" set x "$@" -Fo"$file" shift ;; *) func_file_conv "$2" set x "$@" -Fe"$file" shift ;; esac ;; -I) eat=1 func_file_conv "$2" mingw set x "$@" -I"$file" shift ;; -I*) func_file_conv "${1#-I}" mingw set x "$@" -I"$file" shift ;; -l) eat=1 func_cl_dashl "$2" set x "$@" "$lib" shift ;; -l*) func_cl_dashl "${1#-l}" set x "$@" "$lib" shift ;; -L) eat=1 func_cl_dashL "$2" ;; -L*) func_cl_dashL "${1#-L}" ;; -static) shared=false ;; -Wl,*) arg=${1#-Wl,} save_ifs="$IFS"; IFS=',' for flag in $arg; do IFS="$save_ifs" linker_opts="$linker_opts $flag" done IFS="$save_ifs" ;; -Xlinker) eat=1 linker_opts="$linker_opts $2" ;; -*) set x "$@" "$1" shift ;; *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) func_file_conv "$1" set x "$@" -Tp"$file" shift ;; *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) func_file_conv "$1" mingw set x "$@" "$file" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -n "$linker_opts"; then linker_opts="-link$linker_opts" fi exec "$@" $linker_opts exit 1 } eat= case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] Wrapper for compilers which do not understand '-c -o'. Remove '-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the right script to run: please start by reading the file 'INSTALL'. Report bugs to . EOF exit $? ;; -v | --v*) echo "compile $scriptversion" exit $? ;; cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac ofile= cfile= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. # So we strip '-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) ofile=$2 ;; *) set x "$@" -o "$2" shift ;; esac ;; *.c) cfile=$1 set x "$@" "$1" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -z "$ofile" || test -z "$cfile"; then # If no '-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no # '.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi # Name of file we expect compiler to create. cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` # Create the lock directory. # Note: use '[/\\:.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d while true; do if mkdir "$lockdir" >/dev/null 2>&1; then break fi sleep 1 done # FIXME: race condition here if user kills between mkdir and trap. trap "rmdir '$lockdir'; exit 1" 1 2 15 # Run the compile. "$@" ret=$? if test -f "$cofile"; then test "$cofile" = "$ofile" || mv "$cofile" "$ofile" elif test -f "${cofile}bj"; then test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" fi rmdir "$lockdir" exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: libopenmpt-0.3.6+release.autotools/LICENSE0000644000372100037210000000311313222361677015272 00000000000000The OpenMPT code is licensed under the BSD license. Copyright (c) 2004-2018, OpenMPT contributors Copyright (c) 1997-2003, Olivier Lapicque All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the OpenMPT project nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.libopenmpt-0.3.6+release.autotools/test/0000755000372100037210000000000013235362226015321 500000000000000libopenmpt-0.3.6+release.autotools/test/TestToolsLib.h0000644000372100037210000002155513130405330017775 00000000000000/* * TestToolsLib.h * -------------- * Purpose: Unit test framework for libopenmpt. * Notes : This is more complex than the OpenMPT version because we cannot * rely on a debugger and have to deal with exceptions ourselves. * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #ifdef ENABLE_TESTS #ifndef MODPLUG_TRACKER //#define MPT_TEST_CXX11 #include "../common/Endianness.h" #include "../common/FlagSet.h" #include "../soundlib/Snd_defs.h" OPENMPT_NAMESPACE_BEGIN namespace Test { extern int fail_count; enum Verbosity { VerbosityQuiet, VerbosityNormal, VerbosityVerbose, }; enum Fatality { FatalityContinue, FatalityStop }; struct Context { public: const char * const file; const int line; public: Context(const char * file, int line); Context(const Context &c); }; #define MPT_TEST_CONTEXT_CURRENT() (Test::Context( __FILE__ , __LINE__ )) struct TestFailed { std::string values; TestFailed(const std::string &values) : values(values) { } TestFailed() { } }; } // namespace Test template struct ToStringHelper { std::string operator () (const T &x) { return mpt::fmt::val(x); } }; #ifdef MPT_TEST_CXX11 template<> struct ToStringHelper { std::string operator () (const mpt::endian_type &x) { return mpt::fmt::val(x.value); } }; template struct ToStringHelper > { std::string operator () (const FlagSet &x) { return mpt::fmt::val(x.GetRaw()); } }; template struct ToStringHelper > { std::string operator () (const enum_value_type &x) { return mpt::fmt::val(x.as_bits()); } }; template struct ToStringHelper > { std::string operator () (const std::pair &x) { return std::string("{") + mpt::fmt::val(x.first) + std::string(",") + mpt::fmt::val(x.second) + std::string("}"); } }; template struct ToStringHelper > { std::string operator () (const FPInt &x) { return std::string("FPInt<") + mpt::fmt::val(FRACT) + std::string(",") + mpt::fmt::val(typeid(T).name()) + std::string(">{") + mpt::fmt::val(x.GetInt()) + std::string(".") + mpt::fmt::val(x.GetFract()) + std::string("}"); } }; template<> struct ToStringHelper { std::string operator () (const SamplePosition &x) { return mpt::fmt::val(x.GetInt()) + std::string(".") + std::string("0x") + mpt::fmt::hex0<8>(x.GetFract()); } }; #endif // MPT_TEST_CXX11 namespace Test { // We do not generally have type_traits from C++03-TR1 // and std::numeric_limits does not provide a is_integer which is useable as template argument. template struct is_integer : public std::false_type { }; template <> struct is_integer : public std::true_type { }; template <> struct is_integer : public std::true_type { }; template <> struct is_integer : public std::true_type { }; template <> struct is_integer : public std::true_type { }; template <> struct is_integer : public std::true_type { }; template <> struct is_integer : public std::true_type { }; template <> struct is_integer : public std::true_type { }; template <> struct is_integer : public std::true_type { }; class Testcase { private: Fatality const fatality; Verbosity const verbosity; const char * const desc; Context const context; public: Testcase(Fatality fatality, Verbosity verbosity, const char * const desc, const Context &context); public: std::string AsString() const; void ShowStart() const; void ShowProgress(const char * text) const; void ShowPass() const; void ShowFail(bool exception = false, const char * const text = nullptr) const; void ReportPassed(); void ReportFailed(); void ReportException(); private: template inline bool IsEqual(const Tx &x, const Ty &y, std::false_type, std::false_type) { return (x == y); } template inline bool IsEqual(const Tx &x, const Ty &y, std::false_type, std::true_type) { return (x == y); } template inline bool IsEqual(const Tx &x, const Ty &y, std::true_type, std::false_type) { return (x == y); } template inline bool IsEqual(const Tx &x, const Ty &y, std::true_type /* is_integer */, std::true_type /* is_integer */ ) { // Avoid signed-unsigned-comparison warnings and test equivalence in case of either type conversion direction. return ((x == static_cast(y)) && (static_cast(x) == y)); } template inline bool IsEqualEpsilon(const Tx &x, const Ty &y, const Teps &eps) { return mpt::abs(x - y) <= eps; } public: #ifdef MPT_TEST_CXX11 private: template MPT_NOINLINE void TypeCompareHelper(const Tx &x, const Ty &y) { if(!IsEqual(x, y, is_integer(), is_integer())) { throw TestFailed(mpt::format(std::string("%1 != %2"))(ToStringHelper()(x), ToStringHelper()(y))); //throw TestFailed(); } } template MPT_NOINLINE void TypeCompareHelper(const Tx &x, const Ty &y, const Teps &eps) { if(!IsEqualEpsilon(x, y, eps)) { throw TestFailed(mpt::format(std::string("%1 != %2"))(ToStringHelper()(x), ToStringHelper()(y))); //throw TestFailed(); } } public: template MPT_NOINLINE void operator () (const Tfx &fx, const Tfy &fy) { ShowStart(); try { ShowProgress("Calculate x ..."); const auto x = fx(); ShowProgress("Calculate y ..."); const auto y = fy(); ShowProgress("Compare ..."); TypeCompareHelper(x, y); ReportPassed(); } catch(...) { ReportFailed(); } } template MPT_NOINLINE void operator () (const Tfx &fx, const Tfy &fy, const Teps &eps) { ShowStart(); try { ShowProgress("Calculate x ..."); const auto x = fx(); ShowProgress("Calculate y ..."); const auto y = fy(); ShowProgress("Compare ..."); TypeCompareHelper(x, y, eps); ReportPassed(); } catch(...) { ReportFailed(); } } #define VERIFY_EQUAL(x,y) Test::Testcase(Test::FatalityContinue, Test::VerbosityNormal, #x " == " #y , MPT_TEST_CONTEXT_CURRENT() )( [&](){return (x) ;}, [&](){return (y) ;} ) #define VERIFY_EQUAL_NONCONT(x,y) Test::Testcase(Test::FatalityStop , Test::VerbosityNormal, #x " == " #y , MPT_TEST_CONTEXT_CURRENT() )( [&](){return (x) ;}, [&](){return (y) ;} ) #define VERIFY_EQUAL_QUIET_NONCONT(x,y) Test::Testcase(Test::FatalityStop , Test::VerbosityQuiet , #x " == " #y , MPT_TEST_CONTEXT_CURRENT() )( [&](){return (x) ;}, [&](){return (y) ;} ) #define VERIFY_EQUAL_EPS(x,y,eps) Test::Testcase(Test::FatalityContinue, Test::VerbosityNormal, #x " == " #y , MPT_TEST_CONTEXT_CURRENT() )( [&](){return (x) ;}, [&](){return (y) ;}, (eps) ) #else public: template MPT_NOINLINE void operator () (const Tx &x, const Ty &y) { ShowStart(); try { if(!IsEqual(x, y, is_integer(), is_integer())) { //throw TestFailed(mpt::format(std::string("%1 != %2"))(x, y)); throw TestFailed(); } ReportPassed(); } catch(...) { ReportFailed(); } } template MPT_NOINLINE void operator () (const Tx &x, const Ty &y, const Teps &eps) { ShowStart(); try { if(!IsEqualEpsilon(x, y, eps)) { //throw TestFailed(mpt::format(std::string("%1 != %2"))(x, y)); throw TestFailed(); } ReportPassed(); } catch(...) { ReportFailed(); } } #define VERIFY_EQUAL(x,y) Test::Testcase(Test::FatalityContinue, Test::VerbosityNormal, #x " == " #y , MPT_TEST_CONTEXT_CURRENT() )( (x) , (y) ) #define VERIFY_EQUAL_NONCONT(x,y) Test::Testcase(Test::FatalityStop , Test::VerbosityNormal, #x " == " #y , MPT_TEST_CONTEXT_CURRENT() )( (x) , (y) ) #define VERIFY_EQUAL_QUIET_NONCONT(x,y) Test::Testcase(Test::FatalityStop , Test::VerbosityQuiet , #x " == " #y , MPT_TEST_CONTEXT_CURRENT() )( (x) , (y) ) #define VERIFY_EQUAL_EPS(x,y,eps) Test::Testcase(Test::FatalityContinue, Test::VerbosityNormal, #x " == " #y , MPT_TEST_CONTEXT_CURRENT() )( (x) , (y), (eps) ) #endif }; #define DO_TEST(func) \ MPT_DO { \ Test::Testcase test(Test::FatalityStop, Test::VerbosityVerbose, #func , MPT_TEST_CONTEXT_CURRENT() ); \ try { \ test.ShowStart(); \ fail_count = 0; \ func(); \ if(fail_count > 0) { \ throw Test::TestFailed(); \ } \ test.ReportPassed(); \ } catch(...) { \ test.ReportException(); \ } \ } MPT_WHILE_0 } // namespace Test OPENMPT_NAMESPACE_END #endif // !MODPLUG_TRACKER #endif // ENABLE_TESTS libopenmpt-0.3.6+release.autotools/test/test.s3m0000644000372100037210000000142013231111774016635 00000000000000S3M_Test__________________X@'QSCRM þ!ü‰ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿ # /%*Filename_1_X)<< )#Sample_1__________________XSCRS@EmptySCRSFilename_3_X-€>Stereo / 16-BitSCRS¡ Aƒ {A@ƒ" þA€ƒQAÀƒDƒUƒfƒwƒˆƒ ™ƒ ªƒ »ƒ ̃ ݃îƒÿƒƒƒƒƒƒƒƒƒƒƒQ"€‚ƒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿlibopenmpt-0.3.6+release.autotools/test/test.h0000644000372100037210000000057012420156065016370 00000000000000/* * test.h * ------ * Purpose: Unit tests for OpenMPT. * Notes : We need FAAAAAAAR more unit tests! * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once OPENMPT_NAMESPACE_BEGIN namespace Test { void DoTests(); } // namespace Test OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/test/test.cpp0000644000372100037210000055357613231112277016744 00000000000000/* * test.cpp * -------- * Purpose: Unit tests for OpenMPT. * Notes : We need FAAAAAAAR more unit tests! * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "test.h" #ifdef ENABLE_TESTS #include "../common/version.h" #include "../common/misc_util.h" #include "../common/mptCRC.h" #include "../common/StringFixer.h" #include "../common/serialization_utils.h" #include "../common/mptUUID.h" #include "../soundlib/Sndfile.h" #include "../common/FileReader.h" #include "../soundlib/mod_specifications.h" #include "../soundlib/MIDIEvents.h" #include "../soundlib/MIDIMacros.h" #include "../soundbase/SampleFormatConverters.h" #include "../soundbase/SampleFormatCopy.h" #include "../soundlib/ModSampleCopy.h" #include "../soundlib/ITCompression.h" #include "../soundlib/tuningcollection.h" #include "../soundlib/tuning.h" #ifdef MODPLUG_TRACKER #include "../mptrack/mptrack.h" #include "../mptrack/moddoc.h" #include "../mptrack/MainFrm.h" #include "../mptrack/Settings.h" #endif // MODPLUG_TRACKER #include "../common/mptFileIO.h" #ifdef LIBOPENMPT_BUILD #include "../libopenmpt/libopenmpt_version.h" #endif // LIBOPENMPT_BUILD #ifndef NO_PLUGINS #include "../soundlib/plugins/PlugInterface.h" #endif #include "../common/mptBufferIO.h" #include #include #include #include #if MPT_COMPILER_MSVC #include #endif #if MPT_OS_WINDOWS #include #endif #if defined(MPT_WITH_ZLIB) #include #elif defined(MPT_WITH_MINIZ) #define MINIZ_NO_ZLIB_COMPATIBLE_NAMES #include #endif #ifdef _DEBUG #if MPT_COMPILER_MSVC && defined(_MFC_VER) #define new DEBUG_NEW #endif #endif #include "TestTools.h" // enable tests which may fail spuriously //#define FLAKY_TESTS OPENMPT_NAMESPACE_BEGIN namespace Test { static MPT_NOINLINE void TestVersion(); static MPT_NOINLINE void TestTypes(); static MPT_NOINLINE void TestMisc1(); static MPT_NOINLINE void TestMisc2(); static MPT_NOINLINE void TestRandom(); static MPT_NOINLINE void TestCharsets(); static MPT_NOINLINE void TestStringFormatting(); static MPT_NOINLINE void TestSettings(); static MPT_NOINLINE void TestStringIO(); static MPT_NOINLINE void TestMIDIEvents(); static MPT_NOINLINE void TestSampleConversion(); static MPT_NOINLINE void TestITCompression(); static MPT_NOINLINE void TestTunings(); static MPT_NOINLINE void TestPCnoteSerialization(); static MPT_NOINLINE void TestLoadSaveFile(); static MPT_NOINLINE void TestEditing(); static mpt::PathString *PathPrefix = nullptr; static mpt::prng * s_PRNG = nullptr; mpt::PathString GetPathPrefix() { if((*PathPrefix).empty()) { return MPT_PATHSTRING(""); } return *PathPrefix + MPT_PATHSTRING("/"); } void DoTests() { #if MPT_OS_WINDOWS // prefix for test suite std::wstring pathprefix = std::wstring(); bool libopenmpt = false; #ifdef LIBOPENMPT_BUILD libopenmpt = true; #endif #if !MPT_OS_WINDOWS_WINRT // set path prefix for test files (if provided) std::vector buf(GetEnvironmentVariableW(L"srcdir", NULL, 0) + 1); if(GetEnvironmentVariableW(L"srcdir", buf.data(), static_cast(buf.size())) > 0) { pathprefix = buf.data(); } else #endif if(libopenmpt && IsDebuggerPresent()) { pathprefix = L"../../"; } PathPrefix = new mpt::PathString(mpt::PathString::FromNative(pathprefix)); #else // prefix for test suite std::string pathprefix = std::string(); // set path prefix for test files (if provided) std::string env_srcdir = mpt::getenv( "srcdir" ); if ( !env_srcdir.empty() ) { pathprefix = env_srcdir; } PathPrefix = new mpt::PathString(mpt::PathString::FromNative(pathprefix)); #endif mpt::random_device rd; s_PRNG = new mpt::prng(mpt::make_prng(rd)); DO_TEST(TestVersion); DO_TEST(TestTypes); DO_TEST(TestMisc1); DO_TEST(TestMisc2); DO_TEST(TestRandom); DO_TEST(TestCharsets); DO_TEST(TestStringFormatting); DO_TEST(TestSettings); DO_TEST(TestStringIO); DO_TEST(TestMIDIEvents); DO_TEST(TestSampleConversion); DO_TEST(TestITCompression); DO_TEST(TestTunings); // slower tests, require opening a CModDoc DO_TEST(TestPCnoteSerialization); DO_TEST(TestLoadSaveFile); DO_TEST(TestEditing); delete s_PRNG; s_PRNG = nullptr; delete PathPrefix; PathPrefix = nullptr; } static mpt::PathString GetTempFilenameBase(); static void RemoveFile(const mpt::PathString &filename) { #if MPT_OS_WINDOWS for(int retry=0; retry<10; retry++) { if(DeleteFileW(filename.AsNative().c_str()) != FALSE) { break; } // wait for windows virus scanners Sleep(10); } #else remove(filename.AsNative().c_str()); #endif } // Test if functions related to program version data work static MPT_NOINLINE void TestVersion() { //Verify that macros and functions work. { VERIFY_EQUAL( MptVersion::ToNum(MptVersion::ToStr(MptVersion::num)), MptVersion::num ); VERIFY_EQUAL( MptVersion::ToStr(MptVersion::ToNum(MptVersion::str)), MptVersion::str ); VERIFY_EQUAL( MptVersion::ToStr(18285096), "1.17.02.28" ); VERIFY_EQUAL( MptVersion::ToNum("1.17.02.28"), MptVersion::VersionNum(18285096) ); VERIFY_EQUAL( MptVersion::ToNum("1.fe.02.28"), MptVersion::VersionNum(0x01fe0228) ); VERIFY_EQUAL( MptVersion::ToNum("01.fe.02.28"), MptVersion::VersionNum(0x01fe0228) ); VERIFY_EQUAL( MptVersion::ToNum("1.22"), MptVersion::VersionNum(0x01220000) ); VERIFY_EQUAL( MptVersion::ToNum(MptVersion::str), MptVersion::num ); VERIFY_EQUAL( MptVersion::ToStr(MptVersion::num), MptVersion::str ); VERIFY_EQUAL( MptVersion::RemoveBuildNumber(MAKE_VERSION_NUMERIC(1,19,02,00)), MAKE_VERSION_NUMERIC(1,19,02,00)); VERIFY_EQUAL( MptVersion::RemoveBuildNumber(MAKE_VERSION_NUMERIC(1,18,03,20)), MAKE_VERSION_NUMERIC(1,18,03,00)); VERIFY_EQUAL( MptVersion::IsTestBuild(MAKE_VERSION_NUMERIC(1,18,01,13)), true); VERIFY_EQUAL( MptVersion::IsTestBuild(MAKE_VERSION_NUMERIC(1,19,01,00)), false); VERIFY_EQUAL( MptVersion::IsTestBuild(MAKE_VERSION_NUMERIC(1,17,02,54)), false); VERIFY_EQUAL( MptVersion::IsTestBuild(MAKE_VERSION_NUMERIC(1,18,00,00)), false); VERIFY_EQUAL( MptVersion::IsTestBuild(MAKE_VERSION_NUMERIC(1,18,02,00)), false); VERIFY_EQUAL( MptVersion::IsTestBuild(MAKE_VERSION_NUMERIC(1,18,02,01)), true); // Ensure that versions ending in .00.00 (which are ambiguous to truncated version numbers in certain file formats (e.g. S3M and IT) do not get qualified as test builds. VERIFY_EQUAL( MptVersion::IsTestBuild(MAKE_VERSION_NUMERIC(1,23,00,00)), false); STATIC_ASSERT( MAKE_VERSION_NUMERIC(1,17,2,28) == 18285096 ); STATIC_ASSERT( MAKE_VERSION_NUMERIC(1,17,02,48) == 18285128 ); STATIC_ASSERT( MAKE_VERSION_NUMERIC(01,17,02,52) == 18285138 ); // Ensure that bit-shifting works (used in some mod loaders for example) STATIC_ASSERT( MAKE_VERSION_NUMERIC(01,17,00,00) == 0x0117 << 16 ); STATIC_ASSERT( MAKE_VERSION_NUMERIC(01,17,03,00) >> 8 == 0x011703 ); } #ifdef MODPLUG_TRACKER //Verify that the version obtained from the executable file is the same as //defined in MptVersion. { WCHAR szFullPath[MAX_PATH]; DWORD dwVerHnd; DWORD dwVerInfoSize; // Get version information from the application ::GetModuleFileNameW(NULL, szFullPath, mpt::size(szFullPath)); dwVerInfoSize = ::GetFileVersionInfoSizeW(szFullPath, &dwVerHnd); if (!dwVerInfoSize) throw std::runtime_error("!dwVerInfoSize is true"); std::vector pVersionInfo(dwVerInfoSize); WCHAR *szVer = nullptr; UINT uVerLength; if (!(::GetFileVersionInfoW(szFullPath, (DWORD)dwVerHnd, (DWORD)dwVerInfoSize, pVersionInfo.data()))) { throw std::runtime_error("GetFileVersionInfo() returned false"); } if (!(::VerQueryValueW(pVersionInfo.data(), L"\\StringFileInfo\\040904b0\\FileVersion", (LPVOID*)&szVer, &uVerLength))) { throw std::runtime_error("VerQueryValue() returned false"); } std::string version = mpt::ToCharset(mpt::CharsetASCII, szVer); //version string should be like: 1,17,2,38 Change ',' to '.' to get format 1.17.2.38 version = mpt::String::Replace(version, ",", "."); VERIFY_EQUAL( version, MptVersion::str ); VERIFY_EQUAL( MptVersion::ToNum(version), MptVersion::num ); } #endif #ifdef LIBOPENMPT_BUILD mpt::PathString version_mk = GetPathPrefix() + MPT_PATHSTRING("libopenmpt/libopenmpt_version.mk"); mpt::ifstream f(version_mk, std::ios::in); VERIFY_EQUAL(f ? true : false, true); std::map fields; std::string line; while(std::getline(f, line)) { line = mpt::String::Trim(line); if(line.empty()) { continue; } std::vector line_fields = mpt::String::Split(line, std::string("=")); VERIFY_EQUAL_NONCONT(line_fields.size(), 2u); line_fields[0] = mpt::String::Trim(line_fields[0]); line_fields[1] = mpt::String::Trim(line_fields[1]); VERIFY_EQUAL_NONCONT(line_fields[0].length() > 0, true); fields[line_fields[0]] = line_fields[1]; } VERIFY_EQUAL(fields["LIBOPENMPT_VERSION_MAJOR"], mpt::fmt::val(OPENMPT_API_VERSION_MAJOR)); VERIFY_EQUAL(fields["LIBOPENMPT_VERSION_MINOR"], mpt::fmt::val(OPENMPT_API_VERSION_MINOR)); VERIFY_EQUAL(fields["LIBOPENMPT_VERSION_PATCH"], mpt::fmt::val(OPENMPT_API_VERSION_PATCH)); VERIFY_EQUAL(fields["LIBOPENMPT_VERSION_PREREL"], mpt::fmt::val(OPENMPT_API_VERSION_PREREL)); if(std::string(OPENMPT_API_VERSION_PREREL).length() > 0) { VERIFY_EQUAL(std::string(OPENMPT_API_VERSION_PREREL).substr(0, 1), "-"); } VERIFY_EQUAL(OPENMPT_API_VERSION_IS_PREREL, (std::string(OPENMPT_API_VERSION_PREREL).length() > 0) ? 1 : 0); VERIFY_EQUAL(fields["LIBOPENMPT_LTVER_CURRENT"].length() > 0, true); VERIFY_EQUAL(fields["LIBOPENMPT_LTVER_REVISION"].length() > 0, true); VERIFY_EQUAL(fields["LIBOPENMPT_LTVER_AGE"].length() > 0, true); #endif // LIBOPENMPT_BUILD } // Test if data types are interpreted correctly static MPT_NOINLINE void TestTypes() { VERIFY_EQUAL(int8_min, (std::numeric_limits::min)()); VERIFY_EQUAL(int8_max, (std::numeric_limits::max)()); VERIFY_EQUAL(uint8_max, (std::numeric_limits::max)()); VERIFY_EQUAL(int16_min, (std::numeric_limits::min)()); VERIFY_EQUAL(int16_max, (std::numeric_limits::max)()); VERIFY_EQUAL(uint16_max, (std::numeric_limits::max)()); VERIFY_EQUAL(int32_min, (std::numeric_limits::min)()); VERIFY_EQUAL(int32_max, (std::numeric_limits::max)()); VERIFY_EQUAL(uint32_max, (std::numeric_limits::max)()); VERIFY_EQUAL(int64_min, (std::numeric_limits::min)()); VERIFY_EQUAL(int64_max, (std::numeric_limits::max)()); VERIFY_EQUAL(uint64_max, (std::numeric_limits::max)()); STATIC_ASSERT(int8_max == MPT_MAX_VALUE_OF_TYPE(int8)); STATIC_ASSERT(uint8_max == MPT_MAX_VALUE_OF_TYPE(uint8)); STATIC_ASSERT(int16_max == MPT_MAX_VALUE_OF_TYPE(int16)); STATIC_ASSERT(uint16_max == MPT_MAX_VALUE_OF_TYPE(uint16)); STATIC_ASSERT(int32_max == MPT_MAX_VALUE_OF_TYPE(int32)); STATIC_ASSERT(uint32_max == MPT_MAX_VALUE_OF_TYPE(uint32)); STATIC_ASSERT(int64_max == MPT_MAX_VALUE_OF_TYPE(int64)); STATIC_ASSERT(uint64_max == MPT_MAX_VALUE_OF_TYPE(uint64)); } #ifdef MODPLUG_TRACKER // In tracker debug builds, the sprintf-like function is retained in order to be able to validate our own formatting against sprintf. // There are 4 reasons why this is not available for library code: // 1. printf-like functionality is not type-safe. // 2. There are portability problems with char/wchar_t and the semantics of %s/%ls/%S . // 3. There are portability problems with specifying format for 64bit integers. // 4. Formatting of floating point values depends on the currently set C locale. // A library is not allowed to mock with that and thus cannot influence the behavior in this case. template static std::string StringFormat(const char *format, T x) { #if MPT_COMPILER_MSVC // Count the needed array size. const size_t nCount = _scprintf(format, x); // null character not included. std::vector buf(nCount + 1); // + 1 is for null terminator. sprintf_s(&(buf[0]), buf.size(), format, x); return &(buf[0]); #else int size = snprintf(NULL, 0, format, x); // get required size, requires c99 compliant snprintf which msvc does not have std::vector temp(size + 1); snprintf(&(temp[0]), size + 1, format, x); return &(temp[0]); #endif } #endif static void TestFloatFormat(double x, const char * format, mpt::FormatFlags f, std::size_t width = 0, int precision = -1) { #ifdef MODPLUG_TRACKER std::string str_sprintf = StringFormat(format, x); #endif std::string str_iostreams = mpt::FormatSpec().SetFlags(f).SetWidth(width).SetPrecision(precision).ToString(x); std::string str_parsed = mpt::FormatSpec().ParsePrintf(format).ToString(x); //Log("%s", str_sprintf.c_str()); //Log("%s", str_iostreams.c_str()); //Log("%s", str_iostreams.c_str()); #ifdef MODPLUG_TRACKER VERIFY_EQUAL(str_iostreams, str_sprintf); // this will fail with a set c locale (and there is nothing that can be done about that in libopenmpt) #endif VERIFY_EQUAL(str_iostreams, str_parsed); } static void TestFloatFormats(double x) { TestFloatFormat(x, "%g", mpt::fmt::NotaNrm | mpt::fmt::FillOff); TestFloatFormat(x, "%.8g", mpt::fmt::NotaNrm | mpt::fmt::FillOff, 0, 8); TestFloatFormat(x, "%f", mpt::fmt::NotaFix | mpt::fmt::FillOff); TestFloatFormat(x, "%.0f", mpt::fmt::NotaFix | mpt::fmt::FillOff, 0, 0); TestFloatFormat(x, "%.1f", mpt::fmt::NotaFix | mpt::fmt::FillOff, 0, 1); TestFloatFormat(x, "%.2f", mpt::fmt::NotaFix | mpt::fmt::FillOff, 0, 2); TestFloatFormat(x, "%.3f", mpt::fmt::NotaFix | mpt::fmt::FillOff, 0, 3); TestFloatFormat(x, "%1.1f", mpt::fmt::NotaFix | mpt::fmt::FillSpc, 1, 1); TestFloatFormat(x, "%3.1f", mpt::fmt::NotaFix | mpt::fmt::FillSpc, 3, 1); TestFloatFormat(x, "%4.1f", mpt::fmt::NotaFix | mpt::fmt::FillSpc, 4, 1); TestFloatFormat(x, "%6.3f", mpt::fmt::NotaFix | mpt::fmt::FillSpc, 6, 3); TestFloatFormat(x, "%0.1f", mpt::fmt::NotaFix | mpt::fmt::FillNul, 0, 1); TestFloatFormat(x, "%02.0f", mpt::fmt::NotaFix | mpt::fmt::FillNul, 2, 0); } static bool BeginsWith(const std::string &str, const std::string &match) { return (str.find(match) == 0); } static bool EndsWith(const std::string &str, const std::string &match) { return (str.rfind(match) == (str.length() - match.length())); } #if MPT_WSTRING_CONVERT static bool BeginsWith(const std::wstring &str, const std::wstring &match) { return (str.find(match) == 0); } static bool EndsWith(const std::wstring &str, const std::wstring &match) { return (str.rfind(match) == (str.length() - match.length())); } #endif #if MPT_USTRING_MODE_UTF8 static bool BeginsWith(const mpt::ustring &str, const mpt::ustring &match) { return (str.find(match) == 0); } static bool EndsWith(const mpt::ustring &str, const mpt::ustring &match) { return (str.rfind(match) == (str.length() - match.length())); } #endif static MPT_NOINLINE void TestStringFormatting() { VERIFY_EQUAL(mpt::fmt::val(1.5f), "1.5"); VERIFY_EQUAL(mpt::fmt::val(true), "1"); VERIFY_EQUAL(mpt::fmt::val(false), "0"); //VERIFY_EQUAL(mpt::fmt::val('A'), "A"); // deprecated //VERIFY_EQUAL(mpt::fmt::val(L'A'), "A"); // deprecated VERIFY_EQUAL(mpt::fmt::val(0), "0"); VERIFY_EQUAL(mpt::fmt::val(-23), "-23"); VERIFY_EQUAL(mpt::fmt::val(42), "42"); VERIFY_EQUAL(mpt::fmt::hex<3>((int32)-1), "ffffffff"); VERIFY_EQUAL(mpt::fmt::hex(0x123e), "123e"); VERIFY_EQUAL(mpt::fmt::hex0<6>(0x123e), "00123e"); VERIFY_EQUAL(mpt::fmt::hex0<2>(0x123e), "123e"); #if MPT_WSTRING_FORMAT VERIFY_EQUAL(mpt::wfmt::hex<3>((int32)-1), L"ffffffff"); VERIFY_EQUAL(mpt::wfmt::hex(0x123e), L"123e"); VERIFY_EQUAL(mpt::wfmt::hex0<6>(0x123e), L"00123e"); VERIFY_EQUAL(mpt::wfmt::hex0<2>(0x123e), L"123e"); #endif VERIFY_EQUAL(mpt::fmt::val(-87.0f), "-87"); if(mpt::fmt::val(-0.5e-6) != "-5e-007" && mpt::fmt::val(-0.5e-6) != "-5e-07" && mpt::fmt::val(-0.5e-6) != "-5e-7" ) { VERIFY_EQUAL(true, false); } VERIFY_EQUAL(mpt::fmt::val(58.65403492763), "58.654"); VERIFY_EQUAL(mpt::FormatSpec("%3.1f").ToString(23.42), "23.4"); VERIFY_EQUAL(mpt::fmt::f("%3.1f", 23.42), "23.4"); VERIFY_EQUAL(ConvertStrTo("586"), 586u); VERIFY_EQUAL(ConvertStrTo("2147483647"), (uint32)int32_max); VERIFY_EQUAL(ConvertStrTo("4294967295"), uint32_max); VERIFY_EQUAL(ConvertStrTo("-9223372036854775808"), int64_min); VERIFY_EQUAL(ConvertStrTo("-159"), -159); VERIFY_EQUAL(ConvertStrTo("9223372036854775807"), int64_max); VERIFY_EQUAL(ConvertStrTo("85059"), 85059u); VERIFY_EQUAL(ConvertStrTo("9223372036854775807"), (uint64)int64_max); VERIFY_EQUAL(ConvertStrTo("18446744073709551615"), uint64_max); VERIFY_EQUAL(ConvertStrTo("-87.0"), -87.0); VERIFY_EQUAL(ConvertStrTo("-0.5e-6"), -0.5e-6); VERIFY_EQUAL(ConvertStrTo("58.65403492763"), 58.65403492763); VERIFY_EQUAL(ConvertStrTo(mpt::fmt::val(-87.0)), -87.0); VERIFY_EQUAL(ConvertStrTo(mpt::fmt::val(-0.5e-6)), -0.5e-6); VERIFY_EQUAL(mpt::String::Parse::Hex("fe"), 254); #if MPT_WSTRING_FORMAT VERIFY_EQUAL(mpt::String::Parse::Hex(L"fe"), 254); #endif VERIFY_EQUAL(mpt::String::Parse::Hex(MPT_USTRING("ffff")), 65535); TestFloatFormats(0.0f); TestFloatFormats(1.0f); TestFloatFormats(-1.0f); TestFloatFormats(0.1f); TestFloatFormats(-0.1f); TestFloatFormats(1000000000.0f); TestFloatFormats(-1000000000.0f); TestFloatFormats(0.0000000001f); TestFloatFormats(-0.0000000001f); TestFloatFormats(6.12345f); TestFloatFormats(42.1234567890); TestFloatFormats(0.1234567890); TestFloatFormats(1234567890000000.0); TestFloatFormats(0.0000001234567890); VERIFY_EQUAL(mpt::FormatSpec().ParsePrintf("%7.3f").ToString(6.12345), " 6.123"); VERIFY_EQUAL(mpt::fmt::f("%7.3f", 6.12345), " 6.123"); VERIFY_EQUAL(mpt::fmt::flt(6.12345, 7, 3), " 6.123"); VERIFY_EQUAL(mpt::fmt::fix(6.12345, 7, 3), " 6.123"); VERIFY_EQUAL(mpt::fmt::flt(6.12345, 0, 4), "6.123"); #if !(MPT_OS_EMSCRIPTEN && MPT_OS_EMSCRIPTEN_ANCIENT) VERIFY_EQUAL(mpt::fmt::fix(6.12345, 0, 4), "6.1235"); #else // emscripten(1.21)/nodejs(v0.10.25) print 6.1234 instead of 6.1235 for unknown reasons. // As this test case is not fatal, ignore it for now in order to make the test cases pass. #endif #if MPT_WSTRING_FORMAT VERIFY_EQUAL(mpt::wfmt::flt(6.12345, 7, 3), L" 6.123"); VERIFY_EQUAL(mpt::wfmt::fix(6.12345, 7, 3), L" 6.123"); VERIFY_EQUAL(mpt::wfmt::flt(6.12345, 0, 4), L"6.123"); #endif // basic VERIFY_EQUAL(mpt::format("%1%2%3")(1,2,3), "123"); VERIFY_EQUAL(mpt::format("%1%1%1")(1,2,3), "111"); VERIFY_EQUAL(mpt::format("%3%3%3")(1,2,3), "333"); // template argument deduction of string type VERIFY_EQUAL(mpt::format(std::string("%1%2%3"))(1,2,3), "123"); #if MPT_WSTRING_FORMAT VERIFY_EQUAL(mpt::format(L"%1%2%3")(1,2,3), L"123"); VERIFY_EQUAL(mpt::format(L"%1%2%3")(1,2,3), L"123"); #endif // escaping and error behviour of '%' VERIFY_EQUAL(mpt::format("%")(), "%"); VERIFY_EQUAL(mpt::format("%%")(), "%"); VERIFY_EQUAL(mpt::format("%%%")(), "%%"); VERIFY_EQUAL(mpt::format("%1")("a"), "a"); VERIFY_EQUAL(mpt::format("%1%")("a"), "a%"); VERIFY_EQUAL(mpt::format("%1%%")("a"), "a%"); VERIFY_EQUAL(mpt::format("%1%%%")("a"), "a%%"); VERIFY_EQUAL(mpt::format("%%1")("a"), "%1"); VERIFY_EQUAL(mpt::format("%%%1")("a"), "%a"); VERIFY_EQUAL(mpt::format("%b")("a"), "%b"); #if defined(_MFC_VER) VERIFY_EQUAL(mpt::ufmt::val(CString(_T("foobar"))), MPT_USTRING("foobar")); VERIFY_EQUAL(mpt::ufmt::val(CString(_T("foobar"))), MPT_USTRING("foobar")); VERIFY_EQUAL(mpt::format(CString(_T("%1%2%3")))(1,2,3), _T("123")); VERIFY_EQUAL(mpt::format(CString(_T("%1%2%3")))(1,mpt::tfmt::dec0<3>(2),3), _T("10023")); #endif } struct Gregorian { int Y,M,D,h,m,s; static Gregorian FromTM(tm t) { Gregorian g; g.Y = t.tm_year + 1900; g.M = t.tm_mon + 1; g.D = t.tm_mday; g.h = t.tm_hour; g.m = t.tm_min; g.s = t.tm_sec; return g; } static tm ToTM(Gregorian g) { tm t; MemsetZero(t); t.tm_year = g.Y - 1900; t.tm_mon = g.M - 1; t.tm_mday = g.D; t.tm_hour = g.h; t.tm_min = g.m; t.tm_sec = g.s; return t; } }; bool operator ==(Gregorian a, Gregorian b) { return a.Y == b.Y && a.M == b.M && a.D == b.D && a.h == b.h && a.m == b.m && a.s == b.s; } bool operator !=(Gregorian a, Gregorian b) { return !(a == b); } int64 TestDate1(int s, int m, int h, int D, int M, int Y) { return mpt::Date::Unix::FromUTC(Gregorian::ToTM(Gregorian{Y,M,D,h,m,s})); } Gregorian TestDate2(int s, int m, int h, int D, int M, int Y) { return Gregorian{Y,M,D,h,m,s}; } static MPT_NOINLINE void TestMisc1() { VERIFY_EQUAL(mpt::endian(), mpt::detail::endian_probe()); VERIFY_EQUAL((mpt::endian() == mpt::endian_big) || (mpt::endian() == mpt::endian_little), true); #define SwapBytesReturn(x) SwapBytesLE(SwapBytesBE(x)) VERIFY_EQUAL(SwapBytesReturn(uint8(0x12)), 0x12); VERIFY_EQUAL(SwapBytesReturn(uint16(0x1234)), 0x3412); VERIFY_EQUAL(SwapBytesReturn(uint32(0x12345678u)), 0x78563412u); VERIFY_EQUAL(SwapBytesReturn(uint64(0x123456789abcdef0ull)), 0xf0debc9a78563412ull); VERIFY_EQUAL(SwapBytesReturn(int8(int8_min)), int8_min); VERIFY_EQUAL(SwapBytesReturn(int16(int16_min)), int16(0x80)); VERIFY_EQUAL(SwapBytesReturn(int32(int32_min)), int32(0x80)); VERIFY_EQUAL(SwapBytesReturn(int64(int64_min)), int64(0x80)); #undef SwapBytesReturn VERIFY_EQUAL(EncodeIEEE754binary32(1.0f), 0x3f800000u); VERIFY_EQUAL(EncodeIEEE754binary32(-1.0f), 0xbf800000u); VERIFY_EQUAL(DecodeIEEE754binary32(0x00000000u), 0.0f); VERIFY_EQUAL(DecodeIEEE754binary32(0x41840000u), 16.5f); VERIFY_EQUAL(DecodeIEEE754binary32(0x3faa0000u), 1.328125f); VERIFY_EQUAL(DecodeIEEE754binary32(0xbfaa0000u), -1.328125f); VERIFY_EQUAL(DecodeIEEE754binary32(0x3f800000u), 1.0f); VERIFY_EQUAL(DecodeIEEE754binary32(0x00000000u), 0.0f); VERIFY_EQUAL(DecodeIEEE754binary32(0xbf800000u), -1.0f); VERIFY_EQUAL(DecodeIEEE754binary32(0x3f800000u), 1.0f); VERIFY_EQUAL(IEEE754binary32LE(1.0f).GetInt32(), 0x3f800000u); VERIFY_EQUAL(IEEE754binary32BE(1.0f).GetInt32(), 0x3f800000u); VERIFY_EQUAL(IEEE754binary32LE(0x00,0x00,0x80,0x3f), 1.0f); VERIFY_EQUAL(IEEE754binary32BE(0x3f,0x80,0x00,0x00), 1.0f); VERIFY_EQUAL(IEEE754binary32LE(1.0f), IEEE754binary32LE(0x00,0x00,0x80,0x3f)); VERIFY_EQUAL(IEEE754binary32BE(1.0f), IEEE754binary32BE(0x3f,0x80,0x00,0x00)); VERIFY_EQUAL(EncodeIEEE754binary64(1.0), 0x3ff0000000000000ull); VERIFY_EQUAL(EncodeIEEE754binary64(-1.0), 0xbff0000000000000ull); VERIFY_EQUAL(DecodeIEEE754binary64(0x0000000000000000ull), 0.0); VERIFY_EQUAL(DecodeIEEE754binary64(0x4030800000000000ull), 16.5); VERIFY_EQUAL(DecodeIEEE754binary64(0x3FF5400000000000ull), 1.328125); VERIFY_EQUAL(DecodeIEEE754binary64(0xBFF5400000000000ull), -1.328125); VERIFY_EQUAL(DecodeIEEE754binary64(0x3ff0000000000000ull), 1.0); VERIFY_EQUAL(DecodeIEEE754binary64(0x0000000000000000ull), 0.0); VERIFY_EQUAL(DecodeIEEE754binary64(0xbff0000000000000ull), -1.0); VERIFY_EQUAL(DecodeIEEE754binary64(0x3ff0000000000000ull), 1.0); VERIFY_EQUAL(IEEE754binary64LE(1.0).GetInt64(), 0x3ff0000000000000ull); VERIFY_EQUAL(IEEE754binary64BE(1.0).GetInt64(), 0x3ff0000000000000ull); VERIFY_EQUAL(IEEE754binary64LE(0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x3f), 1.0); VERIFY_EQUAL(IEEE754binary64BE(0x3f,0xf0,0x00,0x00,0x00,0x00,0x00,0x00), 1.0); VERIFY_EQUAL(IEEE754binary64LE(1.0), IEEE754binary64LE(0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x3f)); VERIFY_EQUAL(IEEE754binary64BE(1.0), IEEE754binary64BE(0x3f,0xf0,0x00,0x00,0x00,0x00,0x00,0x00)); // Packed integers with defined endianness { int8le le8; le8.set(-128); int8be be8; be8.set(-128); VERIFY_EQUAL(le8, -128); VERIFY_EQUAL(be8, -128); VERIFY_EQUAL(memcmp(&le8, "\x80", 1), 0); VERIFY_EQUAL(memcmp(&be8, "\x80", 1), 0); int16le le16; le16.set(0x1234); int16be be16; be16.set(0x1234); VERIFY_EQUAL(le16, 0x1234); VERIFY_EQUAL(be16, 0x1234); VERIFY_EQUAL(memcmp(&le16, "\x34\x12", 2), 0); VERIFY_EQUAL(memcmp(&be16, "\x12\x34", 2), 0); uint32le le32; le32.set(0xFFEEDDCCu); uint32be be32; be32.set(0xFFEEDDCCu); VERIFY_EQUAL(le32, 0xFFEEDDCCu); VERIFY_EQUAL(be32, 0xFFEEDDCCu); VERIFY_EQUAL(memcmp(&le32, "\xCC\xDD\xEE\xFF", 4), 0); VERIFY_EQUAL(memcmp(&be32, "\xFF\xEE\xDD\xCC", 4), 0); uint64le le64; le64.set(0xDEADC0DE15C0FFEEull); uint64be be64; be64.set(0xDEADC0DE15C0FFEEull); VERIFY_EQUAL(le64, 0xDEADC0DE15C0FFEEull); VERIFY_EQUAL(be64, 0xDEADC0DE15C0FFEEull); VERIFY_EQUAL(memcmp(&le64, "\xEE\xFF\xC0\x15\xDE\xC0\xAD\xDE", 8), 0); VERIFY_EQUAL(memcmp(&be64, "\xDE\xAD\xC0\xDE\x15\xC0\xFF\xEE", 8), 0); } VERIFY_EQUAL(ModCommand::IsPcNote(NOTE_MAX), false); VERIFY_EQUAL(ModCommand::IsPcNote(NOTE_PC), true); VERIFY_EQUAL(ModCommand::IsPcNote(NOTE_PCS), true); VERIFY_EQUAL(CModSpecifications::ExtensionToType(".mod"), MOD_TYPE_MOD); VERIFY_EQUAL(CModSpecifications::ExtensionToType("mod"), MOD_TYPE_MOD); VERIFY_EQUAL(CModSpecifications::ExtensionToType(".s3m"), MOD_TYPE_S3M); VERIFY_EQUAL(CModSpecifications::ExtensionToType("s3m"), MOD_TYPE_S3M); VERIFY_EQUAL(CModSpecifications::ExtensionToType(".xm"), MOD_TYPE_XM); VERIFY_EQUAL(CModSpecifications::ExtensionToType("xm"), MOD_TYPE_XM); VERIFY_EQUAL(CModSpecifications::ExtensionToType(".it"), MOD_TYPE_IT); VERIFY_EQUAL(CModSpecifications::ExtensionToType("it"), MOD_TYPE_IT); VERIFY_EQUAL(CModSpecifications::ExtensionToType(".itp"), MOD_TYPE_NONE); VERIFY_EQUAL(CModSpecifications::ExtensionToType("itp"), MOD_TYPE_NONE); VERIFY_EQUAL(CModSpecifications::ExtensionToType("mptm"), MOD_TYPE_MPT); VERIFY_EQUAL(CModSpecifications::ExtensionToType("invalidExtension"), MOD_TYPE_NONE); VERIFY_EQUAL(CModSpecifications::ExtensionToType("ita"), MOD_TYPE_NONE); VERIFY_EQUAL(CModSpecifications::ExtensionToType("s2m"), MOD_TYPE_NONE); VERIFY_EQUAL(CModSpecifications::ExtensionToType(""), MOD_TYPE_NONE); VERIFY_EQUAL( Util::Round(1.99), 2.0 ); VERIFY_EQUAL( Util::Round(1.5), 2.0 ); VERIFY_EQUAL( Util::Round(1.1), 1.0 ); VERIFY_EQUAL( Util::Round(-0.1), 0.0 ); VERIFY_EQUAL( Util::Round(-0.5), -1.0 ); VERIFY_EQUAL( Util::Round(-0.9), -1.0 ); VERIFY_EQUAL( Util::Round(-1.4), -1.0 ); VERIFY_EQUAL( Util::Round(-1.7), -2.0 ); VERIFY_EQUAL( Util::Round(int32_max + 0.1), int32_max ); VERIFY_EQUAL( Util::Round(int32_max - 0.4), int32_max ); VERIFY_EQUAL( Util::Round(int32_min + 0.1), int32_min ); VERIFY_EQUAL( Util::Round(int32_min - 0.1), int32_min ); VERIFY_EQUAL( Util::Round(uint32_max + 0.499), uint32_max ); VERIFY_EQUAL( Util::Round(110.1), 110 ); VERIFY_EQUAL( Util::Round(-110.1), -110 ); // trivials VERIFY_EQUAL( mpt::saturate_cast(-1), -1 ); VERIFY_EQUAL( mpt::saturate_cast(0), 0 ); VERIFY_EQUAL( mpt::saturate_cast(1), 1 ); VERIFY_EQUAL( mpt::saturate_cast(std::numeric_limits::min()), std::numeric_limits::min() ); VERIFY_EQUAL( mpt::saturate_cast(std::numeric_limits::max()), std::numeric_limits::max() ); // signed / unsigned VERIFY_EQUAL( mpt::saturate_cast(std::numeric_limits::min()), std::numeric_limits::min() ); VERIFY_EQUAL( mpt::saturate_cast(std::numeric_limits::max()), std::numeric_limits::max() ); VERIFY_EQUAL( mpt::saturate_cast(std::numeric_limits::min()), (int32)std::numeric_limits::min() ); VERIFY_EQUAL( mpt::saturate_cast(std::numeric_limits::max()), std::numeric_limits::max() ); VERIFY_EQUAL( mpt::saturate_cast(std::numeric_limits::min()), (int64)std::numeric_limits::min() ); VERIFY_EQUAL( mpt::saturate_cast(std::numeric_limits::max()), std::numeric_limits::max() ); VERIFY_EQUAL( mpt::saturate_cast(std::numeric_limits::min()), std::numeric_limits::min() ); VERIFY_EQUAL( mpt::saturate_cast(std::numeric_limits::max()), std::numeric_limits::max() ); VERIFY_EQUAL( mpt::saturate_cast(std::numeric_limits::min()), std::numeric_limits::min() ); VERIFY_EQUAL( mpt::saturate_cast(std::numeric_limits::max()), (uint32)std::numeric_limits::max() ); VERIFY_EQUAL( mpt::saturate_cast(std::numeric_limits::min()), std::numeric_limits::min() ); VERIFY_EQUAL( mpt::saturate_cast(std::numeric_limits::max()), (uint64)std::numeric_limits::max() ); // overflow VERIFY_EQUAL( mpt::saturate_cast(std::numeric_limits::min() - 1), std::numeric_limits::min() ); VERIFY_EQUAL( mpt::saturate_cast(std::numeric_limits::max() + 1), std::numeric_limits::max() ); VERIFY_EQUAL( mpt::saturate_cast(std::numeric_limits::min() - int64(1)), std::numeric_limits::min() ); VERIFY_EQUAL( mpt::saturate_cast(std::numeric_limits::max() + int64(1)), std::numeric_limits::max() ); VERIFY_EQUAL( mpt::saturate_cast(std::numeric_limits::min() - 1), std::numeric_limits::min() ); VERIFY_EQUAL( mpt::saturate_cast(std::numeric_limits::max() + 1), (uint16)std::numeric_limits::max() + 1 ); VERIFY_EQUAL( mpt::saturate_cast(std::numeric_limits::min() - int64(1)), std::numeric_limits::min() ); VERIFY_EQUAL( mpt::saturate_cast(std::numeric_limits::max() + int64(1)), (uint32)std::numeric_limits::max() + 1 ); VERIFY_EQUAL( mpt::saturate_cast( int16(32000) ), 127 ); VERIFY_EQUAL( mpt::saturate_cast( int16(-32000) ), -128 ); VERIFY_EQUAL( mpt::saturate_cast( uint16(32000) ), 127 ); VERIFY_EQUAL( mpt::saturate_cast( uint16(64000) ), 127 ); VERIFY_EQUAL( mpt::saturate_cast( int16(32000) ), 255 ); VERIFY_EQUAL( mpt::saturate_cast( int16(-32000) ), 0 ); VERIFY_EQUAL( mpt::saturate_cast( uint16(32000) ), 255 ); VERIFY_EQUAL( mpt::saturate_cast( uint16(64000) ), 255 ); VERIFY_EQUAL( mpt::saturate_cast( int16(32000) ), 32000 ); VERIFY_EQUAL( mpt::saturate_cast( int16(-32000) ), -32000 ); VERIFY_EQUAL( mpt::saturate_cast( uint16(32000) ), 32000 ); VERIFY_EQUAL( mpt::saturate_cast( uint16(64000) ), 32767 ); VERIFY_EQUAL( mpt::saturate_cast( int16(32000) ), 32000 ); VERIFY_EQUAL( mpt::saturate_cast( int16(-32000) ), 0 ); VERIFY_EQUAL( mpt::saturate_cast( uint16(32000) ), 32000 ); VERIFY_EQUAL( mpt::saturate_cast( uint16(64000) ), 64000 ); VERIFY_EQUAL( mpt::saturate_cast( int16(32000) ), 32000 ); VERIFY_EQUAL( mpt::saturate_cast( int16(-32000) ), -32000 ); VERIFY_EQUAL( mpt::saturate_cast( uint16(32000) ), 32000 ); VERIFY_EQUAL( mpt::saturate_cast( uint16(64000) ), 64000 ); VERIFY_EQUAL( mpt::saturate_cast( int16(32000) ), 32000 ); VERIFY_EQUAL( mpt::saturate_cast( int16(-32000) ), 0 ); VERIFY_EQUAL( mpt::saturate_cast( uint16(32000) ), 32000 ); VERIFY_EQUAL( mpt::saturate_cast( uint16(64000) ), 64000 ); VERIFY_EQUAL( mpt::saturate_cast(std::numeric_limits::max() - 1), std::numeric_limits::max() ); VERIFY_EQUAL( mpt::saturate_cast(std::numeric_limits::max() - 1), std::numeric_limits::max() ); VERIFY_EQUAL( mpt::saturate_cast(static_cast(std::numeric_limits::max())), std::numeric_limits::max() ); VERIFY_EQUAL(mpt::rshift_signed(-32768, 1), mpt::rshift_signed_standard(-32768, 1)); VERIFY_EQUAL(mpt::rshift_signed(-32767, 1), mpt::rshift_signed_standard(-32767, 1)); VERIFY_EQUAL(mpt::rshift_signed(-32766, 1), mpt::rshift_signed_standard(-32766, 1)); VERIFY_EQUAL(mpt::rshift_signed( -2, 1), mpt::rshift_signed_standard( -2, 1)); VERIFY_EQUAL(mpt::rshift_signed( -1, 1), mpt::rshift_signed_standard( -1, 1)); VERIFY_EQUAL(mpt::rshift_signed( 0, 1), mpt::rshift_signed_standard( 0, 1)); VERIFY_EQUAL(mpt::rshift_signed( 1, 1), mpt::rshift_signed_standard( 1, 1)); VERIFY_EQUAL(mpt::rshift_signed( 2, 1), mpt::rshift_signed_standard( 2, 1)); VERIFY_EQUAL(mpt::rshift_signed( 32766, 1), mpt::rshift_signed_standard( 32766, 1)); VERIFY_EQUAL(mpt::rshift_signed( 32767, 1), mpt::rshift_signed_standard( 32767, 1)); VERIFY_EQUAL(mpt::rshift_signed(-32768, 14), mpt::rshift_signed_standard(-32768, 14)); VERIFY_EQUAL(mpt::rshift_signed(-32767, 14), mpt::rshift_signed_standard(-32767, 14)); VERIFY_EQUAL(mpt::rshift_signed(-32766, 14), mpt::rshift_signed_standard(-32766, 14)); VERIFY_EQUAL(mpt::rshift_signed( -2, 14), mpt::rshift_signed_standard( -2, 14)); VERIFY_EQUAL(mpt::rshift_signed( -1, 14), mpt::rshift_signed_standard( -1, 14)); VERIFY_EQUAL(mpt::rshift_signed( 0, 14), mpt::rshift_signed_standard( 0, 14)); VERIFY_EQUAL(mpt::rshift_signed( 1, 14), mpt::rshift_signed_standard( 1, 14)); VERIFY_EQUAL(mpt::rshift_signed( 2, 14), mpt::rshift_signed_standard( 2, 14)); VERIFY_EQUAL(mpt::rshift_signed( 32766, 14), mpt::rshift_signed_standard( 32766, 14)); VERIFY_EQUAL(mpt::rshift_signed( 32767, 14), mpt::rshift_signed_standard( 32767, 14)); VERIFY_EQUAL(mpt::rshift_signed(-32768, 15), mpt::rshift_signed_standard(-32768, 15)); VERIFY_EQUAL(mpt::rshift_signed(-32767, 15), mpt::rshift_signed_standard(-32767, 15)); VERIFY_EQUAL(mpt::rshift_signed(-32766, 15), mpt::rshift_signed_standard(-32766, 15)); VERIFY_EQUAL(mpt::rshift_signed( -2, 15), mpt::rshift_signed_standard( -2, 15)); VERIFY_EQUAL(mpt::rshift_signed( -1, 15), mpt::rshift_signed_standard( -1, 15)); VERIFY_EQUAL(mpt::rshift_signed( 0, 15), mpt::rshift_signed_standard( 0, 15)); VERIFY_EQUAL(mpt::rshift_signed( 1, 15), mpt::rshift_signed_standard( 1, 15)); VERIFY_EQUAL(mpt::rshift_signed( 2, 15), mpt::rshift_signed_standard( 2, 15)); VERIFY_EQUAL(mpt::rshift_signed( 32766, 15), mpt::rshift_signed_standard( 32766, 15)); VERIFY_EQUAL(mpt::rshift_signed( 32767, 15), mpt::rshift_signed_standard( 32767, 15)); VERIFY_EQUAL(mpt::lshift_signed(-32768, 1), mpt::lshift_signed_standard(-32768, 1)); VERIFY_EQUAL(mpt::lshift_signed(-32767, 1), mpt::lshift_signed_standard(-32767, 1)); VERIFY_EQUAL(mpt::lshift_signed(-32766, 1), mpt::lshift_signed_standard(-32766, 1)); VERIFY_EQUAL(mpt::lshift_signed( -2, 1), mpt::lshift_signed_standard( -2, 1)); VERIFY_EQUAL(mpt::lshift_signed( -1, 1), mpt::lshift_signed_standard( -1, 1)); VERIFY_EQUAL(mpt::lshift_signed( 0, 1), mpt::lshift_signed_standard( 0, 1)); VERIFY_EQUAL(mpt::lshift_signed( 1, 1), mpt::lshift_signed_standard( 1, 1)); VERIFY_EQUAL(mpt::lshift_signed( 2, 1), mpt::lshift_signed_standard( 2, 1)); VERIFY_EQUAL(mpt::lshift_signed( 32766, 1), mpt::lshift_signed_standard( 32766, 1)); VERIFY_EQUAL(mpt::lshift_signed( 32767, 1), mpt::lshift_signed_standard( 32767, 1)); VERIFY_EQUAL(mpt::lshift_signed(-32768, 14), mpt::lshift_signed_standard(-32768, 14)); VERIFY_EQUAL(mpt::lshift_signed(-32767, 14), mpt::lshift_signed_standard(-32767, 14)); VERIFY_EQUAL(mpt::lshift_signed(-32766, 14), mpt::lshift_signed_standard(-32766, 14)); VERIFY_EQUAL(mpt::lshift_signed( -2, 14), mpt::lshift_signed_standard( -2, 14)); VERIFY_EQUAL(mpt::lshift_signed( -1, 14), mpt::lshift_signed_standard( -1, 14)); VERIFY_EQUAL(mpt::lshift_signed( 0, 14), mpt::lshift_signed_standard( 0, 14)); VERIFY_EQUAL(mpt::lshift_signed( 1, 14), mpt::lshift_signed_standard( 1, 14)); VERIFY_EQUAL(mpt::lshift_signed( 2, 14), mpt::lshift_signed_standard( 2, 14)); VERIFY_EQUAL(mpt::lshift_signed( 32766, 14), mpt::lshift_signed_standard( 32766, 14)); VERIFY_EQUAL(mpt::lshift_signed( 32767, 14), mpt::lshift_signed_standard( 32767, 14)); VERIFY_EQUAL(mpt::lshift_signed(-32768, 15), mpt::lshift_signed_standard(-32768, 15)); VERIFY_EQUAL(mpt::lshift_signed(-32767, 15), mpt::lshift_signed_standard(-32767, 15)); VERIFY_EQUAL(mpt::lshift_signed(-32766, 15), mpt::lshift_signed_standard(-32766, 15)); VERIFY_EQUAL(mpt::lshift_signed( -2, 15), mpt::lshift_signed_standard( -2, 15)); VERIFY_EQUAL(mpt::lshift_signed( -1, 15), mpt::lshift_signed_standard( -1, 15)); VERIFY_EQUAL(mpt::lshift_signed( 0, 15), mpt::lshift_signed_standard( 0, 15)); VERIFY_EQUAL(mpt::lshift_signed( 1, 15), mpt::lshift_signed_standard( 1, 15)); VERIFY_EQUAL(mpt::lshift_signed( 2, 15), mpt::lshift_signed_standard( 2, 15)); VERIFY_EQUAL(mpt::lshift_signed( 32766, 15), mpt::lshift_signed_standard( 32766, 15)); VERIFY_EQUAL(mpt::lshift_signed( 32767, 15), mpt::lshift_signed_standard( 32767, 15)); #if MPT_COMPILER_SHIFT_SIGNED VERIFY_EQUAL(mpt::rshift_signed(-32768, 1), (-32768) >> 1); VERIFY_EQUAL(mpt::rshift_signed(-32767, 1), (-32767) >> 1); VERIFY_EQUAL(mpt::rshift_signed(-32766, 1), (-32766) >> 1); VERIFY_EQUAL(mpt::rshift_signed( -2, 1), ( -2) >> 1); VERIFY_EQUAL(mpt::rshift_signed( -1, 1), ( -1) >> 1); VERIFY_EQUAL(mpt::rshift_signed( 0, 1), ( 0) >> 1); VERIFY_EQUAL(mpt::rshift_signed( 1, 1), ( 1) >> 1); VERIFY_EQUAL(mpt::rshift_signed( 2, 1), ( 2) >> 1); VERIFY_EQUAL(mpt::rshift_signed( 32766, 1), ( 32766) >> 1); VERIFY_EQUAL(mpt::rshift_signed( 32767, 1), ( 32767) >> 1); VERIFY_EQUAL(mpt::rshift_signed(-32768, 14), (-32768) >> 14); VERIFY_EQUAL(mpt::rshift_signed(-32767, 14), (-32767) >> 14); VERIFY_EQUAL(mpt::rshift_signed(-32766, 14), (-32766) >> 14); VERIFY_EQUAL(mpt::rshift_signed( -2, 14), ( -2) >> 14); VERIFY_EQUAL(mpt::rshift_signed( -1, 14), ( -1) >> 14); VERIFY_EQUAL(mpt::rshift_signed( 0, 14), ( 0) >> 14); VERIFY_EQUAL(mpt::rshift_signed( 1, 14), ( 1) >> 14); VERIFY_EQUAL(mpt::rshift_signed( 2, 14), ( 2) >> 14); VERIFY_EQUAL(mpt::rshift_signed( 32766, 14), ( 32766) >> 14); VERIFY_EQUAL(mpt::rshift_signed( 32767, 14), ( 32767) >> 14); VERIFY_EQUAL(mpt::rshift_signed(-32768, 15), (-32768) >> 15); VERIFY_EQUAL(mpt::rshift_signed(-32767, 15), (-32767) >> 15); VERIFY_EQUAL(mpt::rshift_signed(-32766, 15), (-32766) >> 15); VERIFY_EQUAL(mpt::rshift_signed( -2, 15), ( -2) >> 15); VERIFY_EQUAL(mpt::rshift_signed( -1, 15), ( -1) >> 15); VERIFY_EQUAL(mpt::rshift_signed( 0, 15), ( 0) >> 15); VERIFY_EQUAL(mpt::rshift_signed( 1, 15), ( 1) >> 15); VERIFY_EQUAL(mpt::rshift_signed( 2, 15), ( 2) >> 15); VERIFY_EQUAL(mpt::rshift_signed( 32766, 15), ( 32766) >> 15); VERIFY_EQUAL(mpt::rshift_signed( 32767, 15), ( 32767) >> 15); VERIFY_EQUAL(mpt::lshift_signed(-32768, 1), (-32768) << 1); VERIFY_EQUAL(mpt::lshift_signed(-32767, 1), (-32767) << 1); VERIFY_EQUAL(mpt::lshift_signed(-32766, 1), (-32766) << 1); VERIFY_EQUAL(mpt::lshift_signed( -2, 1), ( -2) << 1); VERIFY_EQUAL(mpt::lshift_signed( -1, 1), ( -1) << 1); VERIFY_EQUAL(mpt::lshift_signed( 0, 1), ( 0) << 1); VERIFY_EQUAL(mpt::lshift_signed( 1, 1), ( 1) << 1); VERIFY_EQUAL(mpt::lshift_signed( 2, 1), ( 2) << 1); VERIFY_EQUAL(mpt::lshift_signed( 32766, 1), ( 32766) << 1); VERIFY_EQUAL(mpt::lshift_signed( 32767, 1), ( 32767) << 1); VERIFY_EQUAL(mpt::lshift_signed(-32768, 14), (-32768) << 14); VERIFY_EQUAL(mpt::lshift_signed(-32767, 14), (-32767) << 14); VERIFY_EQUAL(mpt::lshift_signed(-32766, 14), (-32766) << 14); VERIFY_EQUAL(mpt::lshift_signed( -2, 14), ( -2) << 14); VERIFY_EQUAL(mpt::lshift_signed( -1, 14), ( -1) << 14); VERIFY_EQUAL(mpt::lshift_signed( 0, 14), ( 0) << 14); VERIFY_EQUAL(mpt::lshift_signed( 1, 14), ( 1) << 14); VERIFY_EQUAL(mpt::lshift_signed( 2, 14), ( 2) << 14); VERIFY_EQUAL(mpt::lshift_signed( 32766, 14), ( 32766) << 14); VERIFY_EQUAL(mpt::lshift_signed( 32767, 14), ( 32767) << 14); VERIFY_EQUAL(mpt::lshift_signed(-32768, 15), (-32768) << 15); VERIFY_EQUAL(mpt::lshift_signed(-32767, 15), (-32767) << 15); VERIFY_EQUAL(mpt::lshift_signed(-32766, 15), (-32766) << 15); VERIFY_EQUAL(mpt::lshift_signed( -2, 15), ( -2) << 15); VERIFY_EQUAL(mpt::lshift_signed( -1, 15), ( -1) << 15); VERIFY_EQUAL(mpt::lshift_signed( 0, 15), ( 0) << 15); VERIFY_EQUAL(mpt::lshift_signed( 1, 15), ( 1) << 15); VERIFY_EQUAL(mpt::lshift_signed( 2, 15), ( 2) << 15); VERIFY_EQUAL(mpt::lshift_signed( 32766, 15), ( 32766) << 15); VERIFY_EQUAL(mpt::lshift_signed( 32767, 15), ( 32767) << 15); #endif VERIFY_EQUAL(mpt::rshift_signed(0-0x80000000, 1), mpt::rshift_signed_standard(0-0x80000000, 1)); VERIFY_EQUAL(mpt::rshift_signed(-0x7fffffff, 1), mpt::rshift_signed_standard(-0x7fffffff, 1)); VERIFY_EQUAL(mpt::rshift_signed(-0x7ffffffe, 1), mpt::rshift_signed_standard(-0x7ffffffe, 1)); VERIFY_EQUAL(mpt::rshift_signed( -1, 1), mpt::rshift_signed_standard( -1, 1)); VERIFY_EQUAL(mpt::rshift_signed( 0, 1), mpt::rshift_signed_standard( 0, 1)); VERIFY_EQUAL(mpt::rshift_signed( 1, 1), mpt::rshift_signed_standard( 1, 1)); VERIFY_EQUAL(mpt::rshift_signed( 0x7ffffffe, 1), mpt::rshift_signed_standard( 0x7ffffffe, 1)); VERIFY_EQUAL(mpt::rshift_signed( 0x7fffffff, 1), mpt::rshift_signed_standard( 0x7fffffff, 1)); VERIFY_EQUAL(mpt::rshift_signed(0-0x80000000, 31), mpt::rshift_signed_standard(0-0x80000000, 31)); VERIFY_EQUAL(mpt::rshift_signed(-0x7fffffff, 31), mpt::rshift_signed_standard(-0x7fffffff, 31)); VERIFY_EQUAL(mpt::rshift_signed(-0x7ffffffe, 31), mpt::rshift_signed_standard(-0x7ffffffe, 31)); VERIFY_EQUAL(mpt::rshift_signed( -1, 31), mpt::rshift_signed_standard( -1, 31)); VERIFY_EQUAL(mpt::rshift_signed( 0, 31), mpt::rshift_signed_standard( 0, 31)); VERIFY_EQUAL(mpt::rshift_signed( 1, 31), mpt::rshift_signed_standard( 1, 31)); VERIFY_EQUAL(mpt::rshift_signed( 0x7ffffffe, 31), mpt::rshift_signed_standard( 0x7ffffffe, 31)); VERIFY_EQUAL(mpt::rshift_signed( 0x7fffffff, 31), mpt::rshift_signed_standard( 0x7fffffff, 31)); VERIFY_EQUAL(mpt::lshift_signed(0-0x80000000, 1), mpt::lshift_signed_standard(0-0x80000000, 1)); VERIFY_EQUAL(mpt::lshift_signed(-0x7fffffff, 1), mpt::lshift_signed_standard(-0x7fffffff, 1)); VERIFY_EQUAL(mpt::lshift_signed(-0x7ffffffe, 1), mpt::lshift_signed_standard(-0x7ffffffe, 1)); VERIFY_EQUAL(mpt::lshift_signed( -1, 1), mpt::lshift_signed_standard( -1, 1)); VERIFY_EQUAL(mpt::lshift_signed( 0, 1), mpt::lshift_signed_standard( 0, 1)); VERIFY_EQUAL(mpt::lshift_signed( 1, 1), mpt::lshift_signed_standard( 1, 1)); VERIFY_EQUAL(mpt::lshift_signed( 0x7ffffffe, 1), mpt::lshift_signed_standard( 0x7ffffffe, 1)); VERIFY_EQUAL(mpt::lshift_signed( 0x7fffffff, 1), mpt::lshift_signed_standard( 0x7fffffff, 1)); VERIFY_EQUAL(mpt::lshift_signed(0-0x80000000, 31), mpt::lshift_signed_standard(0-0x80000000, 31)); VERIFY_EQUAL(mpt::lshift_signed(-0x7fffffff, 31), mpt::lshift_signed_standard(-0x7fffffff, 31)); VERIFY_EQUAL(mpt::lshift_signed(-0x7ffffffe, 31), mpt::lshift_signed_standard(-0x7ffffffe, 31)); VERIFY_EQUAL(mpt::lshift_signed( -1, 31), mpt::lshift_signed_standard( -1, 31)); VERIFY_EQUAL(mpt::lshift_signed( 0, 31), mpt::lshift_signed_standard( 0, 31)); VERIFY_EQUAL(mpt::lshift_signed( 1, 31), mpt::lshift_signed_standard( 1, 31)); VERIFY_EQUAL(mpt::lshift_signed( 0x7ffffffe, 31), mpt::lshift_signed_standard( 0x7ffffffe, 31)); VERIFY_EQUAL(mpt::lshift_signed( 0x7fffffff, 31), mpt::lshift_signed_standard( 0x7fffffff, 31)); #if MPT_COMPILER_SHIFT_SIGNED VERIFY_EQUAL(mpt::rshift_signed(0-0x80000000, 1), mpt::rshift_signed_undefined(0-0x80000000, 1)); VERIFY_EQUAL(mpt::rshift_signed(-0x7fffffff, 1), mpt::rshift_signed_undefined(-0x7fffffff, 1)); VERIFY_EQUAL(mpt::rshift_signed(-0x7ffffffe, 1), mpt::rshift_signed_undefined(-0x7ffffffe, 1)); VERIFY_EQUAL(mpt::rshift_signed( -1, 1), mpt::rshift_signed_undefined( -1, 1)); VERIFY_EQUAL(mpt::rshift_signed( 0, 1), mpt::rshift_signed_undefined( 0, 1)); VERIFY_EQUAL(mpt::rshift_signed( 1, 1), mpt::rshift_signed_undefined( 1, 1)); VERIFY_EQUAL(mpt::rshift_signed( 0x7ffffffe, 1), mpt::rshift_signed_undefined( 0x7ffffffe, 1)); VERIFY_EQUAL(mpt::rshift_signed( 0x7fffffff, 1), mpt::rshift_signed_undefined( 0x7fffffff, 1)); VERIFY_EQUAL(mpt::rshift_signed(0-0x80000000, 31), mpt::rshift_signed_undefined(0-0x80000000, 31)); VERIFY_EQUAL(mpt::rshift_signed(-0x7fffffff, 31), mpt::rshift_signed_undefined(-0x7fffffff, 31)); VERIFY_EQUAL(mpt::rshift_signed(-0x7ffffffe, 31), mpt::rshift_signed_undefined(-0x7ffffffe, 31)); VERIFY_EQUAL(mpt::rshift_signed( -1, 31), mpt::rshift_signed_undefined( -1, 31)); VERIFY_EQUAL(mpt::rshift_signed( 0, 31), mpt::rshift_signed_undefined( 0, 31)); VERIFY_EQUAL(mpt::rshift_signed( 1, 31), mpt::rshift_signed_undefined( 1, 31)); VERIFY_EQUAL(mpt::rshift_signed( 0x7ffffffe, 31), mpt::rshift_signed_undefined( 0x7ffffffe, 31)); VERIFY_EQUAL(mpt::rshift_signed( 0x7fffffff, 31), mpt::rshift_signed_undefined( 0x7fffffff, 31)); VERIFY_EQUAL(mpt::lshift_signed(0-0x80000000, 1), mpt::lshift_signed_undefined(0-0x80000000, 1)); VERIFY_EQUAL(mpt::lshift_signed(-0x7fffffff, 1), mpt::lshift_signed_undefined(-0x7fffffff, 1)); VERIFY_EQUAL(mpt::lshift_signed(-0x7ffffffe, 1), mpt::lshift_signed_undefined(-0x7ffffffe, 1)); VERIFY_EQUAL(mpt::lshift_signed( -1, 1), mpt::lshift_signed_undefined( -1, 1)); VERIFY_EQUAL(mpt::lshift_signed( 0, 1), mpt::lshift_signed_undefined( 0, 1)); VERIFY_EQUAL(mpt::lshift_signed( 1, 1), mpt::lshift_signed_undefined( 1, 1)); VERIFY_EQUAL(mpt::lshift_signed( 0x7ffffffe, 1), mpt::lshift_signed_undefined( 0x7ffffffe, 1)); VERIFY_EQUAL(mpt::lshift_signed( 0x7fffffff, 1), mpt::lshift_signed_undefined( 0x7fffffff, 1)); VERIFY_EQUAL(mpt::lshift_signed(0-0x80000000, 31), mpt::lshift_signed_undefined(0-0x80000000, 31)); VERIFY_EQUAL(mpt::lshift_signed(-0x7fffffff, 31), mpt::lshift_signed_undefined(-0x7fffffff, 31)); VERIFY_EQUAL(mpt::lshift_signed(-0x7ffffffe, 31), mpt::lshift_signed_undefined(-0x7ffffffe, 31)); VERIFY_EQUAL(mpt::lshift_signed( -1, 31), mpt::lshift_signed_undefined( -1, 31)); VERIFY_EQUAL(mpt::lshift_signed( 0, 31), mpt::lshift_signed_undefined( 0, 31)); VERIFY_EQUAL(mpt::lshift_signed( 1, 31), mpt::lshift_signed_undefined( 1, 31)); VERIFY_EQUAL(mpt::lshift_signed( 0x7ffffffe, 31), mpt::lshift_signed_undefined( 0x7ffffffe, 31)); VERIFY_EQUAL(mpt::lshift_signed( 0x7fffffff, 31), mpt::lshift_signed_undefined( 0x7fffffff, 31)); #endif VERIFY_EQUAL(mpt::rshift_signed(-0x8000000000000000ll, 1), mpt::rshift_signed_standard(-0x8000000000000000ll, 1)); VERIFY_EQUAL(mpt::rshift_signed(-0x7fffffffffffffffll, 1), mpt::rshift_signed_standard(-0x7fffffffffffffffll, 1)); VERIFY_EQUAL(mpt::rshift_signed(-0x7ffffffffffffffell, 1), mpt::rshift_signed_standard(-0x7ffffffffffffffell, 1)); VERIFY_EQUAL(mpt::rshift_signed( -1ll, 1), mpt::rshift_signed_standard( -1ll, 1)); VERIFY_EQUAL(mpt::rshift_signed( 0ll, 1), mpt::rshift_signed_standard( 0ll, 1)); VERIFY_EQUAL(mpt::rshift_signed( 1ll, 1), mpt::rshift_signed_standard( 1ll, 1)); VERIFY_EQUAL(mpt::rshift_signed( 0x7ffffffffffffffell, 1), mpt::rshift_signed_standard( 0x7ffffffffffffffell, 1)); VERIFY_EQUAL(mpt::rshift_signed( 0x7fffffffffffffffll, 1), mpt::rshift_signed_standard( 0x7fffffffffffffffll, 1)); VERIFY_EQUAL(mpt::rshift_signed(-0x8000000000000000ll, 63), mpt::rshift_signed_standard(-0x8000000000000000ll, 63)); VERIFY_EQUAL(mpt::rshift_signed(-0x7fffffffffffffffll, 63), mpt::rshift_signed_standard(-0x7fffffffffffffffll, 63)); VERIFY_EQUAL(mpt::rshift_signed(-0x7ffffffffffffffell, 63), mpt::rshift_signed_standard(-0x7ffffffffffffffell, 63)); VERIFY_EQUAL(mpt::rshift_signed( -1ll, 63), mpt::rshift_signed_standard( -1ll, 63)); VERIFY_EQUAL(mpt::rshift_signed( 0ll, 63), mpt::rshift_signed_standard( 0ll, 63)); VERIFY_EQUAL(mpt::rshift_signed( 1ll, 63), mpt::rshift_signed_standard( 1ll, 63)); VERIFY_EQUAL(mpt::rshift_signed( 0x7ffffffffffffffell, 63), mpt::rshift_signed_standard( 0x7ffffffffffffffell, 63)); VERIFY_EQUAL(mpt::rshift_signed( 0x7fffffffffffffffll, 63), mpt::rshift_signed_standard( 0x7fffffffffffffffll, 63)); VERIFY_EQUAL(mpt::lshift_signed(-0x8000000000000000ll, 1), mpt::lshift_signed_standard(-0x8000000000000000ll, 1)); VERIFY_EQUAL(mpt::lshift_signed(-0x7fffffffffffffffll, 1), mpt::lshift_signed_standard(-0x7fffffffffffffffll, 1)); VERIFY_EQUAL(mpt::lshift_signed(-0x7ffffffffffffffell, 1), mpt::lshift_signed_standard(-0x7ffffffffffffffell, 1)); VERIFY_EQUAL(mpt::lshift_signed( -1ll, 1), mpt::lshift_signed_standard( -1ll, 1)); VERIFY_EQUAL(mpt::lshift_signed( 0ll, 1), mpt::lshift_signed_standard( 0ll, 1)); VERIFY_EQUAL(mpt::lshift_signed( 1ll, 1), mpt::lshift_signed_standard( 1ll, 1)); VERIFY_EQUAL(mpt::lshift_signed( 0x7ffffffffffffffell, 1), mpt::lshift_signed_standard( 0x7ffffffffffffffell, 1)); VERIFY_EQUAL(mpt::lshift_signed( 0x7fffffffffffffffll, 1), mpt::lshift_signed_standard( 0x7fffffffffffffffll, 1)); VERIFY_EQUAL(mpt::lshift_signed(-0x8000000000000000ll, 63), mpt::lshift_signed_standard(-0x8000000000000000ll, 63)); VERIFY_EQUAL(mpt::lshift_signed(-0x7fffffffffffffffll, 63), mpt::lshift_signed_standard(-0x7fffffffffffffffll, 63)); VERIFY_EQUAL(mpt::lshift_signed(-0x7ffffffffffffffell, 63), mpt::lshift_signed_standard(-0x7ffffffffffffffell, 63)); VERIFY_EQUAL(mpt::lshift_signed( -1ll, 63), mpt::lshift_signed_standard( -1ll, 63)); VERIFY_EQUAL(mpt::lshift_signed( 0ll, 63), mpt::lshift_signed_standard( 0ll, 63)); VERIFY_EQUAL(mpt::lshift_signed( 1ll, 63), mpt::lshift_signed_standard( 1ll, 63)); VERIFY_EQUAL(mpt::lshift_signed( 0x7ffffffffffffffell, 63), mpt::lshift_signed_standard( 0x7ffffffffffffffell, 63)); VERIFY_EQUAL(mpt::lshift_signed( 0x7fffffffffffffffll, 63), mpt::lshift_signed_standard( 0x7fffffffffffffffll, 63)); #if MPT_COMPILER_SHIFT_SIGNED VERIFY_EQUAL(mpt::rshift_signed(-0x8000000000000000ll, 1), mpt::rshift_signed_undefined(-0x8000000000000000ll, 1)); VERIFY_EQUAL(mpt::rshift_signed(-0x7fffffffffffffffll, 1), mpt::rshift_signed_undefined(-0x7fffffffffffffffll, 1)); VERIFY_EQUAL(mpt::rshift_signed(-0x7ffffffffffffffell, 1), mpt::rshift_signed_undefined(-0x7ffffffffffffffell, 1)); VERIFY_EQUAL(mpt::rshift_signed( -1ll, 1), mpt::rshift_signed_undefined( -1ll, 1)); VERIFY_EQUAL(mpt::rshift_signed( 0ll, 1), mpt::rshift_signed_undefined( 0ll, 1)); VERIFY_EQUAL(mpt::rshift_signed( 1ll, 1), mpt::rshift_signed_undefined( 1ll, 1)); VERIFY_EQUAL(mpt::rshift_signed( 0x7ffffffffffffffell, 1), mpt::rshift_signed_undefined( 0x7ffffffffffffffell, 1)); VERIFY_EQUAL(mpt::rshift_signed( 0x7fffffffffffffffll, 1), mpt::rshift_signed_undefined( 0x7fffffffffffffffll, 1)); VERIFY_EQUAL(mpt::rshift_signed(-0x8000000000000000ll, 63), mpt::rshift_signed_undefined(-0x8000000000000000ll, 63)); VERIFY_EQUAL(mpt::rshift_signed(-0x7fffffffffffffffll, 63), mpt::rshift_signed_undefined(-0x7fffffffffffffffll, 63)); VERIFY_EQUAL(mpt::rshift_signed(-0x7ffffffffffffffell, 63), mpt::rshift_signed_undefined(-0x7ffffffffffffffell, 63)); VERIFY_EQUAL(mpt::rshift_signed( -1ll, 63), mpt::rshift_signed_undefined( -1ll, 63)); VERIFY_EQUAL(mpt::rshift_signed( 0ll, 63), mpt::rshift_signed_undefined( 0ll, 63)); VERIFY_EQUAL(mpt::rshift_signed( 1ll, 63), mpt::rshift_signed_undefined( 1ll, 63)); VERIFY_EQUAL(mpt::rshift_signed( 0x7ffffffffffffffell, 63), mpt::rshift_signed_undefined( 0x7ffffffffffffffell, 63)); VERIFY_EQUAL(mpt::rshift_signed( 0x7fffffffffffffffll, 63), mpt::rshift_signed_undefined( 0x7fffffffffffffffll, 63)); VERIFY_EQUAL(mpt::lshift_signed(-0x8000000000000000ll, 1), mpt::lshift_signed_undefined(-0x8000000000000000ll, 1)); VERIFY_EQUAL(mpt::lshift_signed(-0x7fffffffffffffffll, 1), mpt::lshift_signed_undefined(-0x7fffffffffffffffll, 1)); VERIFY_EQUAL(mpt::lshift_signed(-0x7ffffffffffffffell, 1), mpt::lshift_signed_undefined(-0x7ffffffffffffffell, 1)); VERIFY_EQUAL(mpt::lshift_signed( -1ll, 1), mpt::lshift_signed_undefined( -1ll, 1)); VERIFY_EQUAL(mpt::lshift_signed( 0ll, 1), mpt::lshift_signed_undefined( 0ll, 1)); VERIFY_EQUAL(mpt::lshift_signed( 1ll, 1), mpt::lshift_signed_undefined( 1ll, 1)); VERIFY_EQUAL(mpt::lshift_signed( 0x7ffffffffffffffell, 1), mpt::lshift_signed_undefined( 0x7ffffffffffffffell, 1)); VERIFY_EQUAL(mpt::lshift_signed( 0x7fffffffffffffffll, 1), mpt::lshift_signed_undefined( 0x7fffffffffffffffll, 1)); VERIFY_EQUAL(mpt::lshift_signed(-0x8000000000000000ll, 63), mpt::lshift_signed_undefined(-0x8000000000000000ll, 63)); VERIFY_EQUAL(mpt::lshift_signed(-0x7fffffffffffffffll, 63), mpt::lshift_signed_undefined(-0x7fffffffffffffffll, 63)); VERIFY_EQUAL(mpt::lshift_signed(-0x7ffffffffffffffell, 63), mpt::lshift_signed_undefined(-0x7ffffffffffffffell, 63)); VERIFY_EQUAL(mpt::lshift_signed( -1ll, 63), mpt::lshift_signed_undefined( -1ll, 63)); VERIFY_EQUAL(mpt::lshift_signed( 0ll, 63), mpt::lshift_signed_undefined( 0ll, 63)); VERIFY_EQUAL(mpt::lshift_signed( 1ll, 63), mpt::lshift_signed_undefined( 1ll, 63)); VERIFY_EQUAL(mpt::lshift_signed( 0x7ffffffffffffffell, 63), mpt::lshift_signed_undefined( 0x7ffffffffffffffell, 63)); VERIFY_EQUAL(mpt::lshift_signed( 0x7fffffffffffffffll, 63), mpt::lshift_signed_undefined( 0x7fffffffffffffffll, 63)); #endif VERIFY_EQUAL(mpt::wrapping_modulo(-25, 12), 11); VERIFY_EQUAL(mpt::wrapping_modulo(-24, 12), 0); VERIFY_EQUAL(mpt::wrapping_modulo(-23, 12), 1); VERIFY_EQUAL(mpt::wrapping_modulo(-8, 7), 6); VERIFY_EQUAL(mpt::wrapping_modulo(-7, 7), 0); VERIFY_EQUAL(mpt::wrapping_modulo(-6, 7), 1); VERIFY_EQUAL(mpt::wrapping_modulo(-5, 7), 2); VERIFY_EQUAL(mpt::wrapping_modulo(-4, 7), 3); VERIFY_EQUAL(mpt::wrapping_modulo(-3, 7), 4); VERIFY_EQUAL(mpt::wrapping_modulo(-2, 7), 5); VERIFY_EQUAL(mpt::wrapping_modulo(-1, 7), 6); VERIFY_EQUAL(mpt::wrapping_modulo(0, 12), 0); VERIFY_EQUAL(mpt::wrapping_modulo(0, 7), 0); VERIFY_EQUAL(mpt::wrapping_modulo(1, 7), 1); VERIFY_EQUAL(mpt::wrapping_modulo(2, 7), 2); VERIFY_EQUAL(mpt::wrapping_modulo(3, 7), 3); VERIFY_EQUAL(mpt::wrapping_modulo(4, 7), 4); VERIFY_EQUAL(mpt::wrapping_modulo(5, 7), 5); VERIFY_EQUAL(mpt::wrapping_modulo(6, 7), 6); VERIFY_EQUAL(mpt::wrapping_modulo(7, 7), 0); VERIFY_EQUAL(mpt::wrapping_modulo(8, 7), 1); VERIFY_EQUAL(mpt::wrapping_modulo(23, 12), 11); VERIFY_EQUAL(mpt::wrapping_modulo(24, 12), 0); VERIFY_EQUAL(mpt::wrapping_modulo(25, 12), 1); VERIFY_EQUAL(mpt::wrapping_modulo(uint32(0x7fffffff), uint32(0x80000000)), uint32(0x7fffffff)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(0x7ffffffe), int32(0x7fffffff)), int32(0x7ffffffe)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x80000000ll), int32(1)), int32(0)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x80000000ll), int32(2)), int32(0)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x7fffffff), int32(1)), int32(0)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x7fffffff), int32(2)), int32(1)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x7ffffffe), int32(1)), int32(0)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x7ffffffe), int32(2)), int32(0)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x80000000ll), int32(0x7fffffff)), int32(0x7ffffffe)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x7fffffff) , int32(0x7fffffff)), int32(0)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x7ffffffe) , int32(0x7fffffff)), int32(1)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x80000000ll), int32(0x7ffffffe)), int32(0x7ffffffc)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x7fffffff) , int32(0x7ffffffe)), int32(0x7ffffffd)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x7ffffffe) , int32(0x7ffffffe)), int32(0)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x80000000ll), int32(0x7ffffffd)), int32(0x7ffffffa)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x7fffffff) , int32(0x7ffffffd)), int32(0x7ffffffb)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x7ffffffe) , int32(0x7ffffffd)), int32(0x7ffffffc)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(0) , int32(0x7fffffff)), int32(0)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-1), int32(0x7fffffff)), int32(0x7ffffffe)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-2), int32(0x7fffffff)), int32(0x7ffffffd)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(0) , int32(0x7ffffffe)), int32(0)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-1), int32(0x7ffffffe)), int32(0x7ffffffd)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-2), int32(0x7ffffffe)), int32(0x7ffffffc)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x80000000ll), uint32(1)), int32(0)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x80000000ll), uint32(2)), int32(0)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x7fffffff), uint32(1)), int32(0)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x7fffffff), uint32(2)), int32(1)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x7ffffffe), uint32(1)), int32(0)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x7ffffffe), uint32(2)), int32(0)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x40000001) , uint32(0xffffffff)), uint32(0xbffffffe)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x40000000) , uint32(0xffffffff)), uint32(0xbfffffff)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x3fffffff) , uint32(0xffffffff)), uint32(0xc0000000)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x80000000ll), uint32(0x80000000)), uint32(0)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x7fffffff) , uint32(0x80000000)), uint32(1)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x7ffffffe) , uint32(0x80000000)), uint32(2)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x80000000ll), uint32(0x80000001)), uint32(1)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x7fffffff) , uint32(0x80000001)), uint32(2)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x7ffffffe) , uint32(0x80000001)), uint32(3)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x80000000ll), uint32(0x80000000)), uint32(0)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x7fffffff) , uint32(0x80000000)), uint32(1)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x7ffffffe) , uint32(0x80000000)), uint32(2)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x80000000ll), uint32(0x7fffffff)), uint32(0x7ffffffe)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x7fffffff) , uint32(0x7fffffff)), uint32(0)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x7ffffffe) , uint32(0x7fffffff)), uint32(1)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x80000000ll), uint32(0x7ffffffe)), uint32(0x7ffffffc)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x7fffffff) , uint32(0x7ffffffe)), uint32(0x7ffffffd)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x7ffffffe) , uint32(0x7ffffffe)), uint32(0)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x80000000ll), uint32(0x7ffffffd)), uint32(0x7ffffffa)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x7fffffff) , uint32(0x7ffffffd)), uint32(0x7ffffffb)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-0x7ffffffe) , uint32(0x7ffffffd)), uint32(0x7ffffffc)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(0) , uint32(0x7fffffff)), uint32(0)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-1), uint32(0x7fffffff)), uint32(0x7ffffffe)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-2), uint32(0x7fffffff)), uint32(0x7ffffffd)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(0) , uint32(0x7ffffffe)), uint32(0)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-1), uint32(0x7ffffffe)), uint32(0x7ffffffd)); VERIFY_EQUAL(mpt::wrapping_modulo(int32(-2), uint32(0x7ffffffe)), uint32(0x7ffffffc)); VERIFY_EQUAL(mpt::wrapping_divide(-15, 7), -3); VERIFY_EQUAL(mpt::wrapping_divide(-14, 7), -2); VERIFY_EQUAL(mpt::wrapping_divide(-13, 7), -2); VERIFY_EQUAL(mpt::wrapping_divide(-12, 7), -2); VERIFY_EQUAL(mpt::wrapping_divide(-11, 7), -2); VERIFY_EQUAL(mpt::wrapping_divide(-10, 7), -2); VERIFY_EQUAL(mpt::wrapping_divide(-9, 7), -2); VERIFY_EQUAL(mpt::wrapping_divide(-8, 7), -2); VERIFY_EQUAL(mpt::wrapping_divide(-7, 7), -1); VERIFY_EQUAL(mpt::wrapping_divide(-6, 7), -1); VERIFY_EQUAL(mpt::wrapping_divide(-5, 7), -1); VERIFY_EQUAL(mpt::wrapping_divide(-4, 7), -1); VERIFY_EQUAL(mpt::wrapping_divide(-3, 7), -1); VERIFY_EQUAL(mpt::wrapping_divide(-2, 7), -1); VERIFY_EQUAL(mpt::wrapping_divide(-1, 7), -1); VERIFY_EQUAL(mpt::wrapping_divide(0, 7), 0); VERIFY_EQUAL(mpt::wrapping_divide(1, 7), 0); VERIFY_EQUAL(mpt::wrapping_divide(2, 7), 0); VERIFY_EQUAL(mpt::wrapping_divide(3, 7), 0); VERIFY_EQUAL(mpt::wrapping_divide(4, 7), 0); VERIFY_EQUAL(mpt::wrapping_divide(5, 7), 0); VERIFY_EQUAL(mpt::wrapping_divide(6, 7), 0); VERIFY_EQUAL(mpt::wrapping_divide(7, 7), 1); VERIFY_EQUAL(mpt::wrapping_divide(8, 7), 1); VERIFY_EQUAL(mpt::wrapping_divide(9, 7), 1); VERIFY_EQUAL(mpt::wrapping_divide(10, 7), 1); VERIFY_EQUAL(mpt::wrapping_divide(11, 7), 1); VERIFY_EQUAL(mpt::wrapping_divide(12, 7), 1); VERIFY_EQUAL(mpt::wrapping_divide(13, 7), 1); VERIFY_EQUAL(mpt::wrapping_divide(14, 7), 2); VERIFY_EQUAL(mpt::wrapping_divide(15, 7), 2); } static MPT_NOINLINE void TestMisc2() { VERIFY_EQUAL( mpt::String::LTrim(std::string(" ")), "" ); VERIFY_EQUAL( mpt::String::RTrim(std::string(" ")), "" ); VERIFY_EQUAL( mpt::String::Trim(std::string(" ")), "" ); // weird things with std::string containing \0 in the middle and trimming \0 VERIFY_EQUAL( std::string("\0\ta\0b ",6).length(), (std::size_t)6 ); VERIFY_EQUAL( mpt::String::RTrim(std::string("\0\ta\0b ",6)), std::string("\0\ta\0b",5) ); VERIFY_EQUAL( mpt::String::Trim(std::string("\0\ta\0b\0",6),std::string("\0",1)), std::string("\ta\0b",4) ); // These should fail to compile //Util::Round(1.0); //Util::Round(1.0); //Util::Round(1.0); // This should trigger assert in Round. //VERIFY_EQUAL( Util::Round(-129), 0 ); // Check for completeness of supported effect list in mod specifications for(const auto &spec : ModSpecs::Collection) { VERIFY_EQUAL(strlen(spec->commands), (size_t)MAX_EFFECTS); VERIFY_EQUAL(strlen(spec->volcommands), (size_t)MAX_VOLCMDS); } // UUID { VERIFY_EQUAL(mpt::UUID(0x2ed6593au, 0xdfe6, 0x4cf8, 0xb2e575ad7f600c32ull).ToUString(), MPT_USTRING("2ed6593a-dfe6-4cf8-b2e5-75ad7f600c32")); #if defined(MODPLUG_TRACKER) || !defined(NO_DMO) VERIFY_EQUAL(mpt::UUID(0x2ed6593au, 0xdfe6, 0x4cf8, 0xb2e575ad7f600c32ull), MPT_UUID(2ed6593a,dfe6,4cf8,b2e5,75ad7f600c32)); VERIFY_EQUAL(mpt::UUID(0x2ed6593au, 0xdfe6, 0x4cf8, 0xb2e575ad7f600c32ull), mpt::UUID(Util::StringToGUID(L"{2ed6593a-dfe6-4cf8-b2e5-75ad7f600c32}"))); VERIFY_EQUAL(mpt::UUID(0x2ed6593au, 0xdfe6, 0x4cf8, 0xb2e575ad7f600c32ull), mpt::UUID(Util::StringToCLSID(L"{2ed6593a-dfe6-4cf8-b2e5-75ad7f600c32}"))); #endif #if defined(MODPLUG_TRACKER) || !defined(NO_DMO) VERIFY_EQUAL(Util::IsValid(Util::CreateGUID()), true); { mpt::UUID uuid = mpt::UUID::Generate(); VERIFY_EQUAL(uuid, mpt::UUID::FromString(mpt::UUID(uuid).ToUString())); VERIFY_EQUAL(uuid, mpt::UUID(Util::StringToUUID(Util::UUIDToString(uuid)))); VERIFY_EQUAL(uuid, mpt::UUID(Util::StringToGUID(Util::GUIDToString(uuid)))); VERIFY_EQUAL(uuid, mpt::UUID(Util::StringToIID(Util::IIDToString(uuid)))); VERIFY_EQUAL(uuid, mpt::UUID(Util::StringToCLSID(Util::CLSIDToString(uuid)))); } { GUID guid = mpt::UUID::Generate(); VERIFY_EQUAL(IsEqualGUID(guid, static_cast(mpt::UUID::FromString(mpt::UUID(guid).ToUString()))), TRUE); VERIFY_EQUAL(IsEqualGUID(guid, Util::StringToUUID(Util::UUIDToString(guid))), TRUE); VERIFY_EQUAL(IsEqualGUID(guid, Util::StringToGUID(Util::GUIDToString(guid))), TRUE); VERIFY_EQUAL(IsEqualGUID(guid, Util::StringToIID(Util::IIDToString(guid))), TRUE); VERIFY_EQUAL(IsEqualGUID(guid, Util::StringToCLSID(Util::CLSIDToString(guid))), TRUE); } #endif VERIFY_EQUAL(mpt::UUID::Generate().IsValid(), true); VERIFY_EQUAL(mpt::UUID::GenerateLocalUseOnly().IsValid(), true); VERIFY_EQUAL(mpt::UUID::Generate() != mpt::UUID::Generate(), true); mpt::UUID a = mpt::UUID::Generate(); VERIFY_EQUAL(a, mpt::UUID::FromString(a.ToUString())); mpt::byte uuiddata[16]; for(std::size_t i = 0; i < 16; ++i) { uuiddata[i] = static_cast(i); } STATIC_ASSERT(sizeof(mpt::UUID) == 16); mpt::UUID uuid2; std::memcpy(&uuid2, uuiddata, 16); VERIFY_EQUAL(uuid2.ToString(), std::string("00010203-0405-0607-0809-0a0b0c0d0e0f")); } // check that empty stringstream behaves correctly with our MSVC workarounds when using iostream interface directly { mpt::ostringstream ss; VERIFY_EQUAL(ss.tellp(), std::streampos(0)); } { mpt::ostringstream ss; ss.seekp(0); VERIFY_EQUAL(mpt::IO::SeekAbsolute(ss, 0), true); } { mpt::ostringstream ss; ss.seekp(0, std::ios_base::beg); VERIFY_EQUAL(!ss.fail(), true); } { mpt::ostringstream ss; ss.seekp(0, std::ios_base::cur); VERIFY_EQUAL(!ss.fail(), true); } { mpt::istringstream ss; VERIFY_EQUAL(ss.tellg(), std::streampos(0)); } { mpt::istringstream ss; ss.seekg(0); VERIFY_EQUAL(mpt::IO::SeekAbsolute(ss, 0), true); } { mpt::istringstream ss; ss.seekg(0, std::ios_base::beg); VERIFY_EQUAL(!ss.fail(), true); } { mpt::istringstream ss; ss.seekg(0, std::ios_base::cur); VERIFY_EQUAL(!ss.fail(), true); } { mpt::ostringstream s; char b = 23; VERIFY_EQUAL(!s.fail(), true); VERIFY_EQUAL(s.tellp(), std::streampos(0)); VERIFY_EQUAL(!s.fail(), true); s.seekp(0, std::ios_base::beg); VERIFY_EQUAL(!s.fail(), true); VERIFY_EQUAL(s.tellp(), std::streampos(0)); VERIFY_EQUAL(!s.fail(), true); s.write(&b, 1); VERIFY_EQUAL(!s.fail(), true); VERIFY_EQUAL(s.tellp(), std::streampos(1)); VERIFY_EQUAL(!s.fail(), true); s.seekp(0, std::ios_base::beg); VERIFY_EQUAL(!s.fail(), true); VERIFY_EQUAL(s.tellp(), std::streampos(0)); VERIFY_EQUAL(!s.fail(), true); s.seekp(0, std::ios_base::end); VERIFY_EQUAL(!s.fail(), true); VERIFY_EQUAL(s.tellp(), std::streampos(1)); VERIFY_EQUAL(!s.fail(), true); VERIFY_EQUAL(s.str(), std::string(1, b)); } { mpt::istringstream s; VERIFY_EQUAL(!s.fail(), true); VERIFY_EQUAL(s.tellg(), std::streampos(0)); VERIFY_EQUAL(!s.fail(), true); s.seekg(0, std::ios_base::beg); VERIFY_EQUAL(!s.fail(), true); VERIFY_EQUAL(s.tellg(), std::streampos(0)); VERIFY_EQUAL(!s.fail(), true); s.seekg(0, std::ios_base::end); VERIFY_EQUAL(!s.fail(), true); VERIFY_EQUAL(s.tellg(), std::streampos(0)); VERIFY_EQUAL(!s.fail(), true); } { mpt::istringstream s("a"); char a = 0; VERIFY_EQUAL(!s.fail(), true); VERIFY_EQUAL(s.tellg(), std::streampos(0)); VERIFY_EQUAL(!s.fail(), true); s.seekg(0, std::ios_base::beg); VERIFY_EQUAL(!s.fail(), true); VERIFY_EQUAL(s.tellg(), std::streampos(0)); VERIFY_EQUAL(!s.fail(), true); s.read(&a, 1); VERIFY_EQUAL(a, 'a'); VERIFY_EQUAL(!s.fail(), true); VERIFY_EQUAL(s.tellg(), std::streampos(1)); VERIFY_EQUAL(!s.fail(), true); s.seekg(0, std::ios_base::beg); VERIFY_EQUAL(!s.fail(), true); VERIFY_EQUAL(s.tellg(), std::streampos(0)); VERIFY_EQUAL(!s.fail(), true); s.seekg(0, std::ios_base::end); VERIFY_EQUAL(!s.fail(), true); VERIFY_EQUAL(s.tellg(), std::streampos(1)); VERIFY_EQUAL(!s.fail(), true); VERIFY_EQUAL(std::string(1, a), std::string(1, 'a')); } // check that empty native and fixed stringstream both behaves correctly with out IO functions { mpt::ostringstream ss; VERIFY_EQUAL(mpt::IO::TellWrite(ss), 0); } { mpt::ostringstream ss; VERIFY_EQUAL(mpt::IO::SeekBegin(ss), true); } { mpt::ostringstream ss; VERIFY_EQUAL(mpt::IO::SeekAbsolute(ss, 0), true); } { mpt::ostringstream ss; VERIFY_EQUAL(mpt::IO::SeekRelative(ss, 0), true); } { mpt::istringstream ss; VERIFY_EQUAL(mpt::IO::TellRead(ss), 0); } { mpt::istringstream ss; VERIFY_EQUAL(mpt::IO::SeekBegin(ss), true); } { mpt::istringstream ss; VERIFY_EQUAL(mpt::IO::SeekAbsolute(ss, 0), true); } { mpt::istringstream ss; VERIFY_EQUAL(mpt::IO::SeekRelative(ss, 0), true); } { std::ostringstream ss; VERIFY_EQUAL(mpt::IO::TellWrite(ss), 0); } { std::ostringstream ss; VERIFY_EQUAL(mpt::IO::SeekBegin(ss), true); } { std::ostringstream ss; VERIFY_EQUAL(mpt::IO::SeekAbsolute(ss, 0), true); } { std::ostringstream ss; VERIFY_EQUAL(mpt::IO::SeekRelative(ss, 0), true); } { std::istringstream ss; VERIFY_EQUAL(mpt::IO::TellRead(ss), 0); } { std::istringstream ss; VERIFY_EQUAL(mpt::IO::SeekBegin(ss), true); } { std::istringstream ss; VERIFY_EQUAL(mpt::IO::SeekAbsolute(ss, 0), true); } { std::istringstream ss; VERIFY_EQUAL(mpt::IO::SeekRelative(ss, 0), true); } { mpt::ostringstream s; char b = 23; VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::TellWrite(s), 0); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::SeekBegin(s), true); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::TellWrite(s), 0); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::WriteRaw(s, &b, 1), true); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::TellWrite(s), 1); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::SeekBegin(s), true); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::TellWrite(s), 0); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::SeekEnd(s), true); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::TellWrite(s), 1); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(s.str(), std::string(1, b)); } { mpt::istringstream s; VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::TellRead(s), 0); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::SeekBegin(s), true); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::TellRead(s), 0); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::SeekEnd(s), true); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::TellRead(s), 0); VERIFY_EQUAL(mpt::IO::IsValid(s), true); } { mpt::istringstream s("a"); char a = 0; VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::TellRead(s), 0); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::SeekBegin(s), true); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::TellRead(s), 0); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::ReadRaw(s, &a, 1), 1); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::TellRead(s), 1); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::SeekBegin(s), true); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::TellRead(s), 0); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::SeekEnd(s), true); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::TellRead(s), 1); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(std::string(1, a), std::string(1, 'a')); } { std::ostringstream s; char b = 23; VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::TellWrite(s), 0); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::SeekBegin(s), true); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::TellWrite(s), 0); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::WriteRaw(s, &b, 1), true); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::TellWrite(s), 1); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::SeekBegin(s), true); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::TellWrite(s), 0); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::SeekEnd(s), true); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::TellWrite(s), 1); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(s.str(), std::string(1, b)); } { std::istringstream s; VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::TellRead(s), 0); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::SeekBegin(s), true); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::TellRead(s), 0); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::SeekEnd(s), true); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::TellRead(s), 0); VERIFY_EQUAL(mpt::IO::IsValid(s), true); } { std::istringstream s("a"); char a = 0; VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::TellRead(s), 0); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::SeekBegin(s), true); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::TellRead(s), 0); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::ReadRaw(s, &a, 1), 1); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::TellRead(s), 1); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::SeekBegin(s), true); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::TellRead(s), 0); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::SeekEnd(s), true); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(mpt::IO::TellRead(s), 1); VERIFY_EQUAL(mpt::IO::IsValid(s), true); VERIFY_EQUAL(std::string(1, a), std::string(1, 'a')); } #ifdef MPT_ENABLE_FILEIO { std::vector data; data.push_back(0); data.push_back(255); data.push_back(1); data.push_back(2); mpt::PathString fn = GetTempFilenameBase() + MPT_PATHSTRING("lazy"); RemoveFile(fn); mpt::LazyFileRef f(fn); f = data; std::vector data2; data2 = f; VERIFY_EQUAL(data.size(), data2.size()); for(std::size_t i = 0; i < data.size() && i < data2.size(); ++i) { VERIFY_EQUAL(data[i], data2[i]); } RemoveFile(fn); } #endif #ifdef MPT_WITH_ZLIB VERIFY_EQUAL(crc32(0, mpt::byte_cast(std::string("123456789").c_str()), 9), 0xCBF43926u); #endif #ifdef MPT_WITH_MINIZ VERIFY_EQUAL(mz_crc32(0, mpt::byte_cast(std::string("123456789").c_str()), 9), 0xCBF43926u); #endif VERIFY_EQUAL(mpt::crc32(std::string("123456789")), 0xCBF43926u); VERIFY_EQUAL(mpt::crc32_ogg(std::string("123456789")), 0x89a1897fu); // Check floating-point accuracy in TransposeToFrequency int32 transposeToFrequency[] = { 5, 5, 5, 5, 31, 32, 33, 34, 196, 202, 207, 214, 1243, 1280, 1317, 1356, 7894, 8125, 8363, 8608, 50121, 51590, 53102, 54658, 318251, 327576, 337175, 347055, 2020767, 2079980, 2140928, 2203663, }; int freqIndex = 0; for(int32 transpose = -128; transpose < 128; transpose += 32) for(int32 finetune = -128; finetune < 128; finetune += 64, freqIndex++) VERIFY_EQUAL_EPS(transposeToFrequency[freqIndex], static_cast(ModSample::TransposeToFrequency(transpose, finetune)), 1); { ModSample smp; smp.nC5Speed = 9999; smp.Transpose(1.5); VERIFY_EQUAL_EPS(28281, static_cast(smp.nC5Speed), 1); smp.Transpose(-1.3); VERIFY_EQUAL_EPS(11486, static_cast(smp.nC5Speed), 1); } // Check SamplePosition fixed-point type VERIFY_EQUAL(SamplePosition(1).GetRaw(), 1); VERIFY_EQUAL(SamplePosition(2).Set(1), SamplePosition(1, 0)); VERIFY_EQUAL(SamplePosition(2).SetInt(1), SamplePosition(1, 2)); VERIFY_EQUAL(SamplePosition(1).IsPositive(), true); VERIFY_EQUAL(SamplePosition(0).IsZero(), true); VERIFY_EQUAL(SamplePosition(1, 0).IsUnity(), true); VERIFY_EQUAL(SamplePosition(1, 1).IsUnity(), false); VERIFY_EQUAL(SamplePosition(-1).IsNegative(), true); VERIFY_EQUAL(SamplePosition(int64_max).GetRaw(), int64_max); VERIFY_EQUAL(SamplePosition(2, SamplePosition::fractMax).GetInt(), 2); VERIFY_EQUAL(SamplePosition(2, SamplePosition::fractMax).GetFract(), SamplePosition::GetFractMax()); VERIFY_EQUAL(SamplePosition(1, SamplePosition::fractMax).GetInvertedFract(), SamplePosition(0, 1)); VERIFY_EQUAL(SamplePosition(1, 0).GetInvertedFract(), SamplePosition(1, 0)); VERIFY_EQUAL(SamplePosition(2, 0).Negate(), SamplePosition(-2, 0)); VERIFY_EQUAL(SamplePosition::Ratio(10, 5), SamplePosition(2, 0)); VERIFY_EQUAL(SamplePosition(1, 1) + SamplePosition(2, 2), SamplePosition(3, 3)); VERIFY_EQUAL(SamplePosition(1, 0) * 3, SamplePosition(3, 0)); VERIFY_EQUAL((SamplePosition(6, 0) / SamplePosition(2, 0)), 3); VERIFY_EQUAL(srlztn::ID::FromInt(static_cast(0x87654321u)).AsString(), srlztn::ID("\x21\x43\x65\x87").AsString()); #if defined(MODPLUG_TRACKER) VERIFY_EQUAL(mpt::Wine::Version(MPT_USTRING("1.1.44" )).AsString() , MPT_USTRING("1.1.44")); VERIFY_EQUAL(mpt::Wine::Version(MPT_USTRING("1.6.2" )).AsString() , MPT_USTRING("1.6.2" )); VERIFY_EQUAL(mpt::Wine::Version(MPT_USTRING("1.8" )).AsString() , MPT_USTRING("1.8.0" )); VERIFY_EQUAL(mpt::Wine::Version(MPT_USTRING("2.0-rc" )).AsString() , MPT_USTRING("2.0.0" )); VERIFY_EQUAL(mpt::Wine::Version(MPT_USTRING("2.0-rc4")).AsString() , MPT_USTRING("2.0.0" )); VERIFY_EQUAL(mpt::Wine::Version(MPT_USTRING("2.0" )).AsString() , MPT_USTRING("2.0.0" )); VERIFY_EQUAL(mpt::Wine::Version(MPT_USTRING("2.4" )).AsString() , MPT_USTRING("2.4.0" )); #endif // MODPLUG_TRACKER // date VERIFY_EQUAL( 0, TestDate1( 0, 0, 0, 1, 1, 1970 )); VERIFY_EQUAL( 3600, TestDate1( 0, 0, 1, 1, 1, 1970 )); VERIFY_EQUAL( 86400, TestDate1( 0, 0, 0, 2, 1, 1970 )); VERIFY_EQUAL( 31536000, TestDate1( 0, 0, 0, 1, 1, 1971 )); VERIFY_EQUAL( 100000000, TestDate1( 40, 46, 9, 3, 3, 1973 )); VERIFY_EQUAL( 951782400, TestDate1( 0, 0, 0, 29, 2, 2000 )); VERIFY_EQUAL( 1000000000, TestDate1( 40, 46, 1, 9, 9, 2001 )); VERIFY_EQUAL( 1044057600, TestDate1( 0, 0, 0, 1, 2, 2003 )); VERIFY_EQUAL( 1044144000, TestDate1( 0, 0, 0, 2, 2, 2003 )); VERIFY_EQUAL( 1046476800, TestDate1( 0, 0, 0, 1, 3, 2003 )); VERIFY_EQUAL( 1064966400, TestDate1( 0, 0, 0, 1, 10, 2003 )); VERIFY_EQUAL( 1077926399, TestDate1( 59, 59, 23, 27, 2, 2004 )); VERIFY_EQUAL( 1077926400, TestDate1( 0, 0, 0, 28, 2, 2004 )); VERIFY_EQUAL( 1077926410, TestDate1( 10, 0, 0, 28, 2, 2004 )); VERIFY_EQUAL( 1078012799, TestDate1( 59, 59, 23, 28, 2, 2004 )); VERIFY_EQUAL( 1078012800, TestDate1( 0, 0, 0, 29, 2, 2004 )); VERIFY_EQUAL( 1078012820, TestDate1( 20, 0, 0, 29, 2, 2004 )); VERIFY_EQUAL( 1078099199, TestDate1( 59, 59, 23, 29, 2, 2004 )); VERIFY_EQUAL( 1078099200, TestDate1( 0, 0, 0, 1, 3, 2004 )); VERIFY_EQUAL( 1078099230, TestDate1( 30, 0, 0, 1, 3, 2004 )); VERIFY_EQUAL( 1078185599, TestDate1( 59, 59, 23, 1, 3, 2004 )); VERIFY_EQUAL( 1096588800, TestDate1( 0, 0, 0, 1, 10, 2004 )); VERIFY_EQUAL( 1413064016, TestDate1( 56, 46, 21, 11, 10, 2014 )); VERIFY_EQUAL( 1413064100, TestDate1( 20, 48, 21, 11, 10, 2014 )); VERIFY_EQUAL(Gregorian::FromTM(mpt::Date::Unix( 0).AsUTC()), TestDate2( 0, 0, 0, 1, 1, 1970 )); VERIFY_EQUAL(Gregorian::FromTM(mpt::Date::Unix( 3600).AsUTC()), TestDate2( 0, 0, 1, 1, 1, 1970 )); VERIFY_EQUAL(Gregorian::FromTM(mpt::Date::Unix( 86400).AsUTC()), TestDate2( 0, 0, 0, 2, 1, 1970 )); VERIFY_EQUAL(Gregorian::FromTM(mpt::Date::Unix( 31536000).AsUTC()), TestDate2( 0, 0, 0, 1, 1, 1971 )); VERIFY_EQUAL(Gregorian::FromTM(mpt::Date::Unix( 100000000).AsUTC()), TestDate2( 40, 46, 9, 3, 3, 1973 )); VERIFY_EQUAL(Gregorian::FromTM(mpt::Date::Unix( 951782400).AsUTC()), TestDate2( 0, 0, 0, 29, 2, 2000 )); VERIFY_EQUAL(Gregorian::FromTM(mpt::Date::Unix( 1000000000).AsUTC()), TestDate2( 40, 46, 1, 9, 9, 2001 )); VERIFY_EQUAL(Gregorian::FromTM(mpt::Date::Unix( 1044057600).AsUTC()), TestDate2( 0, 0, 0, 1, 2, 2003 )); VERIFY_EQUAL(Gregorian::FromTM(mpt::Date::Unix( 1044144000).AsUTC()), TestDate2( 0, 0, 0, 2, 2, 2003 )); VERIFY_EQUAL(Gregorian::FromTM(mpt::Date::Unix( 1046476800).AsUTC()), TestDate2( 0, 0, 0, 1, 3, 2003 )); VERIFY_EQUAL(Gregorian::FromTM(mpt::Date::Unix( 1064966400).AsUTC()), TestDate2( 0, 0, 0, 1, 10, 2003 )); VERIFY_EQUAL(Gregorian::FromTM(mpt::Date::Unix( 1077926399).AsUTC()), TestDate2( 59, 59, 23, 27, 2, 2004 )); VERIFY_EQUAL(Gregorian::FromTM(mpt::Date::Unix( 1077926400).AsUTC()), TestDate2( 0, 0, 0, 28, 2, 2004 )); VERIFY_EQUAL(Gregorian::FromTM(mpt::Date::Unix( 1077926410).AsUTC()), TestDate2( 10, 0, 0, 28, 2, 2004 )); VERIFY_EQUAL(Gregorian::FromTM(mpt::Date::Unix( 1078012799).AsUTC()), TestDate2( 59, 59, 23, 28, 2, 2004 )); VERIFY_EQUAL(Gregorian::FromTM(mpt::Date::Unix( 1078012800).AsUTC()), TestDate2( 0, 0, 0, 29, 2, 2004 )); VERIFY_EQUAL(Gregorian::FromTM(mpt::Date::Unix( 1078012820).AsUTC()), TestDate2( 20, 0, 0, 29, 2, 2004 )); VERIFY_EQUAL(Gregorian::FromTM(mpt::Date::Unix( 1078099199).AsUTC()), TestDate2( 59, 59, 23, 29, 2, 2004 )); VERIFY_EQUAL(Gregorian::FromTM(mpt::Date::Unix( 1078099200).AsUTC()), TestDate2( 0, 0, 0, 1, 3, 2004 )); VERIFY_EQUAL(Gregorian::FromTM(mpt::Date::Unix( 1078099230).AsUTC()), TestDate2( 30, 0, 0, 1, 3, 2004 )); VERIFY_EQUAL(Gregorian::FromTM(mpt::Date::Unix( 1078185599).AsUTC()), TestDate2( 59, 59, 23, 1, 3, 2004 )); VERIFY_EQUAL(Gregorian::FromTM(mpt::Date::Unix( 1096588800).AsUTC()), TestDate2( 0, 0, 0, 1, 10, 2004 )); VERIFY_EQUAL(Gregorian::FromTM(mpt::Date::Unix( 1413064016).AsUTC()), TestDate2( 56, 46, 21, 11, 10, 2014 )); VERIFY_EQUAL(Gregorian::FromTM(mpt::Date::Unix( 1413064100).AsUTC()), TestDate2( 20, 48, 21, 11, 10, 2014 )); } static MPT_NOINLINE void TestRandom() { mpt::prng & prng = *s_PRNG; for(std::size_t i = 0; i < 10000; ++i) { VERIFY_EQUAL_QUIET_NONCONT(IsInRange(mpt::random(prng), 0u, 127u), true); VERIFY_EQUAL_QUIET_NONCONT(IsInRange(mpt::random(prng), 0u, 255u), true); VERIFY_EQUAL_QUIET_NONCONT(IsInRange(mpt::random(prng), 0u, 511u), true); VERIFY_EQUAL_QUIET_NONCONT(IsInRange(mpt::random(prng), 0u, 1u), true); VERIFY_EQUAL_QUIET_NONCONT(IsInRange(mpt::random(prng, 7), 0u, 127u), true); VERIFY_EQUAL_QUIET_NONCONT(IsInRange(mpt::random(prng, 8), 0u, 255u), true); VERIFY_EQUAL_QUIET_NONCONT(IsInRange(mpt::random(prng, 9), 0u, 511u), true); VERIFY_EQUAL_QUIET_NONCONT(IsInRange(mpt::random(prng, 1), 0u, 1u), true); VERIFY_EQUAL_QUIET_NONCONT(IsInRange(mpt::random(prng), 0, 127), true); VERIFY_EQUAL_QUIET_NONCONT(IsInRange(mpt::random(prng), 0, 255), true); VERIFY_EQUAL_QUIET_NONCONT(IsInRange(mpt::random(prng), 0, 511), true); VERIFY_EQUAL_QUIET_NONCONT(IsInRange(mpt::random(prng), 0, 1), true); VERIFY_EQUAL_QUIET_NONCONT(IsInRange(mpt::random(prng, 7), 0, 127), true); VERIFY_EQUAL_QUIET_NONCONT(IsInRange(mpt::random(prng, 8), 0, 255), true); VERIFY_EQUAL_QUIET_NONCONT(IsInRange(mpt::random(prng, 9), 0, 511), true); VERIFY_EQUAL_QUIET_NONCONT(IsInRange(mpt::random(prng, 1), 0, 1), true); VERIFY_EQUAL_QUIET_NONCONT(IsInRange(mpt::random(prng, 0.0f, 1.0f), 0.0f, 1.0f), true); VERIFY_EQUAL_QUIET_NONCONT(IsInRange(mpt::random(prng, 0.0, 1.0), 0.0, 1.0), true); VERIFY_EQUAL_QUIET_NONCONT(IsInRange(mpt::random(prng, -1.0, 1.0), -1.0, 1.0), true); VERIFY_EQUAL_QUIET_NONCONT(IsInRange(mpt::random(prng, -1.0, 0.0), -1.0, 0.0), true); VERIFY_EQUAL_QUIET_NONCONT(IsInRange(mpt::random(prng, 1.0, 2.0), 1.0, 2.0), true); VERIFY_EQUAL_QUIET_NONCONT(IsInRange(mpt::random(prng, 1.0, 3.0), 1.0, 3.0), true); } #ifdef FLAKY_TESTS { std::vector hist(256); for(std::size_t i = 0; i < 256*256; ++i) { uint8 value = mpt::random(prng); hist[value] += 1; } for(std::size_t i = 0; i < 256; ++i) { VERIFY_EQUAL_QUIET_NONCONT(IsInRange(hist[i], 16u, 65520u), true); } } { std::vector hist(256); for(std::size_t i = 0; i < 256*256; ++i) { int8 value = mpt::random(prng); hist[static_cast(value) + 0x80] += 1; } for(std::size_t i = 0; i < 256; ++i) { VERIFY_EQUAL_QUIET_NONCONT(IsInRange(hist[i], 16u, 65520u), true); } } { std::vector hist(256); for(std::size_t i = 0; i < 256*256; ++i) { uint8 value = mpt::random(prng, 1); hist[value] += 1; } for(std::size_t i = 0; i < 256; ++i) { if(i < 2) { VERIFY_EQUAL_QUIET_NONCONT(IsInRange(hist[i], 16u, 65520u), true); } else { VERIFY_EQUAL_QUIET_NONCONT(hist[i], 0u); } } } #endif } static MPT_NOINLINE void TestCharsets() { // MPT_UTF8 version // Charset conversions (basic sanity checks) VERIFY_EQUAL(mpt::ToCharset(mpt::CharsetUTF8, MPT_USTRING("a")), "a"); VERIFY_EQUAL(mpt::ToCharset(mpt::CharsetISO8859_1, MPT_USTRING("a")), "a"); VERIFY_EQUAL(mpt::ToCharset(mpt::CharsetASCII, MPT_USTRING("a")), "a"); VERIFY_EQUAL(mpt::ToUnicode(mpt::CharsetUTF8, "a"), MPT_USTRING("a")); VERIFY_EQUAL(mpt::ToUnicode(mpt::CharsetISO8859_1, "a"), MPT_USTRING("a")); VERIFY_EQUAL(mpt::ToUnicode(mpt::CharsetASCII, "a"), MPT_USTRING("a")); #if defined(MPT_ENABLE_CHARSET_LOCALE) VERIFY_EQUAL(mpt::ToCharset(mpt::CharsetLocale, MPT_USTRING("a")), "a"); VERIFY_EQUAL(mpt::ToUnicode(mpt::CharsetLocale, "a"), MPT_USTRING("a")); #endif VERIFY_EQUAL(mpt::ToCharset(mpt::CharsetUTF8, MPT_UTF8("a")), "a"); VERIFY_EQUAL(mpt::ToCharset(mpt::CharsetISO8859_1, MPT_UTF8("a")), "a"); VERIFY_EQUAL(mpt::ToCharset(mpt::CharsetASCII, MPT_UTF8("a")), "a"); VERIFY_EQUAL(mpt::ToUnicode(mpt::CharsetUTF8, "a"), MPT_UTF8("a")); VERIFY_EQUAL(mpt::ToUnicode(mpt::CharsetISO8859_1, "a"), MPT_UTF8("a")); VERIFY_EQUAL(mpt::ToUnicode(mpt::CharsetASCII, "a"), MPT_UTF8("a")); #if defined(MPT_ENABLE_CHARSET_LOCALE) VERIFY_EQUAL(mpt::ToCharset(mpt::CharsetLocale, MPT_UTF8("a")), "a"); VERIFY_EQUAL(mpt::ToUnicode(mpt::CharsetLocale, "a"), MPT_UTF8("a")); #endif // Check that some character replacement is done (and not just empty strings or truncated strings are returned) // We test german umlaut-a (U+00E4) (\xC3\xA4) and CJK U+5BB6 (\xE5\xAE\xB6) VERIFY_EQUAL(EndsWith(mpt::ToCharset(mpt::CharsetASCII,MPT_UTF8("abc\xC3\xA4xyz")),"xyz"),true); VERIFY_EQUAL(EndsWith(mpt::ToCharset(mpt::CharsetISO8859_1,MPT_UTF8("abc\xC3\xA4xyz")),"xyz"),true); VERIFY_EQUAL(EndsWith(mpt::ToCharset(mpt::CharsetCP437,MPT_UTF8("abc\xC3\xA4xyz")),"xyz"),true); VERIFY_EQUAL(EndsWith(mpt::ToCharset(mpt::CharsetUTF8,MPT_UTF8("abc\xC3\xA4xyz")),"xyz"),true); VERIFY_EQUAL(BeginsWith(mpt::ToCharset(mpt::CharsetASCII,MPT_UTF8("abc\xC3\xA4xyz")),"abc"),true); VERIFY_EQUAL(BeginsWith(mpt::ToCharset(mpt::CharsetISO8859_1,MPT_UTF8("abc\xC3\xA4xyz")),"abc"),true); VERIFY_EQUAL(BeginsWith(mpt::ToCharset(mpt::CharsetCP437,MPT_UTF8("abc\xC3\xA4xyz")),"abc"),true); VERIFY_EQUAL(BeginsWith(mpt::ToCharset(mpt::CharsetUTF8,MPT_UTF8("abc\xC3\xA4xyz")),"abc"),true); #if defined(MPT_ENABLE_CHARSET_LOCALE) VERIFY_EQUAL(EndsWith(mpt::ToCharset(mpt::CharsetLocale,MPT_UTF8("abc\xC3\xA4xyz")),"xyz"),true); VERIFY_EQUAL(BeginsWith(mpt::ToCharset(mpt::CharsetLocale,MPT_UTF8("abc\xC3\xA4xyz")),"abc"),true); #endif VERIFY_EQUAL(EndsWith(mpt::ToCharset(mpt::CharsetASCII,MPT_UTF8("abc\xE5\xAE\xB6xyz")),"xyz"),true); VERIFY_EQUAL(EndsWith(mpt::ToCharset(mpt::CharsetISO8859_1,MPT_UTF8("abc\xE5\xAE\xB6xyz")),"xyz"),true); VERIFY_EQUAL(EndsWith(mpt::ToCharset(mpt::CharsetCP437,MPT_UTF8("abc\xE5\xAE\xB6xyz")),"xyz"),true); VERIFY_EQUAL(EndsWith(mpt::ToCharset(mpt::CharsetUTF8,MPT_UTF8("abc\xE5\xAE\xB6xyz")),"xyz"),true); VERIFY_EQUAL(BeginsWith(mpt::ToCharset(mpt::CharsetASCII,MPT_UTF8("abc\xE5\xAE\xB6xyz")),"abc"),true); VERIFY_EQUAL(BeginsWith(mpt::ToCharset(mpt::CharsetISO8859_1,MPT_UTF8("abc\xE5\xAE\xB6xyz")),"abc"),true); VERIFY_EQUAL(BeginsWith(mpt::ToCharset(mpt::CharsetCP437,MPT_UTF8("abc\xE5\xAE\xB6xyz")),"abc"),true); VERIFY_EQUAL(BeginsWith(mpt::ToCharset(mpt::CharsetUTF8,MPT_UTF8("abc\xE5\xAE\xB6xyz")),"abc"),true); #if defined(MPT_ENABLE_CHARSET_LOCALE) VERIFY_EQUAL(EndsWith(mpt::ToCharset(mpt::CharsetLocale,MPT_UTF8("abc\xE5\xAE\xB6xyz")),"xyz"),true); VERIFY_EQUAL(BeginsWith(mpt::ToCharset(mpt::CharsetLocale,MPT_UTF8("abc\xE5\xAE\xB6xyz")),"abc"),true); #endif VERIFY_EQUAL(EndsWith(mpt::ToUnicode(mpt::CharsetASCII,"abc\xC3\xA4xyz"),MPT_USTRING("xyz")),true); VERIFY_EQUAL(EndsWith(mpt::ToUnicode(mpt::CharsetISO8859_1,"abc\xC3\xA4xyz"),MPT_USTRING("xyz")),true); VERIFY_EQUAL(EndsWith(mpt::ToUnicode(mpt::CharsetCP437,"abc\xC3\xA4xyz"),MPT_USTRING("xyz")),true); VERIFY_EQUAL(EndsWith(mpt::ToUnicode(mpt::CharsetUTF8,"abc\xC3\xA4xyz"),MPT_USTRING("xyz")),true); VERIFY_EQUAL(BeginsWith(mpt::ToUnicode(mpt::CharsetASCII,"abc\xC3\xA4xyz"),MPT_USTRING("abc")),true); VERIFY_EQUAL(BeginsWith(mpt::ToUnicode(mpt::CharsetISO8859_1,"abc\xC3\xA4xyz"),MPT_USTRING("abc")),true); VERIFY_EQUAL(BeginsWith(mpt::ToUnicode(mpt::CharsetCP437,"abc\xC3\xA4xyz"),MPT_USTRING("abc")),true); VERIFY_EQUAL(BeginsWith(mpt::ToUnicode(mpt::CharsetUTF8,"abc\xC3\xA4xyz"),MPT_USTRING("abc")),true); #if defined(MPT_ENABLE_CHARSET_LOCALE) VERIFY_EQUAL(EndsWith(mpt::ToUnicode(mpt::CharsetLocale,"abc\xC3\xA4xyz"),MPT_USTRING("xyz")),true); VERIFY_EQUAL(BeginsWith(mpt::ToUnicode(mpt::CharsetLocale,"abc\xC3\xA4xyz"),MPT_USTRING("abc")),true); #endif VERIFY_EQUAL(EndsWith(mpt::ToUnicode(mpt::CharsetASCII,"abc\xE5\xAE\xB6xyz"),MPT_USTRING("xyz")),true); VERIFY_EQUAL(EndsWith(mpt::ToUnicode(mpt::CharsetISO8859_1,"abc\xE5\xAE\xB6xyz"),MPT_USTRING("xyz")),true); VERIFY_EQUAL(EndsWith(mpt::ToUnicode(mpt::CharsetCP437,"abc\xE5\xAE\xB6xyz"),MPT_USTRING("xyz")),true); VERIFY_EQUAL(EndsWith(mpt::ToUnicode(mpt::CharsetUTF8,"abc\xE5\xAE\xB6xyz"),MPT_USTRING("xyz")),true); VERIFY_EQUAL(BeginsWith(mpt::ToUnicode(mpt::CharsetASCII,"abc\xE5\xAE\xB6xyz"),MPT_USTRING("abc")),true); VERIFY_EQUAL(BeginsWith(mpt::ToUnicode(mpt::CharsetISO8859_1,"abc\xE5\xAE\xB6xyz"),MPT_USTRING("abc")),true); VERIFY_EQUAL(BeginsWith(mpt::ToUnicode(mpt::CharsetCP437,"abc\xE5\xAE\xB6xyz"),MPT_USTRING("abc")),true); VERIFY_EQUAL(BeginsWith(mpt::ToUnicode(mpt::CharsetUTF8,"abc\xE5\xAE\xB6xyz"),MPT_USTRING("abc")),true); #if defined(MPT_ENABLE_CHARSET_LOCALE) VERIFY_EQUAL(EndsWith(mpt::ToUnicode(mpt::CharsetLocale,"abc\xE5\xAE\xB6xyz"),MPT_USTRING("xyz")),true); VERIFY_EQUAL(BeginsWith(mpt::ToUnicode(mpt::CharsetLocale,"abc\xE5\xAE\xB6xyz"),MPT_USTRING("abc")),true); #endif // Check that characters are correctly converted // We test german umlaut-a (U+00E4) and CJK U+5BB6 // cp437 VERIFY_EQUAL(mpt::ToCharset(mpt::CharsetCP437,MPT_UTF8("abc\xC3\xA4xyz")),"abc\x84xyz"); VERIFY_EQUAL(MPT_UTF8("abc\xC3\xA4xyz"),mpt::ToUnicode(mpt::CharsetCP437,"abc\x84xyz")); // iso8859 VERIFY_EQUAL(mpt::ToCharset(mpt::CharsetISO8859_1,MPT_UTF8("abc\xC3\xA4xyz")),"abc\xE4xyz"); VERIFY_EQUAL(MPT_UTF8("abc\xC3\xA4xyz"),mpt::ToUnicode(mpt::CharsetISO8859_1,"abc\xE4xyz")); // utf8 VERIFY_EQUAL(mpt::ToCharset(mpt::CharsetUTF8,MPT_UTF8("abc\xC3\xA4xyz")),"abc\xC3\xA4xyz"); VERIFY_EQUAL(MPT_UTF8("abc\xC3\xA4xyz"),mpt::ToUnicode(mpt::CharsetUTF8,"abc\xC3\xA4xyz")); VERIFY_EQUAL(mpt::ToCharset(mpt::CharsetUTF8,MPT_UTF8("abc\xE5\xAE\xB6xyz")),"abc\xE5\xAE\xB6xyz"); VERIFY_EQUAL(MPT_UTF8("abc\xE5\xAE\xB6xyz"),mpt::ToUnicode(mpt::CharsetUTF8,"abc\xE5\xAE\xB6xyz")); #if MPT_WSTRING_CONVERT // wide L"" version // Charset conversions (basic sanity checks) VERIFY_EQUAL(mpt::ToCharset(mpt::CharsetUTF8, L"a"), "a"); VERIFY_EQUAL(mpt::ToCharset(mpt::CharsetISO8859_1, L"a"), "a"); VERIFY_EQUAL(mpt::ToCharset(mpt::CharsetASCII, L"a"), "a"); VERIFY_EQUAL(mpt::ToWide(mpt::CharsetUTF8, "a"), L"a"); VERIFY_EQUAL(mpt::ToWide(mpt::CharsetISO8859_1, "a"), L"a"); VERIFY_EQUAL(mpt::ToWide(mpt::CharsetASCII, "a"), L"a"); #if defined(MPT_ENABLE_CHARSET_LOCALE) VERIFY_EQUAL(mpt::ToCharset(mpt::CharsetLocale, L"a"), "a"); VERIFY_EQUAL(mpt::ToWide(mpt::CharsetLocale, "a"), L"a"); #endif // Check that some character replacement is done (and not just empty strings or truncated strings are returned) // We test german umlaut-a (U+00E4) and CJK U+5BB6 #if MPT_COMPILER_MSVC #pragma warning(push) #pragma warning(disable:4428) // universal-character-name encountered in source #endif VERIFY_EQUAL(EndsWith(mpt::ToCharset(mpt::CharsetASCII,L"abc\u00E4xyz"),"xyz"),true); VERIFY_EQUAL(EndsWith(mpt::ToCharset(mpt::CharsetISO8859_1,L"abc\u00E4xyz"),"xyz"),true); VERIFY_EQUAL(EndsWith(mpt::ToCharset(mpt::CharsetCP437,L"abc\u00E4xyz"),"xyz"),true); VERIFY_EQUAL(EndsWith(mpt::ToCharset(mpt::CharsetUTF8,L"abc\u00E4xyz"),"xyz"),true); VERIFY_EQUAL(BeginsWith(mpt::ToCharset(mpt::CharsetASCII,L"abc\u00E4xyz"),"abc"),true); VERIFY_EQUAL(BeginsWith(mpt::ToCharset(mpt::CharsetISO8859_1,L"abc\u00E4xyz"),"abc"),true); VERIFY_EQUAL(BeginsWith(mpt::ToCharset(mpt::CharsetCP437,L"abc\u00E4xyz"),"abc"),true); VERIFY_EQUAL(BeginsWith(mpt::ToCharset(mpt::CharsetUTF8,L"abc\u00E4xyz"),"abc"),true); #if defined(MPT_ENABLE_CHARSET_LOCALE) VERIFY_EQUAL(EndsWith(mpt::ToCharset(mpt::CharsetLocale,L"abc\u00E4xyz"),"xyz"),true); VERIFY_EQUAL(BeginsWith(mpt::ToCharset(mpt::CharsetLocale,L"abc\u00E4xyz"),"abc"),true); #endif VERIFY_EQUAL(EndsWith(mpt::ToCharset(mpt::CharsetASCII,L"abc\u5BB6xyz"),"xyz"),true); VERIFY_EQUAL(EndsWith(mpt::ToCharset(mpt::CharsetISO8859_1,L"abc\u5BB6xyz"),"xyz"),true); VERIFY_EQUAL(EndsWith(mpt::ToCharset(mpt::CharsetCP437,L"abc\u5BB6xyz"),"xyz"),true); VERIFY_EQUAL(EndsWith(mpt::ToCharset(mpt::CharsetUTF8,L"abc\u5BB6xyz"),"xyz"),true); VERIFY_EQUAL(BeginsWith(mpt::ToCharset(mpt::CharsetASCII,L"abc\u5BB6xyz"),"abc"),true); VERIFY_EQUAL(BeginsWith(mpt::ToCharset(mpt::CharsetISO8859_1,L"abc\u5BB6xyz"),"abc"),true); VERIFY_EQUAL(BeginsWith(mpt::ToCharset(mpt::CharsetCP437,L"abc\u5BB6xyz"),"abc"),true); VERIFY_EQUAL(BeginsWith(mpt::ToCharset(mpt::CharsetUTF8,L"abc\u5BB6xyz"),"abc"),true); #if defined(MPT_ENABLE_CHARSET_LOCALE) VERIFY_EQUAL(EndsWith(mpt::ToCharset(mpt::CharsetLocale,L"abc\u5BB6xyz"),"xyz"),true); VERIFY_EQUAL(BeginsWith(mpt::ToCharset(mpt::CharsetLocale,L"abc\u5BB6xyz"),"abc"),true); #endif VERIFY_EQUAL(EndsWith(mpt::ToWide(mpt::CharsetASCII,"abc\xC3\xA4xyz"),L"xyz"),true); VERIFY_EQUAL(EndsWith(mpt::ToWide(mpt::CharsetISO8859_1,"abc\xC3\xA4xyz"),L"xyz"),true); VERIFY_EQUAL(EndsWith(mpt::ToWide(mpt::CharsetCP437,"abc\xC3\xA4xyz"),L"xyz"),true); VERIFY_EQUAL(EndsWith(mpt::ToWide(mpt::CharsetUTF8,"abc\xC3\xA4xyz"),L"xyz"),true); VERIFY_EQUAL(BeginsWith(mpt::ToWide(mpt::CharsetASCII,"abc\xC3\xA4xyz"),L"abc"),true); VERIFY_EQUAL(BeginsWith(mpt::ToWide(mpt::CharsetISO8859_1,"abc\xC3\xA4xyz"),L"abc"),true); VERIFY_EQUAL(BeginsWith(mpt::ToWide(mpt::CharsetCP437,"abc\xC3\xA4xyz"),L"abc"),true); VERIFY_EQUAL(BeginsWith(mpt::ToWide(mpt::CharsetUTF8,"abc\xC3\xA4xyz"),L"abc"),true); #if defined(MPT_ENABLE_CHARSET_LOCALE) VERIFY_EQUAL(EndsWith(mpt::ToWide(mpt::CharsetLocale,"abc\xC3\xA4xyz"),L"xyz"),true); VERIFY_EQUAL(BeginsWith(mpt::ToWide(mpt::CharsetLocale,"abc\xC3\xA4xyz"),L"abc"),true); #endif VERIFY_EQUAL(EndsWith(mpt::ToWide(mpt::CharsetASCII,"abc\xE5\xAE\xB6xyz"),L"xyz"),true); VERIFY_EQUAL(EndsWith(mpt::ToWide(mpt::CharsetISO8859_1,"abc\xE5\xAE\xB6xyz"),L"xyz"),true); VERIFY_EQUAL(EndsWith(mpt::ToWide(mpt::CharsetCP437,"abc\xE5\xAE\xB6xyz"),L"xyz"),true); VERIFY_EQUAL(EndsWith(mpt::ToWide(mpt::CharsetUTF8,"abc\xE5\xAE\xB6xyz"),L"xyz"),true); VERIFY_EQUAL(BeginsWith(mpt::ToWide(mpt::CharsetASCII,"abc\xE5\xAE\xB6xyz"),L"abc"),true); VERIFY_EQUAL(BeginsWith(mpt::ToWide(mpt::CharsetISO8859_1,"abc\xE5\xAE\xB6xyz"),L"abc"),true); VERIFY_EQUAL(BeginsWith(mpt::ToWide(mpt::CharsetCP437,"abc\xE5\xAE\xB6xyz"),L"abc"),true); VERIFY_EQUAL(BeginsWith(mpt::ToWide(mpt::CharsetUTF8,"abc\xE5\xAE\xB6xyz"),L"abc"),true); #if defined(MPT_ENABLE_CHARSET_LOCALE) VERIFY_EQUAL(EndsWith(mpt::ToWide(mpt::CharsetLocale,"abc\xE5\xAE\xB6xyz"),L"xyz"),true); VERIFY_EQUAL(BeginsWith(mpt::ToWide(mpt::CharsetLocale,"abc\xE5\xAE\xB6xyz"),L"abc"),true); #endif // Check that characters are correctly converted // We test german umlaut-a (U+00E4) and CJK U+5BB6 // cp437 VERIFY_EQUAL(mpt::ToCharset(mpt::CharsetCP437,L"abc\u00E4xyz"),"abc\x84xyz"); VERIFY_EQUAL(L"abc\u00E4xyz",mpt::ToWide(mpt::CharsetCP437,"abc\x84xyz")); // iso8859 VERIFY_EQUAL(mpt::ToCharset(mpt::CharsetISO8859_1,L"abc\u00E4xyz"),"abc\xE4xyz"); VERIFY_EQUAL(L"abc\u00E4xyz",mpt::ToWide(mpt::CharsetISO8859_1,"abc\xE4xyz")); // utf8 VERIFY_EQUAL(mpt::ToCharset(mpt::CharsetUTF8,L"abc\u00E4xyz"),"abc\xC3\xA4xyz"); VERIFY_EQUAL(L"abc\u00E4xyz",mpt::ToWide(mpt::CharsetUTF8,"abc\xC3\xA4xyz")); VERIFY_EQUAL(mpt::ToCharset(mpt::CharsetUTF8,L"abc\u5BB6xyz"),"abc\xE5\xAE\xB6xyz"); VERIFY_EQUAL(L"abc\u5BB6xyz",mpt::ToWide(mpt::CharsetUTF8,"abc\xE5\xAE\xB6xyz")); #if MPT_COMPILER_MSVC #pragma warning(pop) #endif #endif // Path splitting #if MPT_OS_WINDOWS && defined(MPT_ENABLE_DYNBIND) VERIFY_EQUAL(MPT_PATHSTRING("").GetDrive(), MPT_PATHSTRING("")); VERIFY_EQUAL(MPT_PATHSTRING("").GetDir(), MPT_PATHSTRING("")); VERIFY_EQUAL(MPT_PATHSTRING("").GetPath(), MPT_PATHSTRING("")); VERIFY_EQUAL(MPT_PATHSTRING("").GetFileName(), MPT_PATHSTRING("")); VERIFY_EQUAL(MPT_PATHSTRING("").GetFileExt(), MPT_PATHSTRING("")); VERIFY_EQUAL(MPT_PATHSTRING("").GetFullFileName(), MPT_PATHSTRING("")); VERIFY_EQUAL(MPT_PATHSTRING("C:\\").GetDrive(), MPT_PATHSTRING("C:")); VERIFY_EQUAL(MPT_PATHSTRING("C:\\").GetDir(), MPT_PATHSTRING("\\")); VERIFY_EQUAL(MPT_PATHSTRING("C:\\").GetPath(), MPT_PATHSTRING("C:\\")); VERIFY_EQUAL(MPT_PATHSTRING("C:\\").GetFileName(), MPT_PATHSTRING("")); VERIFY_EQUAL(MPT_PATHSTRING("C:\\").GetFileExt(), MPT_PATHSTRING("")); VERIFY_EQUAL(MPT_PATHSTRING("C:\\").GetFullFileName(), MPT_PATHSTRING("")); VERIFY_EQUAL(MPT_PATHSTRING("\\directory\\").GetDrive(), MPT_PATHSTRING("")); VERIFY_EQUAL(MPT_PATHSTRING("\\directory\\").GetDir(), MPT_PATHSTRING("\\directory\\")); VERIFY_EQUAL(MPT_PATHSTRING("\\directory\\").GetPath(), MPT_PATHSTRING("\\directory\\")); VERIFY_EQUAL(MPT_PATHSTRING("\\directory\\").GetFileName(), MPT_PATHSTRING("")); VERIFY_EQUAL(MPT_PATHSTRING("\\directory\\").GetFileExt(), MPT_PATHSTRING("")); VERIFY_EQUAL(MPT_PATHSTRING("\\directory\\").GetFullFileName(), MPT_PATHSTRING("")); VERIFY_EQUAL(MPT_PATHSTRING("\\directory\\file.txt").GetDrive(), MPT_PATHSTRING("")); VERIFY_EQUAL(MPT_PATHSTRING("\\directory\\file.txt").GetDir(), MPT_PATHSTRING("\\directory\\")); VERIFY_EQUAL(MPT_PATHSTRING("\\directory\\file.txt").GetPath(), MPT_PATHSTRING("\\directory\\")); VERIFY_EQUAL(MPT_PATHSTRING("\\directory\\file.txt").GetFileName(), MPT_PATHSTRING("file")); VERIFY_EQUAL(MPT_PATHSTRING("\\directory\\file.txt").GetFileExt(), MPT_PATHSTRING(".txt")); VERIFY_EQUAL(MPT_PATHSTRING("\\directory\\file.txt").GetFullFileName(), MPT_PATHSTRING("file.txt")); VERIFY_EQUAL(MPT_PATHSTRING("C:tmp.txt").GetDrive(), MPT_PATHSTRING("C:")); VERIFY_EQUAL(MPT_PATHSTRING("C:tmp.txt").GetDir(), MPT_PATHSTRING("")); VERIFY_EQUAL(MPT_PATHSTRING("C:tmp.txt").GetPath(), MPT_PATHSTRING("C:")); VERIFY_EQUAL(MPT_PATHSTRING("C:tmp.txt").GetFileName(), MPT_PATHSTRING("tmp")); VERIFY_EQUAL(MPT_PATHSTRING("C:tmp.txt").GetFileExt(), MPT_PATHSTRING(".txt")); VERIFY_EQUAL(MPT_PATHSTRING("C:tmp.txt").GetFullFileName(), MPT_PATHSTRING("tmp.txt")); VERIFY_EQUAL(MPT_PATHSTRING("C:tempdir\\tmp.txt").GetDrive(), MPT_PATHSTRING("C:")); VERIFY_EQUAL(MPT_PATHSTRING("C:tempdir\\tmp.txt").GetDir(), MPT_PATHSTRING("tempdir\\")); VERIFY_EQUAL(MPT_PATHSTRING("C:tempdir\\tmp.txt").GetPath(), MPT_PATHSTRING("C:tempdir\\")); VERIFY_EQUAL(MPT_PATHSTRING("C:tempdir\\tmp.txt").GetFileName(), MPT_PATHSTRING("tmp")); VERIFY_EQUAL(MPT_PATHSTRING("C:tempdir\\tmp.txt").GetFileExt(), MPT_PATHSTRING(".txt")); VERIFY_EQUAL(MPT_PATHSTRING("C:tempdir\\tmp.txt").GetFullFileName(), MPT_PATHSTRING("tmp.txt")); VERIFY_EQUAL(MPT_PATHSTRING("C:\\tempdir\\tmp.txt").GetDrive(), MPT_PATHSTRING("C:")); VERIFY_EQUAL(MPT_PATHSTRING("C:\\tempdir\\tmp.txt").GetDir(), MPT_PATHSTRING("\\tempdir\\")); VERIFY_EQUAL(MPT_PATHSTRING("C:\\tempdir\\tmp.txt").GetPath(), MPT_PATHSTRING("C:\\tempdir\\")); VERIFY_EQUAL(MPT_PATHSTRING("C:\\tempdir\\tmp.txt").GetFileName(), MPT_PATHSTRING("tmp")); VERIFY_EQUAL(MPT_PATHSTRING("C:\\tempdir\\tmp.txt").GetFileExt(), MPT_PATHSTRING(".txt")); VERIFY_EQUAL(MPT_PATHSTRING("C:\\tempdir\\tmp.txt").GetFullFileName(), MPT_PATHSTRING("tmp.txt")); VERIFY_EQUAL(MPT_PATHSTRING("C:\\tempdir\\tmp.foo.txt").GetFileName(), MPT_PATHSTRING("tmp.foo")); VERIFY_EQUAL(MPT_PATHSTRING("C:\\tempdir\\tmp.foo.txt").GetFileExt(), MPT_PATHSTRING(".txt")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\server").GetDrive(), MPT_PATHSTRING("\\\\server")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\server").GetDir(), MPT_PATHSTRING("")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\server").GetPath(), MPT_PATHSTRING("\\\\server")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\server").GetFileName(), MPT_PATHSTRING("")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\server").GetFileExt(), MPT_PATHSTRING("")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\server").GetFullFileName(), MPT_PATHSTRING("")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\server\\").GetDrive(), MPT_PATHSTRING("\\\\server\\")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\server\\").GetDir(), MPT_PATHSTRING("")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\server\\").GetPath(), MPT_PATHSTRING("\\\\server\\")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\server\\").GetFileName(), MPT_PATHSTRING("")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\server\\").GetFileExt(), MPT_PATHSTRING("")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\server\\").GetFullFileName(), MPT_PATHSTRING("")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\server\\share").GetDrive(), MPT_PATHSTRING("\\\\server\\share")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\server\\share").GetDir(), MPT_PATHSTRING("")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\server\\share").GetPath(), MPT_PATHSTRING("\\\\server\\share")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\server\\share").GetFileName(), MPT_PATHSTRING("")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\server\\share").GetFileExt(), MPT_PATHSTRING("")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\server\\share").GetFullFileName(), MPT_PATHSTRING("")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\server\\share\\").GetDrive(), MPT_PATHSTRING("\\\\server\\share")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\server\\share\\").GetDir(), MPT_PATHSTRING("\\")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\server\\share\\").GetPath(), MPT_PATHSTRING("\\\\server\\share\\")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\server\\share\\").GetFileName(), MPT_PATHSTRING("")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\server\\share\\").GetFileExt(), MPT_PATHSTRING("")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\server\\share\\").GetFullFileName(), MPT_PATHSTRING("")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\server\\share\\dir1\\dir2\\name.foo.ext").GetDrive(), MPT_PATHSTRING("\\\\server\\share")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\server\\share\\dir1\\dir2\\name.foo.ext").GetDir(), MPT_PATHSTRING("\\dir1\\dir2\\")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\server\\share\\dir1\\dir2\\name.foo.ext").GetPath(), MPT_PATHSTRING("\\\\server\\share\\dir1\\dir2\\")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\server\\share\\dir1\\dir2\\name.foo.ext").GetFileName(), MPT_PATHSTRING("name.foo")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\server\\share\\dir1\\dir2\\name.foo.ext").GetFileExt(), MPT_PATHSTRING(".ext")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\server\\share\\dir1\\dir2\\name.foo.ext").GetFullFileName(), MPT_PATHSTRING("name.foo.ext")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\?\\C:\\tempdir\\dir.2\\tmp.foo.txt").GetDrive(), MPT_PATHSTRING("C:")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\?\\C:\\tempdir\\dir.2\\tmp.foo.txt").GetDir(), MPT_PATHSTRING("\\tempdir\\dir.2\\")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\?\\C:\\tempdir\\dir.2\\tmp.foo.txt").GetPath(), MPT_PATHSTRING("C:\\tempdir\\dir.2\\")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\?\\C:\\tempdir\\dir.2\\tmp.foo.txt").GetFileName(), MPT_PATHSTRING("tmp.foo")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\?\\C:\\tempdir\\dir.2\\tmp.foo.txt").GetFileExt(), MPT_PATHSTRING(".txt")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\?\\C:\\tempdir\\dir.2\\tmp.foo.txt").GetFullFileName(), MPT_PATHSTRING("tmp.foo.txt")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\?\\UNC\\server\\share\\dir1\\dir2\\name.foo.ext").GetDrive(), MPT_PATHSTRING("\\\\server\\share")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\?\\UNC\\server\\share\\dir1\\dir2\\name.foo.ext").GetDir(), MPT_PATHSTRING("\\dir1\\dir2\\")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\?\\UNC\\server\\share\\dir1\\dir2\\name.foo.ext").GetPath(), MPT_PATHSTRING("\\\\server\\share\\dir1\\dir2\\")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\?\\UNC\\server\\share\\dir1\\dir2\\name.foo.ext").GetFileName(), MPT_PATHSTRING("name.foo")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\?\\UNC\\server\\share\\dir1\\dir2\\name.foo.ext").GetFileExt(), MPT_PATHSTRING(".ext")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\?\\UNC\\server\\share\\dir1\\dir2\\name.foo.ext").GetFullFileName(), MPT_PATHSTRING("name.foo.ext")); #endif // Path conversions #ifdef MODPLUG_TRACKER const mpt::PathString exePath = MPT_PATHSTRING("C:\\OpenMPT\\"); VERIFY_EQUAL(MPT_PATHSTRING("C:\\OpenMPT\\").AbsolutePathToRelative(exePath), MPT_PATHSTRING(".\\")); VERIFY_EQUAL(MPT_PATHSTRING("c:\\OpenMPT\\foo").AbsolutePathToRelative(exePath), MPT_PATHSTRING(".\\foo")); VERIFY_EQUAL(MPT_PATHSTRING("C:\\foo").AbsolutePathToRelative(exePath), MPT_PATHSTRING("\\foo")); VERIFY_EQUAL(MPT_PATHSTRING(".\\").RelativePathToAbsolute(exePath), MPT_PATHSTRING("C:\\OpenMPT\\")); VERIFY_EQUAL(MPT_PATHSTRING(".\\foo").RelativePathToAbsolute(exePath), MPT_PATHSTRING("C:\\OpenMPT\\foo")); VERIFY_EQUAL(MPT_PATHSTRING("\\foo").RelativePathToAbsolute(exePath), MPT_PATHSTRING("C:\\foo")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\server\\path\\file").AbsolutePathToRelative(exePath), MPT_PATHSTRING("\\\\server\\path\\file")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\server\\path\\file").RelativePathToAbsolute(exePath), MPT_PATHSTRING("\\\\server\\path\\file")); VERIFY_EQUAL(MPT_PATHSTRING("").Simplify(), MPT_PATHSTRING("")); VERIFY_EQUAL(MPT_PATHSTRING(" ").Simplify(), MPT_PATHSTRING(" ")); VERIFY_EQUAL(MPT_PATHSTRING("foo\\bar").Simplify(), MPT_PATHSTRING("foo\\bar")); VERIFY_EQUAL(MPT_PATHSTRING(".\\foo\\bar").Simplify(), MPT_PATHSTRING(".\\foo\\bar")); VERIFY_EQUAL(MPT_PATHSTRING(".\\\\foo\\bar").Simplify(), MPT_PATHSTRING(".\\foo\\bar")); VERIFY_EQUAL(MPT_PATHSTRING("./\\foo\\bar").Simplify(), MPT_PATHSTRING(".\\foo\\bar")); VERIFY_EQUAL(MPT_PATHSTRING("\\foo\\bar").Simplify(), MPT_PATHSTRING("\\foo\\bar")); VERIFY_EQUAL(MPT_PATHSTRING("A:\\name_1\\.\\name_2\\..\\name_3\\").Simplify(), MPT_PATHSTRING("A:\\name_1\\name_3")); VERIFY_EQUAL(MPT_PATHSTRING("A:\\name_1\\..\\name_2\\./name_3").Simplify(), MPT_PATHSTRING("A:\\name_2\\name_3")); VERIFY_EQUAL(MPT_PATHSTRING("A:\\name_1\\.\\name_2\\.\\name_3\\..\\name_4\\..").Simplify(), MPT_PATHSTRING("A:\\name_1\\name_2")); VERIFY_EQUAL(MPT_PATHSTRING("A:foo\\\\bar").Simplify(), MPT_PATHSTRING("A:\\foo\\bar")); VERIFY_EQUAL(MPT_PATHSTRING("C:\\..").Simplify(), MPT_PATHSTRING("C:\\")); VERIFY_EQUAL(MPT_PATHSTRING("C:\\.").Simplify(), MPT_PATHSTRING("C:\\")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\foo\\..\\.bar").Simplify(), MPT_PATHSTRING("\\\\.bar")); VERIFY_EQUAL(MPT_PATHSTRING("\\\\foo\\..\\..\\bar").Simplify(), MPT_PATHSTRING("\\\\bar")); #endif #ifdef MODPLUG_TRACKER #if MPT_COMPILER_MSVC // Tracker code currently relies on BROKEN MSVC behaviour with respect to %s // handling in printf functions when the target is a wide string. // Ensure that Microsoft KEEPS this BROKEN behavour (it conflicts with C99 and // C++11 demanded semantics. // Additionally, the tracker code makes use of %hs and %ls which are the only // way to unconditionally expect narrow or wide string parameters // respectively; %ls is standard conforming, %hs is a Microsoft extension. // We check all possible combinations and expect Microsoft-style behaviour // here. char src_char[256]; wchar_t src_wchar[256]; TCHAR src_tchar[256]; char dst_char[256]; wchar_t dst_wchar[256]; TCHAR dst_tchar[256]; MemsetZero(src_char); MemsetZero(src_wchar); MemsetZero(src_tchar); strcpy(src_char, "ab"); wcscpy(src_wchar, L"ab"); _tcscpy(src_tchar, _T("ab")); #define MPT_TEST_PRINTF(dst_type, function, format, src_type) \ MPT_DO { \ MemsetZero(dst_ ## dst_type); \ function(dst_ ## dst_type, format, src_ ## src_type); \ VERIFY_EQUAL(std::memcmp(dst_ ## dst_type, src_ ## dst_type, 256), 0); \ } MPT_WHILE_0 \ /**/ #define MPT_TEST_PRINTF_N(dst_type, function, format, src_type) \ MPT_DO { \ MemsetZero(dst_ ## dst_type); \ function(dst_ ## dst_type, 255, format, src_ ## src_type); \ VERIFY_EQUAL(std::memcmp(dst_ ## dst_type, src_ ## dst_type, 256), 0); \ } MPT_WHILE_0 \ /**/ // CRT narrow MPT_TEST_PRINTF(char, sprintf, "%s", char); MPT_TEST_PRINTF(char, sprintf, "%S", wchar); MPT_TEST_PRINTF(char, sprintf, "%hs", char); MPT_TEST_PRINTF(char, sprintf, "%hS", char); MPT_TEST_PRINTF(char, sprintf, "%ls", wchar); MPT_TEST_PRINTF(char, sprintf, "%lS", wchar); MPT_TEST_PRINTF(char, sprintf, "%ws", wchar); MPT_TEST_PRINTF(char, sprintf, "%wS", wchar); // CRT wide MPT_TEST_PRINTF_N(wchar, swprintf, L"%s", wchar); MPT_TEST_PRINTF_N(wchar, swprintf, L"%S", char); MPT_TEST_PRINTF_N(wchar, swprintf, L"%hs", char); MPT_TEST_PRINTF_N(wchar, swprintf, L"%hS", char); MPT_TEST_PRINTF_N(wchar, swprintf, L"%ls", wchar); MPT_TEST_PRINTF_N(wchar, swprintf, L"%lS", wchar); MPT_TEST_PRINTF_N(wchar, swprintf, L"%ws", wchar); MPT_TEST_PRINTF_N(wchar, swprintf, L"%wS", wchar); // WinAPI TCHAR MPT_TEST_PRINTF(tchar, wsprintf, _T("%s"), tchar); MPT_TEST_PRINTF(tchar, wsprintf, _T("%hs"), char); MPT_TEST_PRINTF(tchar, wsprintf, _T("%hS"), char); MPT_TEST_PRINTF(tchar, wsprintf, _T("%ls"), wchar); MPT_TEST_PRINTF(tchar, wsprintf, _T("%lS"), wchar); // WinAPI CHAR MPT_TEST_PRINTF(char, wsprintfA, "%s", char); MPT_TEST_PRINTF(char, wsprintfA, "%S", wchar); MPT_TEST_PRINTF(char, wsprintfA, "%hs", char); MPT_TEST_PRINTF(char, wsprintfA, "%hS", char); MPT_TEST_PRINTF(char, wsprintfA, "%ls", wchar); MPT_TEST_PRINTF(char, wsprintfA, "%lS", wchar); // WinAPI WCHAR MPT_TEST_PRINTF(wchar, wsprintfW, L"%s", wchar); MPT_TEST_PRINTF(wchar, wsprintfW, L"%S", char); MPT_TEST_PRINTF(wchar, wsprintfW, L"%hs", char); MPT_TEST_PRINTF(wchar, wsprintfW, L"%hS", char); MPT_TEST_PRINTF(wchar, wsprintfW, L"%ls", wchar); MPT_TEST_PRINTF(wchar, wsprintfW, L"%lS", wchar); #undef MPT_TEST_PRINTF #undef MPT_TEST_PRINTF_n #endif #endif VERIFY_EQUAL(mpt::CompareNoCaseAscii("f", "f", 6) == 0, true); VERIFY_EQUAL(mpt::CompareNoCaseAscii("f", "F", 6) == 0, true); VERIFY_EQUAL(mpt::CompareNoCaseAscii("F", "f", 6) == 0, true); VERIFY_EQUAL(mpt::CompareNoCaseAscii("f", "g", 6) < 0, true); VERIFY_EQUAL(mpt::CompareNoCaseAscii("h", "g", 6) > 0, true); VERIFY_EQUAL(mpt::CompareNoCaseAscii("fgh", "FgH", 6) == 0, true); VERIFY_EQUAL(mpt::CompareNoCaseAscii("012345678", "012345678", 9) == 0, true); VERIFY_EQUAL(mpt::CompareNoCaseAscii("", "012345678", 9) < 0, true); VERIFY_EQUAL(mpt::CompareNoCaseAscii("FgH", "", 6) > 0, true); VERIFY_EQUAL(mpt::CompareNoCaseAscii("FgH", "F", 6) > 0, true); VERIFY_EQUAL(mpt::CompareNoCaseAscii("FgH", "Fg", 6) > 0, true); VERIFY_EQUAL(mpt::CompareNoCaseAscii("FgH", "fg", 6) > 0, true); VERIFY_EQUAL(mpt::CompareNoCaseAscii("0123456789", "FgH", 0) == 0, true); VERIFY_EQUAL(mpt::CompareNoCaseAscii("FgH", "fgh", 1) == 0, true); VERIFY_EQUAL(mpt::CompareNoCaseAscii("FgH", "fgh", 2) == 0, true); VERIFY_EQUAL(mpt::CompareNoCaseAscii("FgH", "fgh", 3) == 0, true); VERIFY_EQUAL(mpt::CompareNoCaseAscii("FgH", "fghi", 3) == 0, true); VERIFY_EQUAL(mpt::CompareNoCaseAscii("FgH", "fghi", 4) < 0, true); VERIFY_EQUAL(mpt::CompareNoCaseAscii("FIH", "fghi", 1) == 0, true); VERIFY_EQUAL(mpt::CompareNoCaseAscii("FIH", "fghi", 2) > 0, true); } #ifdef MODPLUG_TRACKER struct CustomSettingsTestType { float x; float y; CustomSettingsTestType(float x_ = 0.0f, float y_ = 0.0f) : x(x_), y(y_) { } }; } // namespace Test template <> inline Test::CustomSettingsTestType FromSettingValue(const SettingValue &val) { MPT_ASSERT(val.GetTypeTag() == "myType"); std::string xy = val.as(); if(xy.empty()) { return Test::CustomSettingsTestType(0.0f, 0.0f); } std::size_t pos = xy.find("|"); std::string x = xy.substr(0, pos); std::string y = xy.substr(pos + 1); return Test::CustomSettingsTestType(ConvertStrTo(x.c_str()), ConvertStrTo(y.c_str())); } template <> inline SettingValue ToSettingValue(const Test::CustomSettingsTestType &val) { return SettingValue(mpt::fmt::val(val.x) + "|" + mpt::fmt::val(val.y), "myType"); } namespace Test { #endif // MODPLUG_TRACKER static MPT_NOINLINE void TestSettings() { #ifdef MODPLUG_TRACKER VERIFY_EQUAL(SettingPath("a","b") < SettingPath("a","c"), true); VERIFY_EQUAL(!(SettingPath("c","b") < SettingPath("a","c")), true); { DefaultSettingsContainer conf; int32 foobar = conf.Read("Test", "bar", 23); conf.Write("Test", "bar", 64); conf.Write("Test", "bar", 42); conf.Read("Test", "baz", 4711); foobar = conf.Read("Test", "bar", 28); } { DefaultSettingsContainer conf; int32 foobar = conf.Read("Test", "bar", 28); VERIFY_EQUAL(foobar, 42); conf.Write("Test", "bar", 43); } { DefaultSettingsContainer conf; int32 foobar = conf.Read("Test", "bar", 123); VERIFY_EQUAL(foobar, 43); conf.Write("Test", "bar", 88); } { DefaultSettingsContainer conf; Setting foo(conf, "Test", "bar", 99); VERIFY_EQUAL(foo, 88); foo = 7; } { DefaultSettingsContainer conf; Setting foo(conf, "Test", "bar", 99); VERIFY_EQUAL(foo, 7); } { DefaultSettingsContainer conf; conf.Read("Test", "struct", std::string("")); conf.Write("Test", "struct", std::string("")); } { DefaultSettingsContainer conf; CustomSettingsTestType dummy = conf.Read("Test", "struct", CustomSettingsTestType(1.0f, 1.0f)); dummy = CustomSettingsTestType(0.125f, 32.0f); conf.Write("Test", "struct", dummy); } { DefaultSettingsContainer conf; Setting dummyVar(conf, "Test", "struct", CustomSettingsTestType(1.0f, 1.0f)); CustomSettingsTestType dummy = dummyVar; VERIFY_EQUAL(dummy.x, 0.125f); VERIFY_EQUAL(dummy.y, 32.0f); } #endif // MODPLUG_TRACKER } // Test MIDI Event generating / reading static MPT_NOINLINE void TestMIDIEvents() { uint32 midiEvent; midiEvent = MIDIEvents::CC(MIDIEvents::MIDICC_Balance_Coarse, 13, 40); VERIFY_EQUAL_NONCONT(MIDIEvents::GetTypeFromEvent(midiEvent), MIDIEvents::evControllerChange); VERIFY_EQUAL_NONCONT(MIDIEvents::GetChannelFromEvent(midiEvent), 13); VERIFY_EQUAL_NONCONT(MIDIEvents::GetDataByte1FromEvent(midiEvent), MIDIEvents::MIDICC_Balance_Coarse); VERIFY_EQUAL_NONCONT(MIDIEvents::GetDataByte2FromEvent(midiEvent), 40); midiEvent = MIDIEvents::NoteOn(10, 50, 120); VERIFY_EQUAL_NONCONT(MIDIEvents::GetTypeFromEvent(midiEvent), MIDIEvents::evNoteOn); VERIFY_EQUAL_NONCONT(MIDIEvents::GetChannelFromEvent(midiEvent), 10); VERIFY_EQUAL_NONCONT(MIDIEvents::GetDataByte1FromEvent(midiEvent), 50); VERIFY_EQUAL_NONCONT(MIDIEvents::GetDataByte2FromEvent(midiEvent), 120); midiEvent = MIDIEvents::NoteOff(15, 127, 42); VERIFY_EQUAL_NONCONT(MIDIEvents::GetTypeFromEvent(midiEvent), MIDIEvents::evNoteOff); VERIFY_EQUAL_NONCONT(MIDIEvents::GetChannelFromEvent(midiEvent), 15); VERIFY_EQUAL_NONCONT(MIDIEvents::GetDataByte1FromEvent(midiEvent), 127); VERIFY_EQUAL_NONCONT(MIDIEvents::GetDataByte2FromEvent(midiEvent), 42); midiEvent = MIDIEvents::ProgramChange(1, 127); VERIFY_EQUAL_NONCONT(MIDIEvents::GetTypeFromEvent(midiEvent), MIDIEvents::evProgramChange); VERIFY_EQUAL_NONCONT(MIDIEvents::GetChannelFromEvent(midiEvent), 1); VERIFY_EQUAL_NONCONT(MIDIEvents::GetDataByte1FromEvent(midiEvent), 127); VERIFY_EQUAL_NONCONT(MIDIEvents::GetDataByte2FromEvent(midiEvent), 0); midiEvent = MIDIEvents::PitchBend(2, MIDIEvents::pitchBendCentre); VERIFY_EQUAL_NONCONT(MIDIEvents::GetTypeFromEvent(midiEvent), MIDIEvents::evPitchBend); VERIFY_EQUAL_NONCONT(MIDIEvents::GetChannelFromEvent(midiEvent), 2); VERIFY_EQUAL_NONCONT(MIDIEvents::GetDataByte1FromEvent(midiEvent), 0x00); VERIFY_EQUAL_NONCONT(MIDIEvents::GetDataByte2FromEvent(midiEvent), 0x40); midiEvent = MIDIEvents::System(MIDIEvents::sysStart); VERIFY_EQUAL_NONCONT(MIDIEvents::GetTypeFromEvent(midiEvent), MIDIEvents::evSystem); VERIFY_EQUAL_NONCONT(MIDIEvents::GetChannelFromEvent(midiEvent), MIDIEvents::sysStart); VERIFY_EQUAL_NONCONT(MIDIEvents::GetDataByte1FromEvent(midiEvent), 0); VERIFY_EQUAL_NONCONT(MIDIEvents::GetDataByte2FromEvent(midiEvent), 0); } // Check if our test file was loaded correctly. static void TestLoadXMFile(const CSoundFile &sndFile) { #ifdef MODPLUG_TRACKER const CModDoc *pModDoc = sndFile.GetpModDoc(); VERIFY_EQUAL_NONCONT(pModDoc->IsChannelUnused(0), true); VERIFY_EQUAL_NONCONT(pModDoc->IsChannelUnused(1), false); #endif // MODPLUG_TRACKER // Global Variables VERIFY_EQUAL_NONCONT(sndFile.GetTitle(), "Test Module"); VERIFY_EQUAL_NONCONT(sndFile.m_songMessage.at(0), 'O'); VERIFY_EQUAL_NONCONT(sndFile.m_nDefaultTempo, TEMPO(139, 0)); VERIFY_EQUAL_NONCONT(sndFile.m_nDefaultSpeed, 5); VERIFY_EQUAL_NONCONT(sndFile.m_nDefaultGlobalVolume, 128); VERIFY_EQUAL_NONCONT(sndFile.m_nVSTiVolume, 42); VERIFY_EQUAL_NONCONT(sndFile.m_nSamplePreAmp, 23); VERIFY_EQUAL_NONCONT((sndFile.m_SongFlags & SONG_FILE_FLAGS), SONG_LINEARSLIDES | SONG_EXFILTERRANGE); VERIFY_EQUAL_NONCONT(sndFile.m_playBehaviour[MSF_COMPATIBLE_PLAY], true); VERIFY_EQUAL_NONCONT(sndFile.m_playBehaviour[kMIDICCBugEmulation], false); VERIFY_EQUAL_NONCONT(sndFile.m_playBehaviour[kMPTOldSwingBehaviour], false); VERIFY_EQUAL_NONCONT(sndFile.m_playBehaviour[kOldMIDIPitchBends], false); VERIFY_EQUAL_NONCONT(sndFile.GetMixLevels(), mixLevelsCompatible); VERIFY_EQUAL_NONCONT(sndFile.m_nTempoMode, tempoModeModern); VERIFY_EQUAL_NONCONT(sndFile.m_nDefaultRowsPerBeat, 6); VERIFY_EQUAL_NONCONT(sndFile.m_nDefaultRowsPerMeasure, 12); VERIFY_EQUAL_NONCONT(sndFile.m_dwCreatedWithVersion, MAKE_VERSION_NUMERIC(1, 19, 02, 05)); VERIFY_EQUAL_NONCONT(sndFile.Order().GetRestartPos(), 1); // Macros VERIFY_EQUAL_NONCONT(sndFile.m_MidiCfg.GetParameteredMacroType(0), sfx_reso); VERIFY_EQUAL_NONCONT(sndFile.m_MidiCfg.GetParameteredMacroType(1), sfx_drywet); VERIFY_EQUAL_NONCONT(sndFile.m_MidiCfg.GetFixedMacroType(), zxx_resomode); // Channels VERIFY_EQUAL_NONCONT(sndFile.GetNumChannels(), 2); VERIFY_EQUAL_NONCONT(strcmp(sndFile.ChnSettings[0].szName, "First Channel"), 0); #ifndef NO_PLUGINS VERIFY_EQUAL_NONCONT(sndFile.ChnSettings[0].nMixPlugin, 0); #endif // NO_PLUGINS VERIFY_EQUAL_NONCONT(strcmp(sndFile.ChnSettings[1].szName, "Second Channel"), 0); #ifndef NO_PLUGINS VERIFY_EQUAL_NONCONT(sndFile.ChnSettings[1].nMixPlugin, 1); #endif // NO_PLUGINS // Samples VERIFY_EQUAL_NONCONT(sndFile.GetNumSamples(), 3); VERIFY_EQUAL_NONCONT(strcmp(sndFile.m_szNames[1], "Pulse Sample"), 0); VERIFY_EQUAL_NONCONT(strcmp(sndFile.m_szNames[2], "Empty Sample"), 0); VERIFY_EQUAL_NONCONT(strcmp(sndFile.m_szNames[3], "Unassigned Sample"), 0); #ifdef MODPLUG_TRACKER VERIFY_EQUAL_NONCONT(pModDoc->FindSampleParent(1), 1); VERIFY_EQUAL_NONCONT(pModDoc->FindSampleParent(2), 1); VERIFY_EQUAL_NONCONT(pModDoc->FindSampleParent(3), INSTRUMENTINDEX_INVALID); #endif // MODPLUG_TRACKER const ModSample &sample = sndFile.GetSample(1); VERIFY_EQUAL_NONCONT(sample.GetBytesPerSample(), 1); VERIFY_EQUAL_NONCONT(sample.GetNumChannels(), 1); VERIFY_EQUAL_NONCONT(sample.GetElementarySampleSize(), 1); VERIFY_EQUAL_NONCONT(sample.GetSampleSizeInBytes(), 16); VERIFY_EQUAL_NONCONT(sample.nFineTune, 35); VERIFY_EQUAL_NONCONT(sample.RelativeTone, 1); VERIFY_EQUAL_NONCONT(sample.nVolume, 32 * 4); VERIFY_EQUAL_NONCONT(sample.nGlobalVol, 64); VERIFY_EQUAL_NONCONT(sample.nPan, 160); VERIFY_EQUAL_NONCONT(sample.uFlags, CHN_PANNING | CHN_LOOP | CHN_PINGPONGLOOP); VERIFY_EQUAL_NONCONT(sample.nLoopStart, 1); VERIFY_EQUAL_NONCONT(sample.nLoopEnd, 8); VERIFY_EQUAL_NONCONT(sample.nVibType, VIB_SQUARE); VERIFY_EQUAL_NONCONT(sample.nVibSweep, 3); VERIFY_EQUAL_NONCONT(sample.nVibRate, 4); VERIFY_EQUAL_NONCONT(sample.nVibDepth, 5); // Sample Data for(size_t i = 0; i < 6; i++) { VERIFY_EQUAL_NONCONT(sample.pSample8[i], 18); } for(size_t i = 6; i < 16; i++) { VERIFY_EQUAL_NONCONT(sample.pSample8[i], 0); } // Instruments VERIFY_EQUAL_NONCONT(sndFile.GetNumInstruments(), 1); const ModInstrument *pIns = sndFile.Instruments[1]; VERIFY_EQUAL_NONCONT(pIns->nFadeOut, 1024); VERIFY_EQUAL_NONCONT(pIns->nPan, 128); VERIFY_EQUAL_NONCONT(pIns->dwFlags, InstrumentFlags(0)); VERIFY_EQUAL_NONCONT(pIns->nPPS, 0); VERIFY_EQUAL_NONCONT(pIns->nPPC, NOTE_MIDDLEC - 1); VERIFY_EQUAL_NONCONT(pIns->nVolRampUp, 1200); VERIFY_EQUAL_NONCONT(pIns->nResampling, (unsigned)SRCMODE_POLYPHASE); VERIFY_EQUAL_NONCONT(pIns->IsCutoffEnabled(), false); VERIFY_EQUAL_NONCONT(pIns->GetCutoff(), 0); VERIFY_EQUAL_NONCONT(pIns->IsResonanceEnabled(), false); VERIFY_EQUAL_NONCONT(pIns->GetResonance(), 0); VERIFY_EQUAL_NONCONT(pIns->nFilterMode, FLTMODE_UNCHANGED); VERIFY_EQUAL_NONCONT(pIns->nVolSwing, 0); VERIFY_EQUAL_NONCONT(pIns->nPanSwing, 0); VERIFY_EQUAL_NONCONT(pIns->nCutSwing, 0); VERIFY_EQUAL_NONCONT(pIns->nResSwing, 0); VERIFY_EQUAL_NONCONT(pIns->nNNA, NNA_NOTECUT); VERIFY_EQUAL_NONCONT(pIns->nDCT, DCT_NONE); VERIFY_EQUAL_NONCONT(pIns->nMixPlug, 1); VERIFY_EQUAL_NONCONT(pIns->nMidiChannel, 16); VERIFY_EQUAL_NONCONT(pIns->nMidiProgram, 64); VERIFY_EQUAL_NONCONT(pIns->wMidiBank, 2); VERIFY_EQUAL_NONCONT(pIns->midiPWD, 8); VERIFY_EQUAL_NONCONT(pIns->pTuning, sndFile.GetDefaultTuning()); VERIFY_EQUAL_NONCONT(pIns->pitchToTempoLock, TEMPO(0, 0)); VERIFY_EQUAL_NONCONT(pIns->nPluginVelocityHandling, PLUGIN_VELOCITYHANDLING_VOLUME); VERIFY_EQUAL_NONCONT(pIns->nPluginVolumeHandling, PLUGIN_VOLUMEHANDLING_MIDI); for(size_t i = sndFile.GetModSpecifications().noteMin; i < sndFile.GetModSpecifications().noteMax; i++) { VERIFY_EQUAL_NONCONT(pIns->Keyboard[i], (i == NOTE_MIDDLEC - 1) ? 2 : 1); } VERIFY_EQUAL_NONCONT(pIns->VolEnv.dwFlags, ENV_ENABLED | ENV_SUSTAIN); VERIFY_EQUAL_NONCONT(pIns->VolEnv.size(), 3); VERIFY_EQUAL_NONCONT(pIns->VolEnv.nReleaseNode, ENV_RELEASE_NODE_UNSET); VERIFY_EQUAL_NONCONT(pIns->VolEnv[2].tick, 96); VERIFY_EQUAL_NONCONT(pIns->VolEnv[2].value, 0); VERIFY_EQUAL_NONCONT(pIns->VolEnv.nSustainStart, 1); VERIFY_EQUAL_NONCONT(pIns->VolEnv.nSustainEnd, 1); VERIFY_EQUAL_NONCONT(pIns->PanEnv.dwFlags, ENV_LOOP); VERIFY_EQUAL_NONCONT(pIns->PanEnv.size(), 12); VERIFY_EQUAL_NONCONT(pIns->PanEnv.nLoopStart, 9); VERIFY_EQUAL_NONCONT(pIns->PanEnv.nLoopEnd, 11); VERIFY_EQUAL_NONCONT(pIns->PanEnv.nReleaseNode, ENV_RELEASE_NODE_UNSET); VERIFY_EQUAL_NONCONT(pIns->PanEnv[9].tick, 46); VERIFY_EQUAL_NONCONT(pIns->PanEnv[9].value, 23); VERIFY_EQUAL_NONCONT(pIns->PitchEnv.dwFlags, EnvelopeFlags(0)); VERIFY_EQUAL_NONCONT(pIns->PitchEnv.size(), 0); // Sequences VERIFY_EQUAL_NONCONT(sndFile.Order.GetNumSequences(), 1); VERIFY_EQUAL_NONCONT(sndFile.Order()[0], 0); VERIFY_EQUAL_NONCONT(sndFile.Order()[1], 1); // Patterns VERIFY_EQUAL_NONCONT(sndFile.Patterns.GetNumPatterns(), 2); VERIFY_EQUAL_NONCONT(sndFile.Patterns[0].GetName(), "First Pattern"); VERIFY_EQUAL_NONCONT(sndFile.Patterns[0].GetNumRows(), 64); VERIFY_EQUAL_NONCONT(sndFile.Patterns[0].GetNumChannels(), 2); VERIFY_EQUAL_NONCONT(sndFile.Patterns[0].GetOverrideSignature(), false); VERIFY_EQUAL_NONCONT(sndFile.Patterns[0].GetRowsPerBeat(), 0); VERIFY_EQUAL_NONCONT(sndFile.Patterns[0].GetRowsPerMeasure(), 0); VERIFY_EQUAL_NONCONT(sndFile.Patterns.IsPatternEmpty(0), true); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetName(), "Second Pattern"); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetNumRows(), 32); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetNumChannels(), 2); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetOverrideSignature(), false); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetRowsPerBeat(), 0); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetRowsPerMeasure(), 0); VERIFY_EQUAL_NONCONT(sndFile.Patterns.IsPatternEmpty(1), false); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(0, 0)->IsPcNote(), false); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(0, 0)->note, NOTE_NONE); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(0, 0)->instr, 0); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(0, 0)->volcmd, VOLCMD_VIBRATOSPEED); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(0, 0)->vol, 15); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(31, 0)->IsEmpty(), true); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(31, 1)->IsEmpty(), false); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(31, 1)->IsPcNote(), false); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(31, 1)->note, NOTE_MIDDLEC + 12); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(31, 1)->instr, 45); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(31, 1)->volcmd, VOLCMD_VOLSLIDEDOWN); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(31, 1)->vol, 5); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(31, 1)->command, CMD_PANNING8); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(31, 1)->param, 0xFF); // Test 4-Bit Panning conversion for(int i = 0; i < 16; i++) { VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(10 + i, 0)->vol, i * 4); } // Plugins #ifndef NO_PLUGINS const SNDMIXPLUGIN &plug = sndFile.m_MixPlugins[0]; VERIFY_EQUAL_NONCONT(strcmp(plug.GetName(), "First Plugin"), 0); VERIFY_EQUAL_NONCONT(plug.fDryRatio, 0.26f); VERIFY_EQUAL_NONCONT(plug.IsMasterEffect(), true); VERIFY_EQUAL_NONCONT(plug.GetGain(), 11); #endif // NO_PLUGINS } // Check if our test file was loaded correctly. static void TestLoadMPTMFile(const CSoundFile &sndFile) { // Global Variables VERIFY_EQUAL_NONCONT(sndFile.GetTitle(), "Test Module_____________X"); VERIFY_EQUAL_NONCONT(sndFile.m_songMessage.at(0), 'O'); VERIFY_EQUAL_NONCONT(sndFile.m_nDefaultTempo, TEMPO(139, 999)); VERIFY_EQUAL_NONCONT(sndFile.m_nDefaultSpeed, 5); VERIFY_EQUAL_NONCONT(sndFile.m_nDefaultGlobalVolume, 128); VERIFY_EQUAL_NONCONT(sndFile.m_nVSTiVolume, 42); VERIFY_EQUAL_NONCONT(sndFile.m_nSamplePreAmp, 23); VERIFY_EQUAL_NONCONT((sndFile.m_SongFlags & SONG_FILE_FLAGS), SONG_LINEARSLIDES | SONG_EXFILTERRANGE | SONG_ITCOMPATGXX | SONG_ITOLDEFFECTS); VERIFY_EQUAL_NONCONT(sndFile.m_playBehaviour[MSF_COMPATIBLE_PLAY], true); VERIFY_EQUAL_NONCONT(sndFile.m_playBehaviour[kMIDICCBugEmulation], false); VERIFY_EQUAL_NONCONT(sndFile.m_playBehaviour[kMPTOldSwingBehaviour], false); VERIFY_EQUAL_NONCONT(sndFile.m_playBehaviour[kOldMIDIPitchBends], false); VERIFY_EQUAL_NONCONT(sndFile.GetMixLevels(), mixLevelsCompatible); VERIFY_EQUAL_NONCONT(sndFile.m_nTempoMode, tempoModeModern); VERIFY_EQUAL_NONCONT(sndFile.m_nDefaultRowsPerBeat, 6); VERIFY_EQUAL_NONCONT(sndFile.m_nDefaultRowsPerMeasure, 12); VERIFY_EQUAL_NONCONT(sndFile.m_dwCreatedWithVersion, MAKE_VERSION_NUMERIC(1, 19, 02, 05)); VERIFY_EQUAL_NONCONT(sndFile.m_nResampling, SRCMODE_POLYPHASE); VERIFY_EQUAL_NONCONT(sndFile.m_songArtist, MPT_USTRING("Tester")); VERIFY_EQUAL_NONCONT(sndFile.m_tempoSwing.size(), 6); VERIFY_EQUAL_NONCONT(sndFile.m_tempoSwing[0], 29360125); VERIFY_EQUAL_NONCONT(sndFile.m_tempoSwing[1], 4194305); VERIFY_EQUAL_NONCONT(sndFile.m_tempoSwing[2], 29360128); VERIFY_EQUAL_NONCONT(sndFile.m_tempoSwing[3], 4194305); VERIFY_EQUAL_NONCONT(sndFile.m_tempoSwing[4], 29360128); VERIFY_EQUAL_NONCONT(sndFile.m_tempoSwing[5], 4194305); // Edit history VERIFY_EQUAL_NONCONT(sndFile.GetFileHistory().size() > 0, true); const FileHistory &fh = sndFile.GetFileHistory().at(0); VERIFY_EQUAL_NONCONT(fh.loadDate.tm_year, 111); VERIFY_EQUAL_NONCONT(fh.loadDate.tm_mon, 5); VERIFY_EQUAL_NONCONT(fh.loadDate.tm_mday, 14); VERIFY_EQUAL_NONCONT(fh.loadDate.tm_hour, 21); VERIFY_EQUAL_NONCONT(fh.loadDate.tm_min, 8); VERIFY_EQUAL_NONCONT(fh.loadDate.tm_sec, 32); VERIFY_EQUAL_NONCONT((uint32)((double)fh.openTime / HISTORY_TIMER_PRECISION), 31); // Macros VERIFY_EQUAL_NONCONT(sndFile.m_MidiCfg.GetParameteredMacroType(0), sfx_reso); VERIFY_EQUAL_NONCONT(sndFile.m_MidiCfg.GetParameteredMacroType(1), sfx_drywet); VERIFY_EQUAL_NONCONT(sndFile.m_MidiCfg.GetParameteredMacroType(2), sfx_polyAT); VERIFY_EQUAL_NONCONT(sndFile.m_MidiCfg.GetFixedMacroType(), zxx_resomode); // Channels VERIFY_EQUAL_NONCONT(sndFile.GetNumChannels(), 70); VERIFY_EQUAL_NONCONT(strcmp(sndFile.ChnSettings[0].szName, "First Channel"), 0); VERIFY_EQUAL_NONCONT(sndFile.ChnSettings[0].nPan, 32); VERIFY_EQUAL_NONCONT(sndFile.ChnSettings[0].nVolume, 32); VERIFY_EQUAL_NONCONT(sndFile.ChnSettings[0].dwFlags, CHN_MUTE); #ifndef NO_PLUGINS VERIFY_EQUAL_NONCONT(sndFile.ChnSettings[0].nMixPlugin, 0); #endif // NO_PLUGINS VERIFY_EQUAL_NONCONT(strcmp(sndFile.ChnSettings[1].szName, "Second Channel"), 0); VERIFY_EQUAL_NONCONT(sndFile.ChnSettings[1].nPan, 128); VERIFY_EQUAL_NONCONT(sndFile.ChnSettings[1].nVolume, 16); VERIFY_EQUAL_NONCONT(sndFile.ChnSettings[1].dwFlags, CHN_SURROUND); #ifndef NO_PLUGINS VERIFY_EQUAL_NONCONT(sndFile.ChnSettings[1].nMixPlugin, 1); #endif // NO_PLUGINS VERIFY_EQUAL_NONCONT(strcmp(sndFile.ChnSettings[69].szName, "Last Channel______X"), 0); VERIFY_EQUAL_NONCONT(sndFile.ChnSettings[69].nPan, 256); VERIFY_EQUAL_NONCONT(sndFile.ChnSettings[69].nVolume, 7); VERIFY_EQUAL_NONCONT(sndFile.ChnSettings[69].dwFlags, ChannelFlags(0)); #ifndef NO_PLUGINS VERIFY_EQUAL_NONCONT(sndFile.ChnSettings[69].nMixPlugin, 1); #endif // NO_PLUGINS // Samples VERIFY_EQUAL_NONCONT(sndFile.GetNumSamples(), 4); { const ModSample &sample = sndFile.GetSample(1); VERIFY_EQUAL_NONCONT(sample.GetBytesPerSample(), 1); VERIFY_EQUAL_NONCONT(sample.GetNumChannels(), 1); VERIFY_EQUAL_NONCONT(sample.GetElementarySampleSize(), 1); VERIFY_EQUAL_NONCONT(sample.GetSampleSizeInBytes(), 16); VERIFY_EQUAL_NONCONT(sample.GetSampleRate(MOD_TYPE_MPT), 9001); VERIFY_EQUAL_NONCONT(sample.nVolume, 32 * 4); VERIFY_EQUAL_NONCONT(sample.nGlobalVol, 16); VERIFY_EQUAL_NONCONT(sample.nPan, 160); VERIFY_EQUAL_NONCONT(sample.uFlags, CHN_PANNING | CHN_LOOP | CHN_SUSTAINLOOP | CHN_PINGPONGSUSTAIN); VERIFY_EQUAL_NONCONT(sample.nLoopStart, 1); VERIFY_EQUAL_NONCONT(sample.nLoopEnd, 8); VERIFY_EQUAL_NONCONT(sample.nSustainStart, 1); VERIFY_EQUAL_NONCONT(sample.nSustainEnd, 7); VERIFY_EQUAL_NONCONT(sample.nVibType, VIB_SQUARE); VERIFY_EQUAL_NONCONT(sample.nVibSweep, 3); VERIFY_EQUAL_NONCONT(sample.nVibRate, 4); VERIFY_EQUAL_NONCONT(sample.nVibDepth, 5); // Sample Data for(size_t i = 0; i < 6; i++) { VERIFY_EQUAL_NONCONT(sample.pSample8[i], 18); } for(size_t i = 6; i < 16; i++) { VERIFY_EQUAL_NONCONT(sample.pSample8[i], 0); } VERIFY_EQUAL_NONCONT(sample.cues[0], 2); VERIFY_EQUAL_NONCONT(sample.cues[8], 9); } { const ModSample &sample = sndFile.GetSample(2); VERIFY_EQUAL_NONCONT(strcmp(sndFile.m_szNames[2], "Stereo / 16-Bit"), 0); VERIFY_EQUAL_NONCONT(sample.GetBytesPerSample(), 4); VERIFY_EQUAL_NONCONT(sample.GetNumChannels(), 2); VERIFY_EQUAL_NONCONT(sample.GetElementarySampleSize(), 2); VERIFY_EQUAL_NONCONT(sample.GetSampleSizeInBytes(), 16 * 4); VERIFY_EQUAL_NONCONT(sample.GetSampleRate(MOD_TYPE_MPT), 16000); VERIFY_EQUAL_NONCONT(sample.uFlags, CHN_16BIT | CHN_STEREO | CHN_LOOP); // Sample Data (Stereo Interleaved) for(size_t i = 0; i < 7; i++) { VERIFY_EQUAL_NONCONT(sample.pSample16[4 + i], int16(-32768)); } VERIFY_EQUAL_NONCONT(sample.cues[0], 3); VERIFY_EQUAL_NONCONT(sample.cues[8], 14); } // External sample { const ModSample &sample = sndFile.GetSample(4); VERIFY_EQUAL_NONCONT(strcmp(sndFile.m_szNames[4], "Overridden Name"), 0); VERIFY_EQUAL_NONCONT(strcmp(sample.filename, "External"), 0); #ifdef MPT_EXTERNAL_SAMPLES VERIFY_EQUAL_NONCONT(sample.GetBytesPerSample(), 1); VERIFY_EQUAL_NONCONT(sample.GetNumChannels(), 1); VERIFY_EQUAL_NONCONT(sample.GetElementarySampleSize(), 1); VERIFY_EQUAL_NONCONT(sample.GetSampleSizeInBytes(), 64); VERIFY_EQUAL_NONCONT(sample.nLoopStart, 42); VERIFY_EQUAL_NONCONT(sample.nLoopEnd, 55); VERIFY_EQUAL_NONCONT(sample.nSustainStart, 42); VERIFY_EQUAL_NONCONT(sample.nSustainEnd, 55); VERIFY_EQUAL_NONCONT(sample.uFlags, CHN_LOOP | CHN_SUSTAINLOOP | CHN_PINGPONGSUSTAIN | SMP_KEEPONDISK); #endif // MPT_EXTERNAL_SAMPLES VERIFY_EQUAL_NONCONT(sample.GetSampleRate(MOD_TYPE_MPT), 10101); VERIFY_EQUAL_NONCONT(sample.nVolume, 26 * 4); VERIFY_EQUAL_NONCONT(sample.nGlobalVol, 26); VERIFY_EQUAL_NONCONT(sample.nPan, 26 * 4); VERIFY_EQUAL_NONCONT(sample.nVibType, VIB_SINE); VERIFY_EQUAL_NONCONT(sample.nVibSweep, 37); VERIFY_EQUAL_NONCONT(sample.nVibRate, 42); VERIFY_EQUAL_NONCONT(sample.nVibDepth, 23); // Sample Data #ifdef MPT_EXTERNAL_SAMPLES for(size_t i = 0; i < 16; i++) { VERIFY_EQUAL_NONCONT(sample.pSample8[i], int8(45)); } #endif // MPT_EXTERNAL_SAMPLES VERIFY_EQUAL_NONCONT(sample.cues[0], 10); VERIFY_EQUAL_NONCONT(sample.cues[8], 50); } // Instruments VERIFY_EQUAL_NONCONT(sndFile.GetNumInstruments(), 2); for(INSTRUMENTINDEX ins = 1; ins <= 2; ins++) { const ModInstrument *pIns = sndFile.Instruments[ins]; VERIFY_EQUAL_NONCONT(pIns->nGlobalVol, 32); VERIFY_EQUAL_NONCONT(pIns->nFadeOut, 1024); VERIFY_EQUAL_NONCONT(pIns->nPan, 64); VERIFY_EQUAL_NONCONT(pIns->dwFlags, INS_SETPANNING); VERIFY_EQUAL_NONCONT(pIns->nPPS, 8); VERIFY_EQUAL_NONCONT(pIns->nPPC, (NOTE_MIDDLEC - NOTE_MIN) + 6); // F#5 VERIFY_EQUAL_NONCONT(pIns->nVolRampUp, 1200); VERIFY_EQUAL_NONCONT(pIns->nResampling, (unsigned)SRCMODE_POLYPHASE); VERIFY_EQUAL_NONCONT(pIns->IsCutoffEnabled(), true); VERIFY_EQUAL_NONCONT(pIns->GetCutoff(), 0x32); VERIFY_EQUAL_NONCONT(pIns->IsResonanceEnabled(), true); VERIFY_EQUAL_NONCONT(pIns->GetResonance(), 0x64); VERIFY_EQUAL_NONCONT(pIns->nFilterMode, FLTMODE_HIGHPASS); VERIFY_EQUAL_NONCONT(pIns->nVolSwing, 0x30); VERIFY_EQUAL_NONCONT(pIns->nPanSwing, 0x18); VERIFY_EQUAL_NONCONT(pIns->nCutSwing, 0x0C); VERIFY_EQUAL_NONCONT(pIns->nResSwing, 0x3C); VERIFY_EQUAL_NONCONT(pIns->nNNA, NNA_CONTINUE); VERIFY_EQUAL_NONCONT(pIns->nDCT, DCT_NOTE); VERIFY_EQUAL_NONCONT(pIns->nDNA, DNA_NOTEFADE); VERIFY_EQUAL_NONCONT(pIns->nMixPlug, 1); VERIFY_EQUAL_NONCONT(pIns->nMidiChannel, 16); VERIFY_EQUAL_NONCONT(pIns->nMidiProgram, 64); VERIFY_EQUAL_NONCONT(pIns->wMidiBank, 2); VERIFY_EQUAL_NONCONT(pIns->midiPWD, ins); VERIFY_EQUAL_NONCONT(pIns->pTuning, sndFile.GetDefaultTuning()); VERIFY_EQUAL_NONCONT(pIns->pitchToTempoLock, TEMPO(130, 2000)); VERIFY_EQUAL_NONCONT(pIns->nPluginVelocityHandling, PLUGIN_VELOCITYHANDLING_VOLUME); VERIFY_EQUAL_NONCONT(pIns->nPluginVolumeHandling, PLUGIN_VOLUMEHANDLING_MIDI); for(size_t i = 0; i < NOTE_MAX; i++) { VERIFY_EQUAL_NONCONT(pIns->Keyboard[i], (i == NOTE_MIDDLEC - 1) ? 99 : 1); VERIFY_EQUAL_NONCONT(pIns->NoteMap[i], (i == NOTE_MIDDLEC - 1) ? (i + 13) : (i + 1)); } VERIFY_EQUAL_NONCONT(pIns->VolEnv.dwFlags, ENV_ENABLED | ENV_CARRY); VERIFY_EQUAL_NONCONT(pIns->VolEnv.size(), 3); VERIFY_EQUAL_NONCONT(pIns->VolEnv.nReleaseNode, 1); VERIFY_EQUAL_NONCONT(pIns->VolEnv[2].tick, 96); VERIFY_EQUAL_NONCONT(pIns->VolEnv[2].value, 0); VERIFY_EQUAL_NONCONT(pIns->PanEnv.dwFlags, ENV_LOOP); VERIFY_EQUAL_NONCONT(pIns->PanEnv.size(), 76); VERIFY_EQUAL_NONCONT(pIns->PanEnv.nLoopStart, 22); VERIFY_EQUAL_NONCONT(pIns->PanEnv.nLoopEnd, 29); VERIFY_EQUAL_NONCONT(pIns->PanEnv.nReleaseNode, ENV_RELEASE_NODE_UNSET); VERIFY_EQUAL_NONCONT(pIns->PanEnv[75].tick, 427); VERIFY_EQUAL_NONCONT(pIns->PanEnv[75].value, 27); VERIFY_EQUAL_NONCONT(pIns->PitchEnv.dwFlags, ENV_ENABLED | ENV_CARRY | ENV_SUSTAIN | ENV_FILTER); VERIFY_EQUAL_NONCONT(pIns->PitchEnv.size(), 3); VERIFY_EQUAL_NONCONT(pIns->PitchEnv.nSustainStart, 1); VERIFY_EQUAL_NONCONT(pIns->PitchEnv.nSustainEnd, 2); VERIFY_EQUAL_NONCONT(pIns->PitchEnv[1].tick, 96); VERIFY_EQUAL_NONCONT(pIns->PitchEnv[1].value, 64); } // Sequences VERIFY_EQUAL_NONCONT(sndFile.Order.GetNumSequences(), 2); VERIFY_EQUAL_NONCONT(sndFile.Order(0).GetLengthTailTrimmed(), 3); VERIFY_EQUAL_NONCONT(sndFile.Order(0).GetName(), "First Sequence"); VERIFY_EQUAL_NONCONT(sndFile.Order(0)[0], sndFile.Order.GetIgnoreIndex()); VERIFY_EQUAL_NONCONT(sndFile.Order(0)[1], 0); VERIFY_EQUAL_NONCONT(sndFile.Order(0)[2], sndFile.Order.GetIgnoreIndex()); VERIFY_EQUAL_NONCONT(sndFile.Order(0).GetRestartPos(), 1); VERIFY_EQUAL_NONCONT(sndFile.Order(1).GetLengthTailTrimmed(), 3); VERIFY_EQUAL_NONCONT(sndFile.Order(1).GetName(), "Second Sequence"); VERIFY_EQUAL_NONCONT(sndFile.Order(1)[0], 1); VERIFY_EQUAL_NONCONT(sndFile.Order(1)[1], 2); VERIFY_EQUAL_NONCONT(sndFile.Order(1)[2], 3); VERIFY_EQUAL_NONCONT(sndFile.Order(1).GetRestartPos(), 2); // Patterns VERIFY_EQUAL_NONCONT(sndFile.Patterns.GetNumPatterns(), 2); VERIFY_EQUAL_NONCONT(sndFile.Patterns[0].GetName(), "First Pattern"); VERIFY_EQUAL_NONCONT(sndFile.Patterns[0].GetNumRows(), 70); VERIFY_EQUAL_NONCONT(sndFile.Patterns[0].GetNumChannels(), 70); VERIFY_EQUAL_NONCONT(sndFile.Patterns[0].GetOverrideSignature(), true); VERIFY_EQUAL_NONCONT(sndFile.Patterns[0].GetRowsPerBeat(), 5); VERIFY_EQUAL_NONCONT(sndFile.Patterns[0].GetRowsPerMeasure(), 10); VERIFY_EQUAL_NONCONT(sndFile.Patterns[0].HasTempoSwing(), true); VERIFY_EQUAL_NONCONT(sndFile.Patterns.IsPatternEmpty(0), true); { TempoSwing swing = sndFile.Patterns[0].GetTempoSwing(); VERIFY_EQUAL_NONCONT(swing.size(), 5); VERIFY_EQUAL_NONCONT(swing[0], 16770149); VERIFY_EQUAL_NONCONT(swing[1], 16803696); VERIFY_EQUAL_NONCONT(swing[2], 16770157); VERIFY_EQUAL_NONCONT(swing[3], 29347774); VERIFY_EQUAL_NONCONT(swing[4], 4194304); } VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetName(), "Second Pattern"); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetNumRows(), 32); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetNumChannels(), 70); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetOverrideSignature(), false); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetRowsPerBeat(), 0); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetRowsPerMeasure(), 0); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].HasTempoSwing(), false); VERIFY_EQUAL_NONCONT(sndFile.Patterns.IsPatternEmpty(1), false); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(0, 0)->IsPcNote(), true); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(0, 0)->note, NOTE_PC); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(0, 0)->instr, 99); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(0, 0)->GetValueVolCol(), 1); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(0, 0)->GetValueEffectCol(), 200); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(31, 0)->IsEmpty(), true); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(31, 1)->IsEmpty(), false); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(31, 1)->IsPcNote(), false); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(31, 1)->note, NOTE_MIDDLEC + 12); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(31, 1)->instr, 45); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(31, 1)->volcmd, VOLCMD_VOLSLIDEDOWN); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(31, 1)->vol, 5); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(31, 1)->command, CMD_PANNING8); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(31, 1)->param, 0xFF); // Plugins #ifndef NO_PLUGINS const SNDMIXPLUGIN &plug = sndFile.m_MixPlugins[0]; VERIFY_EQUAL_NONCONT(strcmp(plug.GetName(), "First Plugin"), 0); VERIFY_EQUAL_NONCONT(plug.fDryRatio, 0.26f); VERIFY_EQUAL_NONCONT(plug.IsMasterEffect(), true); VERIFY_EQUAL_NONCONT(plug.GetGain(), 11); VERIFY_EQUAL_NONCONT(plug.pMixPlugin != nullptr, true); VERIFY_EQUAL_NONCONT(plug.pMixPlugin->GetParameter(1), 0.5f); VERIFY_EQUAL_NONCONT(plug.pMixPlugin->IsInstrument(), false); #endif // NO_PLUGINS #ifdef MODPLUG_TRACKER // MIDI Mapping VERIFY_EQUAL_NONCONT(sndFile.GetMIDIMapper().GetCount(), 1); const CMIDIMappingDirective &mapping = sndFile.GetMIDIMapper().GetDirective(0); VERIFY_EQUAL_NONCONT(mapping.GetAllowPatternEdit(), true); VERIFY_EQUAL_NONCONT(mapping.GetCaptureMIDI(), false); VERIFY_EQUAL_NONCONT(mapping.IsActive(), true); VERIFY_EQUAL_NONCONT(mapping.GetAnyChannel(), false); VERIFY_EQUAL_NONCONT(mapping.GetChannel(), 5); VERIFY_EQUAL_NONCONT(mapping.GetPlugIndex(), 1); VERIFY_EQUAL_NONCONT(mapping.GetParamIndex(), 0); VERIFY_EQUAL_NONCONT(mapping.GetEvent(), MIDIEvents::evControllerChange); VERIFY_EQUAL_NONCONT(mapping.GetController(), MIDIEvents::MIDICC_ModulationWheel_Coarse); #endif VERIFY_EQUAL_NONCONT(sndFile.FrequencyToCutOff(sndFile.CutOffToFrequency(0)), 0); VERIFY_EQUAL_NONCONT(sndFile.FrequencyToCutOff(sndFile.CutOffToFrequency(80)), 80); VERIFY_EQUAL_NONCONT(sndFile.FrequencyToCutOff(sndFile.CutOffToFrequency(127)), 127); } // Check if our test file was loaded correctly. static void TestLoadS3MFile(const CSoundFile &sndFile, bool resaved) { // Global Variables VERIFY_EQUAL_NONCONT(sndFile.GetTitle(), "S3M_Test__________________X"); VERIFY_EQUAL_NONCONT(sndFile.m_nDefaultTempo, TEMPO(33, 0)); VERIFY_EQUAL_NONCONT(sndFile.m_nDefaultSpeed, 254); VERIFY_EQUAL_NONCONT(sndFile.m_nDefaultGlobalVolume, 32 * 4); VERIFY_EQUAL_NONCONT(sndFile.m_nVSTiVolume, 48); VERIFY_EQUAL_NONCONT(sndFile.m_nSamplePreAmp, 16); VERIFY_EQUAL_NONCONT((sndFile.m_SongFlags & SONG_FILE_FLAGS), SONG_FASTVOLSLIDES); VERIFY_EQUAL_NONCONT(sndFile.GetMixLevels(), mixLevelsCompatible); VERIFY_EQUAL_NONCONT(sndFile.m_nTempoMode, tempoModeClassic); VERIFY_EQUAL_NONCONT(sndFile.m_dwLastSavedWithVersion, resaved ? (MptVersion::num & 0xFFFF0000) : MAKE_VERSION_NUMERIC(1, 27, 00, 00)); VERIFY_EQUAL_NONCONT(sndFile.Order().GetRestartPos(), 0); // Channels VERIFY_EQUAL_NONCONT(sndFile.GetNumChannels(), 4); VERIFY_EQUAL_NONCONT(sndFile.ChnSettings[0].nPan, 0); VERIFY_EQUAL_NONCONT(sndFile.ChnSettings[0].dwFlags, ChannelFlags(0)); VERIFY_EQUAL_NONCONT(sndFile.ChnSettings[1].nPan, 256); VERIFY_EQUAL_NONCONT(sndFile.ChnSettings[1].dwFlags, CHN_MUTE); VERIFY_EQUAL_NONCONT(sndFile.ChnSettings[2].nPan, 85); VERIFY_EQUAL_NONCONT(sndFile.ChnSettings[2].dwFlags, ChannelFlags(0)); VERIFY_EQUAL_NONCONT(sndFile.ChnSettings[3].nPan, 171); VERIFY_EQUAL_NONCONT(sndFile.ChnSettings[3].dwFlags, CHN_MUTE); // Samples VERIFY_EQUAL_NONCONT(sndFile.GetNumSamples(), 3); { const ModSample &sample = sndFile.GetSample(1); VERIFY_EQUAL_NONCONT(strcmp(sndFile.m_szNames[1], "Sample_1__________________X"), 0); VERIFY_EQUAL_NONCONT(strcmp(sample.filename, "Filename_1_X"), 0); VERIFY_EQUAL_NONCONT(sample.GetBytesPerSample(), 1); VERIFY_EQUAL_NONCONT(sample.GetNumChannels(), 1); VERIFY_EQUAL_NONCONT(sample.GetElementarySampleSize(), 1); VERIFY_EQUAL_NONCONT(sample.GetSampleSizeInBytes(), 60); VERIFY_EQUAL_NONCONT(sample.GetSampleRate(MOD_TYPE_S3M), 9001); VERIFY_EQUAL_NONCONT(sample.nVolume, 32 * 4); VERIFY_EQUAL_NONCONT(sample.nGlobalVol, 64); VERIFY_EQUAL_NONCONT(sample.uFlags, CHN_LOOP); VERIFY_EQUAL_NONCONT(sample.nLoopStart, 16); VERIFY_EQUAL_NONCONT(sample.nLoopEnd, 60); // Sample Data for(size_t i = 0; i < 30; i++) { VERIFY_EQUAL_NONCONT(sample.pSample8[i], 127); } for(size_t i = 31; i < 60; i++) { VERIFY_EQUAL_NONCONT(sample.pSample8[i], -128); } } { const ModSample &sample = sndFile.GetSample(2); VERIFY_EQUAL_NONCONT(strcmp(sndFile.m_szNames[2], "Empty"), 0); VERIFY_EQUAL_NONCONT(sample.GetSampleRate(MOD_TYPE_S3M), 16384); VERIFY_EQUAL_NONCONT(sample.nVolume, 2 * 4); } { const ModSample &sample = sndFile.GetSample(3); VERIFY_EQUAL_NONCONT(strcmp(sndFile.m_szNames[3], "Stereo / 16-Bit"), 0); VERIFY_EQUAL_NONCONT(strcmp(sample.filename, "Filename_3_X"), 0); VERIFY_EQUAL_NONCONT(sample.GetBytesPerSample(), 4); VERIFY_EQUAL_NONCONT(sample.GetNumChannels(), 2); VERIFY_EQUAL_NONCONT(sample.GetElementarySampleSize(), 2); VERIFY_EQUAL_NONCONT(sample.GetSampleSizeInBytes(), 64); VERIFY_EQUAL_NONCONT(sample.GetSampleRate(MOD_TYPE_S3M), 16000); VERIFY_EQUAL_NONCONT(sample.nVolume, 0); VERIFY_EQUAL_NONCONT(sample.uFlags, CHN_LOOP | CHN_16BIT | CHN_STEREO); VERIFY_EQUAL_NONCONT(sample.nLoopStart, 0); VERIFY_EQUAL_NONCONT(sample.nLoopEnd, 16); // Sample Data (Stereo Interleaved) for(size_t i = 0; i < 7; i++) { VERIFY_EQUAL_NONCONT(sample.pSample16[4 + i], int16(-32768)); } } // Orders VERIFY_EQUAL_NONCONT(sndFile.Order().GetLengthTailTrimmed(), 5); VERIFY_EQUAL_NONCONT(sndFile.Order()[0], 0); VERIFY_EQUAL_NONCONT(sndFile.Order()[1], sndFile.Order.GetIgnoreIndex()); VERIFY_EQUAL_NONCONT(sndFile.Order()[2], sndFile.Order.GetInvalidPatIndex()); VERIFY_EQUAL_NONCONT(sndFile.Order()[3], 1); VERIFY_EQUAL_NONCONT(sndFile.Order()[4], 0); // Patterns VERIFY_EQUAL_NONCONT(sndFile.Patterns.GetNumPatterns(), 2); VERIFY_EQUAL_NONCONT(sndFile.Patterns[0].GetNumRows(), 64); VERIFY_EQUAL_NONCONT(sndFile.Patterns[0].GetNumChannels(), 4); VERIFY_EQUAL_NONCONT(sndFile.Patterns[0].GetOverrideSignature(), false); VERIFY_EQUAL_NONCONT(sndFile.Patterns[0].GetpModCommand(0, 0)->note, NOTE_MIN + 12); VERIFY_EQUAL_NONCONT(sndFile.Patterns[0].GetpModCommand(1, 0)->note, NOTE_MIN + 107); VERIFY_EQUAL_NONCONT(sndFile.Patterns[0].GetpModCommand(0, 1)->volcmd, VOLCMD_VOLUME); VERIFY_EQUAL_NONCONT(sndFile.Patterns[0].GetpModCommand(0, 1)->vol, 0); VERIFY_EQUAL_NONCONT(sndFile.Patterns[0].GetpModCommand(1, 1)->volcmd, VOLCMD_VOLUME); VERIFY_EQUAL_NONCONT(sndFile.Patterns[0].GetpModCommand(1, 1)->vol, 64); VERIFY_EQUAL_NONCONT(sndFile.Patterns[0].GetpModCommand(2, 1)->volcmd, VOLCMD_PANNING); VERIFY_EQUAL_NONCONT(sndFile.Patterns[0].GetpModCommand(2, 1)->vol, 0); VERIFY_EQUAL_NONCONT(sndFile.Patterns[0].GetpModCommand(3, 1)->volcmd, VOLCMD_PANNING); VERIFY_EQUAL_NONCONT(sndFile.Patterns[0].GetpModCommand(3, 1)->vol, 64); VERIFY_EQUAL_NONCONT(sndFile.Patterns[0].GetpModCommand(0, 3)->command, CMD_SPEED); VERIFY_EQUAL_NONCONT(sndFile.Patterns[0].GetpModCommand(0, 3)->param, 0x11); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetNumRows(), 64); VERIFY_EQUAL_NONCONT(sndFile.Patterns.IsPatternEmpty(1), false); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(63, 3)->param, 0x04); } #ifdef MODPLUG_TRACKER static bool ShouldRunTests() { mpt::PathString theFile = theApp.GetAppDirPath(); // Only run the tests when we're in the project directory structure. std::size_t pathComponents = mpt::String::Split(theFile.ToUnicode(), MPT_USTRING("\\")).size() - 1; for(std::size_t i = 0; i < pathComponents; ++i) { if(theFile.IsDirectory() && (theFile + MPT_PATHSTRING("test")).IsDirectory()) { if((theFile + MPT_PATHSTRING("test\\test.mptm")).IsFile()) { return true; } } theFile += MPT_PATHSTRING("..\\"); } return false; } static mpt::PathString GetTestFilenameBase() { mpt::PathString theFile = theApp.GetAppDirPath(); std::size_t pathComponents = mpt::String::Split(theFile.ToUnicode(), MPT_USTRING("\\")).size() - 1; for(std::size_t i = 0; i < pathComponents; ++i) { if(theFile.IsDirectory() && (theFile + MPT_PATHSTRING("test")).IsDirectory()) { if((theFile + MPT_PATHSTRING("test\\test.mptm")).IsFile()) { break; } } theFile += MPT_PATHSTRING("..\\"); } theFile += MPT_PATHSTRING("test/test."); return theFile; } static mpt::PathString GetTempFilenameBase() { return GetTestFilenameBase(); } typedef CModDoc *TSoundFileContainer; static CSoundFile &GetrSoundFile(TSoundFileContainer &sndFile) { return sndFile->GetrSoundFile(); } static TSoundFileContainer CreateSoundFileContainer(const mpt::PathString &filename) { CModDoc *pModDoc = (CModDoc *)theApp.OpenDocumentFile(filename, FALSE); return pModDoc; } static void DestroySoundFileContainer(TSoundFileContainer &sndFile) { sndFile->OnCloseDocument(); } static void SaveIT(const TSoundFileContainer &sndFile, const mpt::PathString &filename) { sndFile->DoSave(filename); // Saving the file puts it in the MRU list... theApp.RemoveMruItem(0); } static void SaveXM(const TSoundFileContainer &sndFile, const mpt::PathString &filename) { sndFile->DoSave(filename); // Saving the file puts it in the MRU list... theApp.RemoveMruItem(0); } static void SaveS3M(const TSoundFileContainer &sndFile, const mpt::PathString &filename) { sndFile->DoSave(filename); // Saving the file puts it in the MRU list... theApp.RemoveMruItem(0); } #else static bool ShouldRunTests() { return true; } static mpt::PathString GetTestFilenameBase() { return Test::GetPathPrefix() + MPT_PATHSTRING("./test/test."); } static mpt::PathString GetTempFilenameBase() { return MPT_PATHSTRING("./test."); } typedef std::shared_ptr TSoundFileContainer; static CSoundFile &GetrSoundFile(TSoundFileContainer &sndFile) { return *sndFile.get(); } static TSoundFileContainer CreateSoundFileContainer(const mpt::PathString &filename) { mpt::ifstream stream(filename, std::ios::binary); FileReader file = make_FileReader(&stream); std::shared_ptr pSndFile = std::make_shared(); pSndFile->Create(file, CSoundFile::loadCompleteModule); return pSndFile; } static void DestroySoundFileContainer(TSoundFileContainer & /* sndFile */ ) { return; } #ifndef MODPLUG_NO_FILESAVE static void SaveIT(const TSoundFileContainer &sndFile, const mpt::PathString &filename) { sndFile->SaveIT(filename, false); } static void SaveXM(const TSoundFileContainer &sndFile, const mpt::PathString &filename) { sndFile->SaveXM(filename, false); } static void SaveS3M(const TSoundFileContainer &sndFile, const mpt::PathString &filename) { sndFile->SaveS3M(filename); } #endif #endif // Test file loading and saving static MPT_NOINLINE void TestLoadSaveFile() { if(!ShouldRunTests()) { return; } #ifdef MODPLUG_TRACKER bool saveMutedChannels = TrackerSettings::Instance().MiscSaveChannelMuteStatus; TrackerSettings::Instance().MiscSaveChannelMuteStatus = true; #endif mpt::PathString filenameBaseSrc = GetTestFilenameBase(); mpt::PathString filenameBase = GetTempFilenameBase(); // Test MPTM file loading { TSoundFileContainer sndFileContainer = CreateSoundFileContainer(filenameBaseSrc + MPT_PATHSTRING("mptm")); TestLoadMPTMFile(GetrSoundFile(sndFileContainer)); #ifndef MODPLUG_NO_FILESAVE // Test file saving GetrSoundFile(sndFileContainer).m_dwLastSavedWithVersion = MptVersion::num; SaveIT(sndFileContainer, filenameBase + MPT_PATHSTRING("saved.mptm")); #endif DestroySoundFileContainer(sndFileContainer); } // Reload the saved file and test if everything is still working correctly. #ifndef MODPLUG_NO_FILESAVE { TSoundFileContainer sndFileContainer = CreateSoundFileContainer(filenameBase + MPT_PATHSTRING("saved.mptm")); TestLoadMPTMFile(GetrSoundFile(sndFileContainer)); DestroySoundFileContainer(sndFileContainer); RemoveFile(filenameBase + MPT_PATHSTRING("saved.mptm")); } #endif // Test XM file loading { TSoundFileContainer sndFileContainer = CreateSoundFileContainer(filenameBaseSrc + MPT_PATHSTRING("xm")); TestLoadXMFile(GetrSoundFile(sndFileContainer)); // In OpenMPT 1.20 (up to revision 1459), there was a bug in the XM saver // that would create broken XMs if the sample map contained samples that // were only referenced below C-1 or above B-8 (such samples should not // be written). Let's insert a sample there and check if re-loading the // file still works. GetrSoundFile(sndFileContainer).m_nSamples++; GetrSoundFile(sndFileContainer).Instruments[1]->Keyboard[110] = GetrSoundFile(sndFileContainer).GetNumSamples(); #ifndef MODPLUG_NO_FILESAVE // Test file saving GetrSoundFile(sndFileContainer).m_dwLastSavedWithVersion = MptVersion::num; SaveXM(sndFileContainer, filenameBase + MPT_PATHSTRING("saved.xm")); #endif DestroySoundFileContainer(sndFileContainer); } // Reload the saved file and test if everything is still working correctly. #ifndef MODPLUG_NO_FILESAVE { TSoundFileContainer sndFileContainer = CreateSoundFileContainer(filenameBase + MPT_PATHSTRING("saved.xm")); TestLoadXMFile(GetrSoundFile(sndFileContainer)); DestroySoundFileContainer(sndFileContainer); RemoveFile(filenameBase + MPT_PATHSTRING("saved.xm")); } #endif // Test S3M file loading { TSoundFileContainer sndFileContainer = CreateSoundFileContainer(filenameBaseSrc + MPT_PATHSTRING("s3m")); TestLoadS3MFile(GetrSoundFile(sndFileContainer), false); // Test GetLength code, in particular with subsongs VERIFY_EQUAL_EPS(GetrSoundFile(sndFileContainer).GetLength(eAdjustSamplePositions, GetLengthTarget(3, 1)).back().duration, 19.237, 0.01); VERIFY_EQUAL_NONCONT(GetrSoundFile(sndFileContainer).GetLength(eAdjustSamplePositions, GetLengthTarget(2, 0).StartPos(0, 1, 0)).back().targetReached, false); auto allSubSongs = GetrSoundFile(sndFileContainer).GetLength(eNoAdjust, GetLengthTarget(true)); VERIFY_EQUAL_NONCONT(allSubSongs.size(), 3); double totalDuration = 0.0; for(const auto &subSong : allSubSongs) { totalDuration += subSong.duration; } VERIFY_EQUAL_EPS(totalDuration, 2505.53, 0.01); #ifndef MODPLUG_NO_FILESAVE // Test file saving GetrSoundFile(sndFileContainer).m_dwLastSavedWithVersion = MptVersion::num; SaveS3M(sndFileContainer, filenameBase + MPT_PATHSTRING("saved.s3m")); #endif DestroySoundFileContainer(sndFileContainer); } // Reload the saved file and test if everything is still working correctly. #ifndef MODPLUG_NO_FILESAVE { TSoundFileContainer sndFileContainer = CreateSoundFileContainer(filenameBase + MPT_PATHSTRING("saved.s3m")); TestLoadS3MFile(GetrSoundFile(sndFileContainer), true); DestroySoundFileContainer(sndFileContainer); RemoveFile(filenameBase + MPT_PATHSTRING("saved.s3m")); } #endif // General file I/O tests { mpt::ostringstream f; size_t bytesWritten; mpt::IO::WriteVarInt(f, uint16(0), &bytesWritten); VERIFY_EQUAL_NONCONT(bytesWritten, 1); mpt::IO::WriteVarInt(f, uint16(127), &bytesWritten); VERIFY_EQUAL_NONCONT(bytesWritten, 1); mpt::IO::WriteVarInt(f, uint16(128), &bytesWritten); VERIFY_EQUAL_NONCONT(bytesWritten, 2); mpt::IO::WriteVarInt(f, uint16(16383), &bytesWritten); VERIFY_EQUAL_NONCONT(bytesWritten, 2); mpt::IO::WriteVarInt(f, uint16(16384), &bytesWritten); VERIFY_EQUAL_NONCONT(bytesWritten, 3); mpt::IO::WriteVarInt(f, uint16(65535), &bytesWritten); VERIFY_EQUAL_NONCONT(bytesWritten, 3); mpt::IO::WriteVarInt(f, uint64(0xFFFFFFFFFFFFFFFFull), &bytesWritten); VERIFY_EQUAL_NONCONT(bytesWritten, 10); std::string data = f.str(); FileReader file(mpt::byte_cast(mpt::as_span(data))); uint64 v; file.ReadVarInt(v); VERIFY_EQUAL_NONCONT(v, 0); file.ReadVarInt(v); VERIFY_EQUAL_NONCONT(v, 127); file.ReadVarInt(v); VERIFY_EQUAL_NONCONT(v, 128); file.ReadVarInt(v); VERIFY_EQUAL_NONCONT(v, 16383); file.ReadVarInt(v); VERIFY_EQUAL_NONCONT(v, 16384); file.ReadVarInt(v); VERIFY_EQUAL_NONCONT(v, 65535); file.ReadVarInt(v); VERIFY_EQUAL_NONCONT(v, 0xFFFFFFFFFFFFFFFFull); } { // Verify that writing arrays does not confuse the compiler. // This is both, compile-time and run-time cheking. // Run-time in case some weird compiler gets confused by our templates // and only writes the first array element. mpt::ostringstream f; uint16be data[2]; data[0] = 0x1234; data[1] = 0x5678; mpt::IO::Write(f, data); VERIFY_EQUAL(f.str(), std::string("\x12\x34\x56\x78")); } #ifdef MODPLUG_TRACKER TrackerSettings::Instance().MiscSaveChannelMuteStatus = saveMutedChannels; #endif } // Test various editing features static MPT_NOINLINE void TestEditing() { #ifdef MODPLUG_TRACKER auto modDoc = static_cast(theApp.GetModDocTemplate()->CreateNewDocument()); auto &sndFile = modDoc->GetrSoundFile(); sndFile.Create(FileReader(), CSoundFile::loadCompleteModule, modDoc); sndFile.m_nChannels = 4; sndFile.ChangeModTypeTo(MOD_TYPE_MPT); // Rearrange channels sndFile.Patterns.ResizeArray(2); sndFile.Patterns.Insert(0, 32); sndFile.Patterns.Insert(1, 48); sndFile.Patterns[1].SetName("Pattern"); sndFile.Patterns[1].SetSignature(2, 4); TempoSwing swing; swing.resize(2); sndFile.Patterns[1].SetTempoSwing(swing); sndFile.Patterns[1].GetpModCommand(37, 0)->instr = 1; sndFile.Patterns[1].GetpModCommand(37, 1)->instr = 2; sndFile.Patterns[1].GetpModCommand(37, 2)->instr = 3; sndFile.Patterns[1].GetpModCommand(37, 3)->instr = 4; modDoc->ReArrangeChannels({ 3, 2, CHANNELINDEX_INVALID, 0 }); modDoc->ReArrangeChannels({ 0, 1, 1, CHANNELINDEX_INVALID, 3 }); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetName(), "Pattern"); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetRowsPerBeat(), 2); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetRowsPerMeasure(), 4); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetTempoSwing(), swing); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(37, 0)->instr, 4); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(37, 1)->instr, 3); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(37, 2)->instr, 3); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(37, 3)->instr, 0); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(37, 4)->instr, 1); // Rearrange samples sndFile.m_nSamples = 2; mpt::String::Copy(sndFile.GetSample(1).filename, "1"); mpt::String::Copy(sndFile.m_szNames[1], "1"); mpt::String::Copy(sndFile.GetSample(2).filename, "2"); mpt::String::Copy(sndFile.m_szNames[2], "2"); sndFile.GetSample(2).nLength = 16; sndFile.GetSample(2).AllocateSample(); modDoc->ReArrangeSamples({ 2, SAMPLEINDEX_INVALID, 1 }); VERIFY_EQUAL_NONCONT(sndFile.GetSample(1).pSample != nullptr, true); VERIFY_EQUAL_NONCONT(sndFile.GetSample(1).filename, std::string("2")); VERIFY_EQUAL_NONCONT(sndFile.m_szNames[1], std::string("2")); VERIFY_EQUAL_NONCONT(sndFile.GetSample(2).filename, std::string()); VERIFY_EQUAL_NONCONT(sndFile.m_szNames[2], std::string()); VERIFY_EQUAL_NONCONT(sndFile.GetSample(3).filename, std::string("1")); VERIFY_EQUAL_NONCONT(sndFile.m_szNames[3], std::string("1")); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(37, 4)->instr, 3); // Convert / rearrange instruments modDoc->ConvertSamplesToInstruments(); modDoc->ReArrangeInstruments({ INSTRUMENTINDEX_INVALID, 2, 1, 3 }); VERIFY_EQUAL_NONCONT(sndFile.Instruments[1]->name, std::string()); VERIFY_EQUAL_NONCONT(sndFile.Instruments[2]->name, std::string()); VERIFY_EQUAL_NONCONT(sndFile.Instruments[3]->name, std::string("2")); VERIFY_EQUAL_NONCONT(sndFile.Instruments[4]->name, std::string("1")); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(37, 4)->instr, 4); modDoc->ConvertInstrumentsToSamples(); VERIFY_EQUAL_NONCONT(sndFile.Patterns[1].GetpModCommand(37, 4)->instr, 3); modDoc->SetModified(); VERIFY_EQUAL_NONCONT(modDoc->IsModified(), true); VERIFY_EQUAL_NONCONT(modDoc->ModifiedSinceLastAutosave(), true); VERIFY_EQUAL_NONCONT(modDoc->ModifiedSinceLastAutosave(), false); sndFile.Destroy(); modDoc->OnCloseDocument(); #endif } static void RunITCompressionTest(const std::vector &sampleData, FlagSet smpFormat, bool it215) { ModSample smp; smp.uFlags = smpFormat; smp.pSample = const_cast(sampleData.data()); smp.nLength = mpt::saturate_cast(sampleData.size() / smp.GetBytesPerSample()); std::string data; { mpt::ostringstream f; ITCompression compression(smp, it215, &f); data = f.str(); } { FileReader file(mpt::byte_cast(mpt::as_span(data))); std::vector sampleDataNew(sampleData.size(), 0); smp.pSample = sampleDataNew.data(); ITDecompression decompression(file, smp, it215); VERIFY_EQUAL_NONCONT(memcmp(sampleData.data(), sampleDataNew.data(), sampleData.size()), 0); } } static MPT_NOINLINE void TestITCompression() { // Test loading / saving of IT-compressed samples const int sampleDataSize = 65536; std::vector sampleData(sampleDataSize, 0); std::srand(0); for(int i = 0; i < sampleDataSize; i++) { sampleData[i] = mpt::random(*s_PRNG); } // Run each compression test with IT215 compression and without. for(int i = 0; i < 2; i++) { RunITCompressionTest(sampleData, ChannelFlags(0), i == 0); RunITCompressionTest(sampleData, CHN_16BIT, i == 0); RunITCompressionTest(sampleData, CHN_STEREO, i == 0); RunITCompressionTest(sampleData, CHN_16BIT | CHN_STEREO, i == 0); } } #if 0 static bool RatioEqual(CTuningBase::RATIOTYPE a, CTuningBase::RATIOTYPE b) { if(a == CTuningBase::RATIOTYPE(0) && b == CTuningBase::RATIOTYPE(0)) { return true; } if(a == CTuningBase::RATIOTYPE(0) || b == CTuningBase::RATIOTYPE(0)) { return false; } return (std::fabs(CTuningBase::RATIOTYPE(1) - (a/b)) < CTuningBase::RATIOTYPE(0.0001)); } static void CheckEqualTuningCollections(const CTuningCollection &a, const CTuningCollection &b) { VERIFY_EQUAL(a.GetName(), b.GetName()); VERIFY_EQUAL(a.GetNumTunings(), b.GetNumTunings()); for(std::size_t tuning = 0; tuning < std::min(a.GetNumTunings(), b.GetNumTunings()); ++tuning) { VERIFY_EQUAL(a.GetTuning(tuning).GetName(), b.GetTuning(tuning).GetName()); VERIFY_EQUAL(a.GetTuning(tuning).GetType(), b.GetTuning(tuning).GetType()); VERIFY_EQUAL(a.GetTuning(tuning).GetGroupSize(), b.GetTuning(tuning).GetGroupSize()); VERIFY_EQUAL(a.GetTuning(tuning).GetFineStepCount(), b.GetTuning(tuning).GetFineStepCount()); VERIFY_EQUAL(RatioEqual(a.GetTuning(tuning).GetGroupRatio(), b.GetTuning(tuning).GetGroupRatio()), true); VERIFY_EQUAL(a.GetTuning(tuning).GetValidityRange(), b.GetTuning(tuning).GetValidityRange()); for(ModCommand::NOTE note = NOTE_MIN; note <= NOTE_MAX; ++note) { VERIFY_EQUAL(a.GetTuning(tuning).GetNoteName(note - NOTE_MIDDLEC), b.GetTuning(tuning).GetNoteName(note - NOTE_MIDDLEC)); VERIFY_EQUAL(RatioEqual(a.GetTuning(tuning).GetRatio(note - NOTE_MIDDLEC), b.GetTuning(tuning).GetRatio(note - NOTE_MIDDLEC)), true); } } } #endif static MPT_NOINLINE void TestTunings() { // nothing for now } static double Rand01() { return mpt::random(*s_PRNG, 0.0, 1.0); } template T Rand(const T min, const T max) { return Util::Round(min + Rand01() * (max - min)); } static void GenerateCommands(CPattern& pat, const double dProbPcs, const double dProbPc) { const double dPcxProb = dProbPcs + dProbPc; for(auto &m : pat) { const double rand = Rand01(); if(rand < dPcxProb) { if(rand < dProbPcs) m.note = NOTE_PCS; else m.note = NOTE_PC; m.instr = Rand(0, MAX_MIXPLUGINS); m.SetValueVolCol(Rand(0, ModCommand::maxColumnValue)); m.SetValueEffectCol(Rand(0, ModCommand::maxColumnValue)); } else m.Clear(); } } // Test PC note serialization static MPT_NOINLINE void TestPCnoteSerialization() { FileReader file; std::unique_ptr pSndFile = mpt::make_unique(); CSoundFile &sndFile = *pSndFile.get(); sndFile.m_nType = MOD_TYPE_MPT; sndFile.Patterns.DestroyPatterns(); sndFile.m_nChannels = ModSpecs::mptm.channelsMax; sndFile.Patterns.Insert(0, ModSpecs::mptm.patternRowsMin); sndFile.Patterns.Insert(1, 64); GenerateCommands(sndFile.Patterns[1], 0.3, 0.3); sndFile.Patterns.Insert(2, ModSpecs::mptm.patternRowsMax); GenerateCommands(sndFile.Patterns[2], 0.5, 0.5); // Copy pattern data for comparison. CPatternContainer patterns{ sndFile.Patterns }; mpt::stringstream mem; WriteModPatterns(mem, sndFile.Patterns); VERIFY_EQUAL_NONCONT( mem.good(), true ); // Clear patterns. sndFile.Patterns[0].ClearCommands(); sndFile.Patterns[1].ClearCommands(); sndFile.Patterns[2].ClearCommands(); // Read data back. ReadModPatterns(mem, sndFile.Patterns); // Compare. VERIFY_EQUAL_NONCONT( sndFile.Patterns[0].GetNumRows(), ModSpecs::mptm.patternRowsMin); VERIFY_EQUAL_NONCONT( sndFile.Patterns[1].GetNumRows(), 64); VERIFY_EQUAL_NONCONT( sndFile.Patterns[2].GetNumRows(), ModSpecs::mptm.patternRowsMax); for(int i = 0; i < 3; i++) { VERIFY_EQUAL(sndFile.Patterns[i], patterns[i]); } } // Test String I/O functionality static MPT_NOINLINE void TestStringIO() { char src0[4] = { '\0', 'X', ' ', 'X' }; // Weird empty buffer char src1[4] = { 'X', ' ', '\0', 'X' }; // Weird buffer (hello Impulse Tracker) char src2[4] = { 'X', 'Y', 'Z', ' ' }; // Full buffer, last character space char src3[4] = { 'X', 'Y', 'Z', '!' }; // Full buffer, last character non-space char src4[4] = { 'x', 'y', '\t', '\n' }; // Full buffer containing non-space whitespace char dst1[6]; // Destination buffer, larger than source buffer char dst2[3]; // Destination buffer, smaller than source buffer #define ReadTest(mode, dst, src, expectedResult) \ mpt::String::Read(dst, src); \ VERIFY_EQUAL_NONCONT(strncmp(dst, expectedResult, CountOf(dst)), 0); /* Ensure that the strings are identical */ \ for(size_t i = strlen(dst); i < CountOf(dst); i++) \ VERIFY_EQUAL_NONCONT(dst[i], '\0'); /* Ensure that rest of the buffer is completely nulled */ #define WriteTest(mode, dst, src, expectedResult) \ mpt::String::Write(dst, src); \ VERIFY_EQUAL_NONCONT(strncmp(dst, expectedResult, CountOf(dst)), 0); /* Ensure that the strings are identical */ \ for(size_t i = mpt::strnlen(dst, CountOf(dst)); i < CountOf(dst); i++) \ VERIFY_EQUAL_NONCONT(dst[i], '\0'); /* Ensure that rest of the buffer is completely nulled */ // Check reading of null-terminated string into larger buffer ReadTest(nullTerminated, dst1, src0, ""); ReadTest(nullTerminated, dst1, src1, "X "); ReadTest(nullTerminated, dst1, src2, "XYZ"); ReadTest(nullTerminated, dst1, src3, "XYZ"); ReadTest(nullTerminated, dst1, src4, "xy\t"); // Check reading of string that should be null-terminated, but is maybe too long to still hold the null character. ReadTest(maybeNullTerminated, dst1, src0, ""); ReadTest(maybeNullTerminated, dst1, src1, "X "); ReadTest(maybeNullTerminated, dst1, src2, "XYZ "); ReadTest(maybeNullTerminated, dst1, src3, "XYZ!"); ReadTest(maybeNullTerminated, dst1, src4, "xy\t\n"); // Check reading of space-padded strings with ignored last character ReadTest(spacePaddedNull, dst1, src0, " X"); ReadTest(spacePaddedNull, dst1, src1, "X"); ReadTest(spacePaddedNull, dst1, src2, "XYZ"); ReadTest(spacePaddedNull, dst1, src3, "XYZ"); ReadTest(spacePaddedNull, dst1, src4, "xy\t"); // Check reading of space-padded strings ReadTest(spacePadded, dst1, src0, " X X"); ReadTest(spacePadded, dst1, src1, "X X"); ReadTest(spacePadded, dst1, src2, "XYZ"); ReadTest(spacePadded, dst1, src3, "XYZ!"); ReadTest(spacePadded, dst1, src4, "xy\t\n"); /////////////////////////////// // Check reading of null-terminated string into smaller buffer ReadTest(nullTerminated, dst2, src0, ""); ReadTest(nullTerminated, dst2, src1, "X "); ReadTest(nullTerminated, dst2, src2, "XY"); ReadTest(nullTerminated, dst2, src3, "XY"); ReadTest(nullTerminated, dst2, src4, "xy"); // Check reading of string that should be null-terminated, but is maybe too long to still hold the null character. ReadTest(maybeNullTerminated, dst2, src0, ""); ReadTest(maybeNullTerminated, dst2, src1, "X "); ReadTest(maybeNullTerminated, dst2, src2, "XY"); ReadTest(maybeNullTerminated, dst2, src3, "XY"); ReadTest(maybeNullTerminated, dst2, src4, "xy"); // Check reading of space-padded strings with ignored last character ReadTest(spacePaddedNull, dst2, src0, " X"); ReadTest(spacePaddedNull, dst2, src1, "X"); ReadTest(spacePaddedNull, dst2, src2, "XY"); ReadTest(spacePaddedNull, dst2, src3, "XY"); ReadTest(spacePaddedNull, dst2, src4, "xy"); // Check reading of space-padded strings ReadTest(spacePadded, dst2, src0, " X"); ReadTest(spacePadded, dst2, src1, "X"); ReadTest(spacePadded, dst2, src2, "XY"); ReadTest(spacePadded, dst2, src3, "XY"); ReadTest(spacePadded, dst2, src4, "xy"); /////////////////////////////// // Check writing of null-terminated string into larger buffer WriteTest(nullTerminated, dst1, src0, ""); WriteTest(nullTerminated, dst1, src1, "X "); WriteTest(nullTerminated, dst1, src2, "XYZ "); WriteTest(nullTerminated, dst1, src3, "XYZ!"); // Check writing of string that should be null-terminated, but is maybe too long to still hold the null character. WriteTest(maybeNullTerminated, dst1, src0, ""); WriteTest(maybeNullTerminated, dst1, src1, "X "); WriteTest(maybeNullTerminated, dst1, src2, "XYZ "); WriteTest(maybeNullTerminated, dst1, src3, "XYZ!"); // Check writing of space-padded strings with last character set to null WriteTest(spacePaddedNull, dst1, src0, " "); WriteTest(spacePaddedNull, dst1, src1, "X "); WriteTest(spacePaddedNull, dst1, src2, "XYZ "); WriteTest(spacePaddedNull, dst1, src3, "XYZ! "); // Check writing of space-padded strings WriteTest(spacePadded, dst1, src0, " "); WriteTest(spacePadded, dst1, src1, "X "); WriteTest(spacePadded, dst1, src2, "XYZ "); WriteTest(spacePadded, dst1, src3, "XYZ! "); /////////////////////////////// // Check writing of null-terminated string into smaller buffer WriteTest(nullTerminated, dst2, src0, ""); WriteTest(nullTerminated, dst2, src1, "X "); WriteTest(nullTerminated, dst2, src2, "XY"); WriteTest(nullTerminated, dst2, src3, "XY"); // Check writing of string that should be null-terminated, but is maybe too long to still hold the null character. WriteTest(maybeNullTerminated, dst2, src0, ""); WriteTest(maybeNullTerminated, dst2, src1, "X "); WriteTest(maybeNullTerminated, dst2, src2, "XYZ"); WriteTest(maybeNullTerminated, dst2, src3, "XYZ"); // Check writing of space-padded strings with last character set to null WriteTest(spacePaddedNull, dst2, src0, " "); WriteTest(spacePaddedNull, dst2, src1, "X "); WriteTest(spacePaddedNull, dst2, src2, "XY"); WriteTest(spacePaddedNull, dst2, src3, "XY"); // Check writing of space-padded strings WriteTest(spacePadded, dst2, src0, " "); WriteTest(spacePadded, dst2, src1, "X "); WriteTest(spacePadded, dst2, src2, "XYZ"); WriteTest(spacePadded, dst2, src3, "XYZ"); #undef ReadTest #undef WriteTest { std::string dststring; std::string src0string = std::string(src0, CountOf(src0)); std::string src1string = std::string(src1, CountOf(src1)); std::string src2string = std::string(src2, CountOf(src2)); std::string src3string = std::string(src3, CountOf(src3)); #define ReadTest(mode, dst, src, expectedResult) \ mpt::String::Read(dst, src); \ VERIFY_EQUAL_NONCONT(dst, expectedResult); /* Ensure that the strings are identical */ \ #define WriteTest(mode, dst, src, expectedResult) \ mpt::String::Write(dst, src); \ VERIFY_EQUAL_NONCONT(strncmp(dst, expectedResult, CountOf(dst)), 0); /* Ensure that the strings are identical */ \ for(size_t i = mpt::strnlen(dst, CountOf(dst)); i < CountOf(dst); i++) \ VERIFY_EQUAL_NONCONT(dst[i], '\0'); /* Ensure that rest of the buffer is completely nulled */ // Check reading of null-terminated string into std::string ReadTest(nullTerminated, dststring, src0, ""); ReadTest(nullTerminated, dststring, src1, "X "); ReadTest(nullTerminated, dststring, src2, "XYZ"); ReadTest(nullTerminated, dststring, src3, "XYZ"); ReadTest(nullTerminated, dststring, src4, "xy\t"); // Check reading of string that should be null-terminated, but is maybe too long to still hold the null character. ReadTest(maybeNullTerminated, dststring, src0, ""); ReadTest(maybeNullTerminated, dststring, src1, "X "); ReadTest(maybeNullTerminated, dststring, src2, "XYZ "); ReadTest(maybeNullTerminated, dststring, src3, "XYZ!"); ReadTest(maybeNullTerminated, dststring, src4, "xy\t\n"); // Check reading of space-padded strings with ignored last character ReadTest(spacePaddedNull, dststring, src0, " X"); ReadTest(spacePaddedNull, dststring, src1, "X"); ReadTest(spacePaddedNull, dststring, src2, "XYZ"); ReadTest(spacePaddedNull, dststring, src3, "XYZ"); ReadTest(spacePaddedNull, dststring, src4, "xy\t"); // Check reading of space-padded strings ReadTest(spacePadded, dststring, src0, " X X"); ReadTest(spacePadded, dststring, src1, "X X"); ReadTest(spacePadded, dststring, src2, "XYZ"); ReadTest(spacePadded, dststring, src3, "XYZ!"); ReadTest(spacePadded, dststring, src4, "xy\t\n"); /////////////////////////////// // Check writing of null-terminated string into larger buffer WriteTest(nullTerminated, dst1, src0string, ""); WriteTest(nullTerminated, dst1, src1string, "X "); WriteTest(nullTerminated, dst1, src2string, "XYZ "); WriteTest(nullTerminated, dst1, src3string, "XYZ!"); // Check writing of string that should be null-terminated, but is maybe too long to still hold the null character. WriteTest(maybeNullTerminated, dst1, src0string, ""); WriteTest(maybeNullTerminated, dst1, src1string, "X "); WriteTest(maybeNullTerminated, dst1, src2string, "XYZ "); WriteTest(maybeNullTerminated, dst1, src3string, "XYZ!"); // Check writing of space-padded strings with last character set to null WriteTest(spacePaddedNull, dst1, src0string, " "); WriteTest(spacePaddedNull, dst1, src1string, "X "); WriteTest(spacePaddedNull, dst1, src2string, "XYZ "); WriteTest(spacePaddedNull, dst1, src3string, "XYZ! "); // Check writing of space-padded strings WriteTest(spacePadded, dst1, src0string, " "); WriteTest(spacePadded, dst1, src1string, "X "); WriteTest(spacePadded, dst1, src2string, "XYZ "); WriteTest(spacePadded, dst1, src3string, "XYZ! "); /////////////////////////////// // Check writing of null-terminated string into smaller buffer WriteTest(nullTerminated, dst2, src0string, ""); WriteTest(nullTerminated, dst2, src1string, "X "); WriteTest(nullTerminated, dst2, src2string, "XY"); WriteTest(nullTerminated, dst2, src3string, "XY"); // Check writing of string that should be null-terminated, but is maybe too long to still hold the null character. WriteTest(maybeNullTerminated, dst2, src0string, ""); WriteTest(maybeNullTerminated, dst2, src1string, "X "); WriteTest(maybeNullTerminated, dst2, src2string, "XYZ"); WriteTest(maybeNullTerminated, dst2, src3string, "XYZ"); // Check writing of space-padded strings with last character set to null WriteTest(spacePaddedNull, dst2, src0string, " "); WriteTest(spacePaddedNull, dst2, src1string, "X "); WriteTest(spacePaddedNull, dst2, src2string, "XY"); WriteTest(spacePaddedNull, dst2, src3string, "XY"); // Check writing of space-padded strings WriteTest(spacePadded, dst2, src0string, " "); WriteTest(spacePadded, dst2, src1string, "X "); WriteTest(spacePadded, dst2, src2string, "XYZ"); WriteTest(spacePadded, dst2, src3string, "XYZ"); /////////////////////////////// #undef ReadTest #undef WriteTest } // Test FixNullString() mpt::String::FixNullString(src1); mpt::String::FixNullString(src2); mpt::String::FixNullString(src3); VERIFY_EQUAL_NONCONT(strncmp(src1, "X ", CountOf(src1)), 0); VERIFY_EQUAL_NONCONT(strncmp(src2, "XYZ", CountOf(src2)), 0); VERIFY_EQUAL_NONCONT(strncmp(src3, "XYZ", CountOf(src3)), 0); } static MPT_NOINLINE void TestSampleConversion() { std::vector sourceBufContainer(65536 * 4); std::vector targetBufContainer(65536 * 6); uint8 *sourceBuf = &(sourceBufContainer[0]); void *targetBuf = &(targetBufContainer[0]); // Signed 8-Bit Integer PCM // Unsigned 8-Bit Integer PCM // Delta 8-Bit Integer PCM { uint8 *source8 = sourceBuf; for(size_t i = 0; i < 256; i++) { source8[i] = static_cast(i); } int8 *signed8 = static_cast(targetBuf); uint8 *unsigned8 = static_cast(targetBuf) + 256; int8 *delta8 = static_cast(targetBuf) + 512; int8 delta = 0; CopySample(signed8, 256, 1, mpt::byte_cast(source8), 256, 1); CopySample(reinterpret_cast(unsigned8), 256, 1, mpt::byte_cast(source8), 256, 1); CopySample(delta8, 256, 1, mpt::byte_cast(source8), 256, 1); for(size_t i = 0; i < 256; i++) { delta += static_cast(i); VERIFY_EQUAL_QUIET_NONCONT(signed8[i], static_cast(i)); VERIFY_EQUAL_QUIET_NONCONT(unsigned8[i], static_cast(i + 0x80u)); VERIFY_EQUAL_QUIET_NONCONT(delta8[i], static_cast(delta)); } } // Signed 16-Bit Integer PCM // Unsigned 16-Bit Integer PCM // Delta 16-Bit Integer PCM { // Little Endian uint8 *source16 = sourceBuf; for(size_t i = 0; i < 65536; i++) { source16[i * 2 + 0] = static_cast(i & 0xFF); source16[i * 2 + 1] = static_cast(i >> 8); } int16 *signed16 = static_cast(targetBuf); uint16 *unsigned16 = static_cast(targetBuf) + 65536; int16 *delta16 = static_cast(targetBuf) + 65536 * 2; int16 delta = 0; CopySample >(signed16, 65536, 1, mpt::byte_cast(source16), 65536 * 2, 1); CopySample >(reinterpret_cast(unsigned16), 65536, 1, mpt::byte_cast(source16), 65536 * 2, 1); CopySample >(delta16, 65536, 1, mpt::byte_cast(source16), 65536 * 2, 1); for(size_t i = 0; i < 65536; i++) { delta += static_cast(i); VERIFY_EQUAL_QUIET_NONCONT(signed16[i], static_cast(i)); VERIFY_EQUAL_QUIET_NONCONT(unsigned16[i], static_cast(i + 0x8000u)); VERIFY_EQUAL_QUIET_NONCONT(delta16[i], static_cast(delta)); } // Big Endian for(size_t i = 0; i < 65536; i++) { source16[i * 2 + 0] = static_cast(i >> 8); source16[i * 2 + 1] = static_cast(i & 0xFF); } CopySample >(signed16, 65536, 1, mpt::byte_cast(source16), 65536 * 2, 1); CopySample >(reinterpret_cast(unsigned16), 65536, 1, mpt::byte_cast(source16), 65536 * 2, 1); CopySample >(delta16, 65536, 1, mpt::byte_cast(source16), 65536 * 2, 1); delta = 0; for(size_t i = 0; i < 65536; i++) { delta += static_cast(i); VERIFY_EQUAL_QUIET_NONCONT(signed16[i], static_cast(i)); VERIFY_EQUAL_QUIET_NONCONT(unsigned16[i], static_cast(i + 0x8000u)); VERIFY_EQUAL_QUIET_NONCONT(delta16[i], static_cast(delta)); } } // Signed 24-Bit Integer PCM { uint8 *source24 = sourceBuf; for(size_t i = 0; i < 65536; i++) { source24[i * 3 + 0] = 0; source24[i * 3 + 1] = static_cast(i & 0xFF); source24[i * 3 + 2] = static_cast(i >> 8); } int16 *truncated16 = static_cast(targetBuf); ModSample sample; sample.Initialize(); sample.nLength = 65536; sample.uFlags.set(CHN_16BIT); sample.pSample = (static_cast(targetBuf) + 65536); CopyAndNormalizeSample, SC::DecodeInt24<0, littleEndian24> > >(sample, mpt::byte_cast(source24), 3*65536); CopySample, SC::DecodeInt24<0, littleEndian24> > >(truncated16, 65536, 1, mpt::byte_cast(source24), 65536 * 3, 1); for(size_t i = 0; i < 65536; i++) { VERIFY_EQUAL_QUIET_NONCONT(sample.pSample16[i], static_cast(i)); VERIFY_EQUAL_QUIET_NONCONT(truncated16[i], static_cast(i)); } } // Float 32-Bit { uint8 *source32 = sourceBuf; for(size_t i = 0; i < 65536; i++) { IEEE754binary32BE floatbits = IEEE754binary32BE((static_cast(i) / 65536.0f) - 0.5f); source32[i * 4 + 0] = floatbits.GetByte(0); source32[i * 4 + 1] = floatbits.GetByte(1); source32[i * 4 + 2] = floatbits.GetByte(2); source32[i * 4 + 3] = floatbits.GetByte(3); } int16 *truncated16 = static_cast(targetBuf); ModSample sample; sample.Initialize(); sample.nLength = 65536; sample.uFlags.set(CHN_16BIT); sample.pSample = static_cast(targetBuf) + 65536; CopyAndNormalizeSample, SC::DecodeFloat32 > >(sample, mpt::byte_cast(source32), 4*65536); CopySample, SC::DecodeFloat32 > >(truncated16, 65536, 1, mpt::byte_cast(source32), 65536 * 4, 1); for(size_t i = 0; i < 65536; i++) { VERIFY_EQUAL_QUIET_NONCONT(sample.pSample16[i], static_cast(i - 0x8000u)); if(mpt::abs(truncated16[i] - static_cast((i - 0x8000u) / 2)) > 1) { VERIFY_EQUAL_QUIET_NONCONT(true, false); } } } // Range checks { int8 oneSample = 1; char *signed8 = reinterpret_cast(targetBuf); memset(signed8, 0, 4); CopySample(reinterpret_cast(targetBuf), 4, 1, reinterpret_cast(&oneSample), sizeof(oneSample), 1); VERIFY_EQUAL_NONCONT(signed8[0], 1); VERIFY_EQUAL_NONCONT(signed8[1], 0); VERIFY_EQUAL_NONCONT(signed8[2], 0); VERIFY_EQUAL_NONCONT(signed8[3], 0); } } } // namespace Test OPENMPT_NAMESPACE_END #else //Case: ENABLE_TESTS is not defined. OPENMPT_NAMESPACE_BEGIN namespace Test { void DoTests() { return; } } // namespace Test OPENMPT_NAMESPACE_END #endif libopenmpt-0.3.6+release.autotools/test/TestTools.h0000644000372100037210000000071412606446007017355 00000000000000/* * TestTools.h * ----------- * Purpose: Unit test framework. * Notes : * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "TestToolsTracker.h" #include "TestToolsLib.h" #include "../common/mptPathString.h" OPENMPT_NAMESPACE_BEGIN #ifdef ENABLE_TESTS namespace Test { mpt::PathString GetPathPrefix(); } // namespace Test OPENMPT_NAMESPACE_END #endif libopenmpt-0.3.6+release.autotools/test/test.mptm0000644000372100037210000002723312646317436017136 00000000000000IMPMTest Module_____________X ‘ˆý@‹€d%ˆd @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@þþ‰³ Ý"-#}#Í#$k$Î>©FÎ>ð©DÎ>IªÚÎ>“«mÎ>ª«##?ó†g+?›~i@nÙfAã1#SB–ëZE£ økFpn¹F펡¿FÄÙÐF°e* 0HãþFFFC9c n v9c n 0Cc pF0F001zF0F003zAcnzF0F00100F0F00108F0F00110F0F00118F0F00120F0F00128F0F00130F0F00138F0F00140F0F00148F0F00150F0F00158F0F00160F0F00168F0F00170F0F00178F0F00200F0F00208F0F00210F0F00218F0F00220F0F00228F0F00230F0F00238F0F00240F0F00248F0F00250F0F00258F0F00260F0F00268F0F00270F0F00278PNAM@First PatternSecond PatternCNAMxFirst ChannelSecond ChannelLast Channel______XFX00°OMXD,“>ï First PluginEcho??¦>¦>DWRT¸…>PROGÿÿÿÿCHFXOpenMPT Module Loader Test Suite Version 10 by Saga Musix Version History --------------- Version 9 Tempo Swing Version 9 Fixed point tempo Version 8 Added song artist and global resampling mode Version 7 Added sample cues Version 6 Added external sample Version 5 Added pitch wheel depth to instrument settings Version 4 Increased number of channels to test ChnS extension, duplicated instrument to check extended instrument property decoding Version 3 Added Stereo / 16-Bit and empty sample, poly aftertouch macro Version 2 Changed PC note, added normal pattern command Version 1 initial test suiteIMPI B@0First Instrument²ä@      !"#$%&'()*+,-./0123456789:;Hc=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvw @:-` ÷ ÷.24ù: BI÷PY ^÷e lõr wò ˆóŽ `àÀIMPI B@0Second Instrument²ä@      !"#$%&'()*+,-./0123456789:;Hc=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvw @:-` ÷ ÷.24ù: BI÷PY ^÷e lõr wò ˆóŽ `àÀIMPS¹ ¨)#š$IMPS@@Stereo / 16-Bit €>¥$IMPS@@Empty « ½$IMPSExternal¹Overridden Name€@*7u'*7½$*%FF' ‚H-dÿ %¤+ €áh ÿl€ .\test.flacXTPM..RV°°.PiM..CM..PM@@..BM...P@@..OF...R..SC ..SR<<..MFNREPÿÿNREAÿÿNREVLTTP‚‚PTTFÐÐHEVPHOVPDWPM..EPLL.[PPà .24:BIPY^elrwˆŽš¥¦ª¯¶¹¼½ÃÇÌÏÔÙßæëïùú '+.2>DJNXakqx„‰Œ”•¡¨« .24:BIPY^elrwˆŽš¥¦ª¯¶¹¼½ÃÇÌÏÔÙßæëïùú '+.2>DJNXakqx„‰Œ”•¡¨«.[EPð 8 9&%=@%6,0!-*)+),,2!.!',0"$(.#/-$!,#!,*'".*+($ 8 9&%=@%6,0!-*)+),,2!.!',0"$(.#/-$!,#!,*'".*+($STPMDTFRç.BPR.MPR ...CFSnhC @ @ @ @ @@..MT.MMP.VWCVWSL&.APSVTSV*..PRRSMPCUES& (08@ CUES& (08@CUES&  (08@2SWNGýÿ¿@À@À@.FSMÿÿÿÿÿAUTHTesterAMIM!h228mptm˜ ë228mptPc˜ 228mptP˜ÿ eäÿpgmäÿ¾Ï¿@datalRPB.…RPM.•SWNG¥X228mptP˜+ücÈdatal˜p}í!num 228mptSeqC˜Ï228mptSeq˜çìFirst SequenceþÿþÿntHl¼aÄrÜ228mptSeq˜ëüSecond SequencentLlÀaÈrànxc|€%¥) mptPclemptSeqCш,libopenmpt-0.3.6+release.autotools/test/TestToolsLib.cpp0000644000372100037210000000776213161656666020364 00000000000000/* * TestToolsLib.cpp * ---------------- * Purpose: Unit test framework for libopenmpt. * Notes : Currently somewhat unreadable :/ * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "TestToolsLib.h" #ifdef ENABLE_TESTS #ifndef MODPLUG_TRACKER #include #include #include OPENMPT_NAMESPACE_BEGIN namespace Test { int fail_count = 0; static std::string remove_newlines(std::string str) { return mpt::String::Replace(mpt::String::Replace(str, "\n", " "), "\r", " "); } Context::Context(const char * file, int line) : file(file) , line(line) { return; } Context::Context(const Context &c) : file(c.file) , line(c.line) { return; } Testcase::Testcase(Fatality fatality, Verbosity verbosity, const char * const desc, const Context &context) : fatality(fatality) , verbosity(verbosity) , desc(desc) , context(context) { return; } std::string Testcase::AsString() const { return mpt::format(std::string("%1(%2): %3"))(context.file, context.line, remove_newlines(desc)); } void Testcase::ShowStart() const { switch(verbosity) { case VerbosityQuiet: break; case VerbosityNormal: std::cout << "TEST..: " << AsString() << ": " << std::endl; break; case VerbosityVerbose: std::cout << "TEST..: " << AsString() << ": " << std::endl; break; } } void Testcase::ShowProgress(const char * text) const { switch(verbosity) { case VerbosityQuiet: break; case VerbosityNormal: break; case VerbosityVerbose: std::cout << "TEST..: " << AsString() << ": " << text << std::endl; break; } } void Testcase::ShowPass() const { switch(verbosity) { case VerbosityQuiet: break; case VerbosityNormal: std::cout << "RESULT: PASS" << std::endl; break; case VerbosityVerbose: std::cout << "PASS..: " << AsString() << std::endl; break; } } void Testcase::ShowFail(bool exception, const char * const text) const { switch(verbosity) { case VerbosityQuiet: break; case VerbosityNormal: std::cout << "RESULT: FAIL" << std::endl; break; case VerbosityVerbose: std::cout << "FAIL..: " << AsString() << std::endl; break; } std::cout.flush(); if(!exception) { if(!text || (text && std::string(text).empty())) { std::cerr << "FAIL: " << AsString() << std::endl; } else { std::cerr << "FAIL: " << AsString() << " : " << text << std::endl; } } else { if(!text || (text && std::string(text).empty())) { std::cerr << "FAIL: " << AsString() << " EXCEPTION!" << std::endl; } else { std::cerr << "FAIL: " << AsString() << " EXCEPTION: " << text << std::endl; } } std::cerr.flush(); } void Testcase::ReportPassed() { ShowPass(); } void Testcase::ReportFailed() { fail_count++; ReportException(); } void Testcase::ReportException() { try { throw; // get the exception } catch(TestFailed & e) { ShowFail(false, e.values.c_str()); if(fatality == FatalityStop) { throw; // rethrow } } catch(std::exception & e) { ShowFail(true, e.what()); throw; // rethrow } catch(...) { ShowFail(true); throw; // rethrow } } } // namespace Test #if defined(MPT_ASSERT_HANDLER_NEEDED) MPT_NOINLINE void AssertHandler(const char *file, int line, const char *function, const char *expr, const char *msg) { Test::fail_count++; if(msg) { mpt::log::Logger().SendLogMessage(mpt::log::Context(file, line, function), LogError, "ASSERT", MPT_USTRING("ASSERTION FAILED: ") + mpt::ToUnicode(mpt::CharsetASCII, msg) + MPT_USTRING(" (") + mpt::ToUnicode(mpt::CharsetASCII, expr) + MPT_USTRING(")") ); } else { mpt::log::Logger().SendLogMessage(mpt::log::Context(file, line, function), LogError, "ASSERT", MPT_USTRING("ASSERTION FAILED: ") + mpt::ToUnicode(mpt::CharsetASCII, expr) ); } #if defined(MPT_BUILD_FATAL_ASSERTS) std::abort(); #endif // MPT_BUILD_FATAL_ASSERTS } #endif // MPT_ASSERT_HANDLER_NEEDED OPENMPT_NAMESPACE_END #endif // !MODPLUG_TRACKER #endif // ENABLE_TESTS libopenmpt-0.3.6+release.autotools/test/test.xm0000644000372100037210000001424412110562762016571 00000000000000Extended Module: Test Module OpenMPT 1.21.01.15 ‹ @ Wœ¯€€€€€€€€€€€€€€€€€€€„À€„Á€„€„À„Ä€„Å€„Æ€„Ç€„È€„É€„Ê€„Ë€„Ì€„Í€„΀„Ï€€€€€€€€€€€€=-eÿ @(@-:` 8 9&%=@.2%46  ? # Pulse Sample Empty Sample @€Unassigned Sample îtextÔOpenMPT Module Loader Test Suite Version 1 by Saga Musix Version History --------------- Version 3 Added pitch wheel depth to instrument settings Version 2 Added unassigned sample Version 1 initial test suiteMIDI FFFC9c n v9c n 0Cc pF0F001zF0F003zF0F00100F0F00108F0F00110F0F00118F0F00120F0F00128F0F00130F0F00138F0F00140F0F00148F0F00150F0F00158F0F00160F0F00168F0F00170F0F00178F0F00200F0F00208F0F00210F0F00218F0F00220F0F00228F0F00230F0F00238F0F00240F0F00248F0F00250F0F00258F0F00260F0F00268F0F00270F0F00278PNAM@First PatternSecond PatternCNAM(First ChannelSecond ChannelFX00°OMXD,“>ï First PluginEcho??¦>¦>DWRT¸…>PROGÿÿÿÿCHFXXTPM..RV°.PiM..CM..PM@..BM...P€..VG@..OF...R..SC..SR..MFÿNREPÿNREAÿNREVÿLTTPHEVPHOVPSTPM..TD‹.BPR.MPR ...C..MT.MMP.VWCVWSL!.APSVTSV*.VGD€..PR.FSMAMIM!hlibopenmpt-0.3.6+release.autotools/test/TestToolsTracker.h0000644000372100037210000000274512710104013020657 00000000000000/* * TestToolsTracker.h * ------------------ * Purpose: Unit test framework for OpenMPT. * Notes : Really basic functionality that relies on a debugger that catches * exceptions and breaks right at the spot where it gets thrown. * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #ifdef ENABLE_TESTS #ifdef MODPLUG_TRACKER OPENMPT_NAMESPACE_BEGIN namespace Test { #if MPT_COMPILER_MSVC // With MSVC, break directly using __debugbreak intrinsic instead of calling DebugBreak which breaks one stackframe deeper than we want #define MyDebugBreak() __debugbreak() #else #define MyDebugBreak() DebugBreak() #endif // Verify that given parameters are 'equal'. Break directly into the debugger if not. // The exact meaning of equality is based on operator!= . #define VERIFY_EQUAL(x,y) \ MPT_DO { \ if((x) != (y)) { \ MyDebugBreak(); \ } \ } MPT_WHILE_0 \ /**/ // Like VERIFY_EQUAL, only differs for libopenmpt #define VERIFY_EQUAL_NONCONT VERIFY_EQUAL // Like VERIFY_EQUAL, only differs for libopenmpt #define VERIFY_EQUAL_QUIET_NONCONT VERIFY_EQUAL #define VERIFY_EQUAL_EPS(x,y,eps) \ MPT_DO { \ if(mpt::abs((x) - (y)) > (eps)) { \ MyDebugBreak(); \ } \ } MPT_WHILE_0 \ /**/ #define DO_TEST(func) \ MPT_DO { \ if(IsDebuggerPresent()) { \ func(); \ } \ } MPT_WHILE_0 \ /**/ } // namespace Test OPENMPT_NAMESPACE_END #endif // MODPLUG_TRACKER #endif // ENABLE_TESTS libopenmpt-0.3.6+release.autotools/README.md0000644000372100037210000002563113213436241015543 00000000000000 README ====== OpenMPT and libopenmpt ====================== How to compile -------------- ### OpenMPT - Supported Visual Studio versions: - Visual Studio 2015 Update 3 Community/Professional/Enterprise To compile the project, open `build/vs2015/OpenMPT.sln` and hit the compile button. - Visual Studio 2017 Community/Professional/Enterprise To compile the project, open `build/vs2017/OpenMPT.sln` and hit the compile button. - The Windows 8.1 SDK and Microsoft Foundation Classes (MFC) are required to build OpenMPT (both are included with Visual Studio, however may need to be selected explicitly during setup). In order to build OpenMPT for Windows XP, the XP targetting toolset also needs to be installed. - The VST and ASIO SDKs are needed for compiling with VST and ASIO support. If you don't want this, uncomment `#define NO_VST` and comment out `#define MPT_WITH_ASIO` in the file `common/BuildSettings.h`. The ASIO and VST SDKs can be downloaded automatically on Windows 7 or later with 7-Zip installed by just running the `build/download_externals.cmd` script. If you do not want to or cannot use this script, you may follow these manual steps instead: - ASIO: If you use `#define MPT_WITH_ASIO`, you will need to put the ASIO SDK in the `include/ASIOSDK2` folder. The top level directory of the SDK is already named `ASIOSDK2`, so simply move that directory in the include folder. Please visit [steinberg.net](http://www.steinberg.net/en/company/developers.html) to download the SDK. - VST: If you don't use `#define NO_VST`, you will need to put the VST SDK in the `include/vstsdk2.4` folder. Simply copy all files from the `VST3 SDK` folder in the SDK .zip file to `include/vstsdk2.4/`. Note: OpenMPT makes use of the VST 2.4 specification only. The VST3 SDK still contains all necessary files in the right locations. If you still have the old VST 2.4 SDK laying around, this should also work fine. Please visit [steinberg.net](http://www.steinberg.net/en/company/developers.html) to download the SDK. If you need further help with the VST and ASIO SDKs, get in touch with the main OpenMPT developers. - 7-Zip is required to be installed in the default path in order to build the required files for OpenMPT Wine integration. Please visit [7-zip.org](http://www.7-zip.org/) to download 7-Zip. ### libopenmpt and openmpt123 For detailed requirements, see `libopenmpt/dox/quickstart.md`. - Autotools Grab a `libopenmpt-VERSION-autotools.tar.gz` tarball. ./configure make make check sudo make install - Visual Studio: - You will find solutions for Visual Studio 2015 to 2017 in the corresponding `build/vsVERSION/` folder. Projects that target Windows versions before Windows 7 are available in `build/vsVERSIONxp/` Most projects are supported with any of the mentioned Visual Studio verions, with the following exceptions: - in_openmpt: Requires Visual Studio with MFC. - xmp-openmpt: Requires Visual Studio with MFC. - You will need the Winamp 5 SDK and the XMPlay SDK if you want to compile the plugins for these 2 players. They can be downloaded automatically on Windows 7 or later with 7-Zip installed by just running the `build/download_externals.cmd` script. If you do not want to or cannot use this script, you may follow these manual steps instead: - Winamp 5 SDK: To build libopenmpt as a winamp input plugin, copy the contents of `WA5.55_SDK.exe` to include/winamp/. Please visit [winamp.com](http://wiki.winamp.com/wiki/Plug-in_Developer) to download the SDK. You can disable in_openmpt in the solution configuration. - XMPlay SDK: To build libopenmpt with XMPlay input plugin support, copy the contents of xmp-sdk.zip into include/xmplay/. Please visit [un4seen.com](http://www.un4seen.com/xmplay.html) to download the SDK. You can disable xmp-openmpt in the solution configuration. - Makefile The makefile supports different build environments and targets via the `CONFIG=` parameter directly to the make invocation. Use `make CONFIG=$newconfig clean` when switching between different configs because the makefile cleans only intermediates and target that are active for the current config and no configuration state is kept around across invocations. - mingw-w64: The required version is at least 4.8. make CONFIG=mingw64-win32 # for win32 make CONFIG=mingw64-win64 # for win64 - gcc or clang (on Unix-like systems, including Mac OS X with MacPorts): The minimum required compiler versions are: - gcc 4.8 - clang 3.4 The Makefile requires pkg-config for native builds. For sound output in openmpt123, PortAudio or SDL is required. openmpt123 can optionally use libflac and libsndfile to render PCM files to disk. When using gcc, run: make CONFIG=gcc When using clang, it is recommended to do: make CONFIG=clang Otherwise, simply run make which will try to guess the compiler based on your operating system. - emscripten (on Unix-like systems): libopenmpt has been tested and verified to work with emscripten 1.31 or later (earlier versions might or might not work). Run: make CONFIG=emscripten Running the test suite on the command line is also supported by using node.js. Version 0.10.25 or greater has been tested. Earlier versions might or might not work. Depending on how your distribution calls the `node.js` binary, you might have to edit `build/make/config-emscripten.mk`. - Haiku: To compile libopenmpt on Haiku (using the 32-bit gcc2h), run: make CONFIG=haiku - American Fuzzy Lop: To compile libopenmpt with fuzzing instrumentation for afl-fuzz, run: make CONFIG=afl For more detailed instructions, read contrib/fuzzing/readme.md - other compilers: To compiler libopenmpt with other C++11 compliant compilers, run: make CONFIG=generic The `Makefile` supports some customizations. You might want to read the top which should get you some possible make settings, like e.g. `make DYNLINK=0` or similar. Cross compiling or different compiler would best be implemented via new `config-*.mk` files. The `Makefile` also supports building doxygen documentation by using make doc Binaries and documentation can be installed systen-wide with make PREFIX=/yourprefix install make PREFIX=/yourprefix install-doc Some systems (i.e. Linux) require running sudo ldconfig in order for the system linker to be able to pick up newly installed libraries. `PREFIX` defaults to `/usr/local`. A `DESTDIR=` parameter is also supported. - Android NDK See `build/android_ndk/README.AndroidNDK.txt`. Coding conventions ------------------ ### OpenMPT (see below for an example) - Place curly braces at the beginning of the line, not at the end - Generally make use of the custom index types like `SAMPLEINDEX` or `ORDERINDEX` when referring to samples, orders, etc. - When changing playback behaviour, make sure that you use the function `CSoundFile::IsCompatibleMode()` so that modules made with previous versions of MPT still sound correct (if the change is extremely small, this might be unnecessary) - `CamelCase` function and variable names are preferred. #### OpenMPT code example ~~~~{.cpp} void Foo::Bar(int foobar) { while(true) { // some code } } ~~~~ ### libopenmpt **Note:** **This applies to `libopenmpt/` and `openmpt123/` directories only.** **Use OpenMPT style (see above) otherwise.** The code generally tries to follow these conventions, but they are not strictly enforced and there are valid reasons to diverge from these conventions. Using common sense is recommended. - In general, the most important thing is to keep style consistent with directly surrounding code. - Use C++ std types when possible, prefer `std::size_t` and `std::int32_t` over `long` or `int`. Do not use C99 std types (e.g. no pure `int32_t`) - Qualify namespaces explicitly, do not use `using`. Members of `namespace openmpt` can be named without full namespace qualification. - Prefer the C++ version in `namespace std` if the same functionality is provided by the C standard library as well. Also, include the C++ version of C standard library headers (e.g. use `` instead of ``. - Do not use ANY locale-dependant C functions. For locale-dependant C++ functionaly (especially iostream), always imbue the `std::locale::classic()` locale. - Prefer kernel_style_names over CamelCaseNames. - If a folder (or one of its parent folders) contains .clang-format, use clang-format v3.5 for indenting C++ and C files, otherwise: - `{` are placed at the end of the opening line. - Enclose even single statements in curly braces. - Avoid placing single statements on the same line as the `if`. - Opening parentheses are separated from keywords with a space. - Opening parentheses are not separated from function names. - Place spaces around operators and inside parentheses. - Align `:` and `,` when inheriting or initializing members in a constructor. - The pointer `*` is separated from both the type and the variable name. - Use tabs for identation, spaces for formatting. Tabs should only appear at the very beginning of a line. Do not assume any particular width of the TAB character. If width is important for formatting reasons, use spaces. - Use empty lines at will. - API documentation is done with doxygen. Use general C doxygen for the C API. Use QT-style doxygen for the C++ API. #### libopenmpt indentation example ~~~~{.cpp} namespace openmpt { // This is totally meaningless code and just illustrates indentation. class foo : public base , public otherbase { private: std::int32_t x; std::int16_t y; public: foo() : x(0) , y(-1) { return; } int bar() const; }; // class foo int foo::bar() const { for ( int i = 0; i < 23; ++i ) { switch ( x ) { case 2: something( y ); break; default: something( ( y - 1 ) * 2 ); break; } } if ( x == 12 ) { return -1; } else if ( x == 42 ) { return 1; } return 42; } } // namespace openmpt ~~~~ libopenmpt-0.3.6+release.autotools/config.h.in0000644000372100037210000000516013235362220016301 00000000000000/* config.h.in. Generated from configure.ac by autoheader. */ /* define if the compiler supports basic C++11 syntax */ #undef HAVE_CXX11 /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to the sub-directory where libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* is package */ #undef MPT_PACKAGE /* svn date */ #undef MPT_SVNDATE /* svn version */ #undef MPT_SVNURL /* svn version */ #undef MPT_SVNVERSION /* with libflac */ #undef MPT_WITH_FLAC /* with mpg123 */ #undef MPT_WITH_MPG123 /* with ogg */ #undef MPT_WITH_OGG /* with libportaudio */ #undef MPT_WITH_PORTAUDIO /* with libportaudiocpp */ #undef MPT_WITH_PORTAUDIOCPP /* with libpulseaudio */ #undef MPT_WITH_PULSEAUDIO /* with libsdl */ #undef MPT_WITH_SDL /* with libsdl2 */ #undef MPT_WITH_SDL2 /* with libsndfile */ #undef MPT_WITH_SNDFILE /* with vorbis */ #undef MPT_WITH_VORBIS /* with vorbisfile */ #undef MPT_WITH_VORBISFILE /* with zlib */ #undef MPT_WITH_ZLIB /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Version number of package */ #undef VERSION /* Enable large inode numbers on Mac OS X 10.5. */ #ifndef _DARWIN_USE_64_BIT_INODE # define _DARWIN_USE_64_BIT_INODE 1 #endif /* Number of bits in a file offset, on hosts where this is settable. */ #undef _FILE_OFFSET_BITS /* Define for large files, on AIX-style hosts. */ #undef _LARGE_FILES libopenmpt-0.3.6+release.autotools/common/0000755000372100037210000000000013235362225015631 500000000000000libopenmpt-0.3.6+release.autotools/common/mptStringParse.cpp0000644000372100037210000001305312571250575021247 00000000000000/* * mptStringParse.cpp * ------------------ * Purpose: Convert strings to other types. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "mptStringParse.h" #include #include OPENMPT_NAMESPACE_BEGIN template inline T ConvertStrToHelper(const std::string &str) { std::istringstream i(str); i.imbue(std::locale::classic()); T x; if(!(i >> x)) { return T(); } return x; } template<> inline bool ConvertStrToHelper(const std::string &str) { return ConvertStrToHelper(str)?true:false; } template<> inline signed char ConvertStrToHelper(const std::string &str) { return static_cast(ConvertStrToHelper(str)); } template<> inline unsigned char ConvertStrToHelper(const std::string &str) { return static_cast(ConvertStrToHelper(str)); } #if MPT_WSTRING_FORMAT template inline T ConvertStrToHelper(const std::wstring &str) { std::wistringstream i(str); i.imbue(std::locale::classic()); T x; if(!(i >> x)) { return T(); } return x; } template<> inline bool ConvertStrToHelper(const std::wstring &str) { return ConvertStrToHelper(str)?true:false; } template<> inline signed char ConvertStrToHelper(const std::wstring &str) { return static_cast(ConvertStrToHelper(str)); } template<> inline unsigned char ConvertStrToHelper(const std::wstring &str) { return static_cast(ConvertStrToHelper(str)); } #endif bool ConvertStrToBool(const std::string &str) { return ConvertStrToHelper(str); } signed char ConvertStrToSignedChar(const std::string &str) { return ConvertStrToHelper(str); } unsigned char ConvertStrToUnsignedChar(const std::string &str) { return ConvertStrToHelper(str); } signed short ConvertStrToSignedShort(const std::string &str) { return ConvertStrToHelper(str); } unsigned short ConvertStrToUnsignedShort(const std::string &str) { return ConvertStrToHelper(str); } signed int ConvertStrToSignedInt(const std::string &str) { return ConvertStrToHelper(str); } unsigned int ConvertStrToUnsignedInt(const std::string &str) { return ConvertStrToHelper(str); } signed long ConvertStrToSignedLong(const std::string &str) { return ConvertStrToHelper(str); } unsigned long ConvertStrToUnsignedLong(const std::string &str) { return ConvertStrToHelper(str); } signed long long ConvertStrToSignedLongLong(const std::string &str) { return ConvertStrToHelper(str); } unsigned long long ConvertStrToUnsignedLongLong(const std::string &str) { return ConvertStrToHelper(str); } float ConvertStrToFloat(const std::string &str) { return ConvertStrToHelper(str); } double ConvertStrToDouble(const std::string &str) { return ConvertStrToHelper(str); } long double ConvertStrToLongDouble(const std::string &str) { return ConvertStrToHelper(str); } #if MPT_WSTRING_FORMAT bool ConvertStrToBool(const std::wstring &str) { return ConvertStrToHelper(str); } signed char ConvertStrToSignedChar(const std::wstring &str) { return ConvertStrToHelper(str); } unsigned char ConvertStrToUnsignedChar(const std::wstring &str) { return ConvertStrToHelper(str); } signed short ConvertStrToSignedShort(const std::wstring &str) { return ConvertStrToHelper(str); } unsigned short ConvertStrToUnsignedShort(const std::wstring &str) { return ConvertStrToHelper(str); } signed int ConvertStrToSignedInt(const std::wstring &str) { return ConvertStrToHelper(str); } unsigned int ConvertStrToUnsignedInt(const std::wstring &str) { return ConvertStrToHelper(str); } signed long ConvertStrToSignedLong(const std::wstring &str) { return ConvertStrToHelper(str); } unsigned long ConvertStrToUnsignedLong(const std::wstring &str) { return ConvertStrToHelper(str); } signed long long ConvertStrToSignedLongLong(const std::wstring &str) { return ConvertStrToHelper(str); } unsigned long long ConvertStrToUnsignedLongLong(const std::wstring &str) { return ConvertStrToHelper(str); } float ConvertStrToFloat(const std::wstring &str) { return ConvertStrToHelper(str); } double ConvertStrToDouble(const std::wstring &str) { return ConvertStrToHelper(str); } long double ConvertStrToLongDouble(const std::wstring &str) { return ConvertStrToHelper(str); } #endif namespace mpt { namespace String { namespace Parse { template T HexToHelper(const std::string &str) { std::istringstream i(str); i.imbue(std::locale::classic()); T x; if(!(i >> std::hex >> x)) { return T(); } return x; } template<> unsigned char HexToHelper(const std::string &str) { return static_cast(HexToHelper(str)); } unsigned char HexToUnsignedChar(const std::string &str) { return HexToHelper(str); } unsigned short HexToUnsignedShort(const std::string &str) { return HexToHelper(str); } unsigned int HexToUnsignedInt(const std::string &str) { return HexToHelper(str); } unsigned long HexToUnsignedLong(const std::string &str) { return HexToHelper(str); } unsigned long long HexToUnsignedLongLong(const std::string &str) { return HexToHelper(str); } } // namespace Parse } // namespace String } // namespace mpt OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/mptRandom.cpp0000644000372100037210000001616013100316523020211 00000000000000/* * mptRandom.cpp * ------------- * Purpose: PRNG * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "mptRandom.h" #include "Endianness.h" #include "mptCRC.h" #include #include #include #include #if MPT_OS_WINDOWS #include #endif // MPT_OS_WINDOWS OPENMPT_NAMESPACE_BEGIN namespace mpt { template static T log2(T x) { return std::log(x) / std::log(static_cast(2)); } static MPT_CONSTEXPR11_FUN int lower_bound_entropy_bits(unsigned int x) { return detail::lower_bound_entropy_bits(x); } template static inline bool is_mask(T x) { STATIC_ASSERT(std::numeric_limits::is_integer); typedef typename std::make_unsigned::type unsigned_T; unsigned_T ux = static_cast(x); unsigned_T mask = 0; for(std::size_t bits = 0; bits <= (sizeof(unsigned_T) * 8); ++bits) { mask = (mask << 1) | 1u; if(ux == mask) { return true; } } return false; } namespace { template struct default_hash { }; template <> struct default_hash { typedef mpt::checksum::crc16 type; }; template <> struct default_hash { typedef mpt::checksum::crc16 type; }; template <> struct default_hash { typedef mpt::checksum::crc32c type; }; template <> struct default_hash { typedef mpt::checksum::crc64_jones type; }; } template static T generate_timeseed() { // Note: CRC is actually not that good a choice here, but it is simple and we // already have an implementaion available. Better choices for mixing entropy // would be a hash function with proper avalanche characteristics or a block // or stream cipher with any pre-choosen random key and IV. The only aspect we // really need here is whitening of the bits. typename mpt::default_hash::type hash; #ifdef MPT_BUILD_FUZZER return static_cast(mpt::FUZZER_RNG_SEED); #else // !MPT_BUILD_FUZZER { #if MPT_OS_WINDOWS FILETIME t; MemsetZero(t); GetSystemTimeAsFileTime(&t); #else // !MPT_OS_WINDOWS std::time_t t = std::time(nullptr); #endif // MPT_OS_WINDOWS mpt::byte bytes[sizeof(t)]; std::memcpy(bytes, &t, sizeof(t)); MPT_MAYBE_CONSTANT_IF(mpt::endian_is_little()) { std::reverse(std::begin(bytes), std::end(bytes)); } hash(std::begin(bytes), std::end(bytes)); } { std::clock_t c = std::clock(); mpt::byte bytes[sizeof(c)]; std::memcpy(bytes, &c, sizeof(c)); MPT_MAYBE_CONSTANT_IF(mpt::endian_is_little()) { std::reverse(std::begin(bytes), std::end(bytes)); } hash(std::begin(bytes), std::end(bytes)); } return static_cast(hash.result()); #endif // MPT_BUILD_FUZZER } #ifdef MODPLUG_TRACKER namespace rng { void crand::reseed(uint32 seed) { std::srand(seed); } crand::result_type crand::operator()() { return std::rand(); } } // namespace rng #endif // MODPLUG_TRACKER sane_random_device::sane_random_device() : rd_reliable(rd.entropy() > 0.0) { if(!rd_reliable) { init_fallback(); } } sane_random_device::sane_random_device(const std::string & token_) : token(token_) , rd(token) , rd_reliable(rd.entropy() > 0.0) { if(!rd_reliable) { init_fallback(); } } void sane_random_device::init_fallback() { if(!rd_fallback) { if(token.length() > 0) { uint64 seed_val = mpt::generate_timeseed(); std::vector seeds; seeds.push_back(static_cast(seed_val >> 32)); seeds.push_back(static_cast(seed_val >> 0)); for(std::size_t i = 0; i < token.length(); ++i) { seeds.push_back(static_cast(static_cast(token[i]))); } std::seed_seq seed(seeds.begin(), seeds.end()); rd_fallback = mpt::make_unique(seed); } else { uint64 seed_val = mpt::generate_timeseed(); unsigned int seeds[2]; seeds[0] = static_cast(seed_val >> 32); seeds[1] = static_cast(seed_val >> 0); std::seed_seq seed(seeds + 0, seeds + 2); rd_fallback = mpt::make_unique(seed); } } } sane_random_device::result_type sane_random_device::operator()() { MPT_LOCK_GUARD l(m); result_type result = 0; try { if(rd.min() != 0 || !mpt::is_mask(rd.max())) { // insane std::random_device // This implementation is not exactly uniformly distributed but good enough // for OpenMPT. double rd_min = static_cast(rd.min()); double rd_max = static_cast(rd.max()); double rd_range = rd_max - rd_min; double rd_size = rd_range + 1.0; double rd_entropy = mpt::log2(rd_size); int iterations = static_cast(std::ceil(result_bits() / rd_entropy)); double tmp = 0.0; for(int i = 0; i < iterations; ++i) { tmp = (tmp * rd_size) + (static_cast(rd()) - rd_min); } double result_01 = std::floor(tmp / std::pow(rd_size, iterations)); result = static_cast(std::floor(result_01 * (static_cast(max() - min()) + 1.0))) + min(); } else { // sane std::random_device result = 0; std::size_t rd_bits = mpt::lower_bound_entropy_bits(rd.max()); for(std::size_t entropy = 0; entropy < (sizeof(result_type) * 8); entropy += rd_bits) { if(rd_bits < (sizeof(result_type) * 8)) { result = (result << rd_bits) | static_cast(rd()); } else { result = result | static_cast(rd()); } } } } catch(const std::exception &) { rd_reliable = false; init_fallback(); } if(!rd_reliable) { // std::random_device is unreliable // XOR the generated random number with more entropy from the time-seeded // PRNG. // Note: This is safe even if the std::random_device itself is implemented // as a std::mt19937 PRNG because we are very likely using a different // seed. result ^= mpt::random(*rd_fallback); } return result; } prng_random_device_seeder::prng_random_device_seeder() { return; } uint8 prng_random_device_seeder::generate_seed8() { return mpt::generate_timeseed(); } uint16 prng_random_device_seeder::generate_seed16() { return mpt::generate_timeseed(); } uint32 prng_random_device_seeder::generate_seed32() { return mpt::generate_timeseed(); } uint64 prng_random_device_seeder::generate_seed64() { return mpt::generate_timeseed(); } #if defined(MODPLUG_TRACKER) && !defined(MPT_BUILD_WINESUPPORT) static mpt::random_device *g_rd = nullptr; static mpt::thread_safe_prng *g_best_prng = nullptr; void set_global_random_device(mpt::random_device *rd) { g_rd = rd; } void set_global_prng(mpt::thread_safe_prng *prng) { g_best_prng = prng; } mpt::random_device & global_random_device() { return *g_rd; } mpt::thread_safe_prng & global_prng() { return *g_best_prng; } #else mpt::random_device & global_random_device() { static mpt::random_device g_rd; return g_rd; } mpt::thread_safe_prng & global_prng() { static mpt::thread_safe_prng g_best_prng(global_random_device()); return g_best_prng; } #endif // MODPLUG_TRACKER && !MPT_BUILD_WINESUPPORT } // namespace mpt OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/mptLibrary.h0000644000372100037210000000631513077150054020053 00000000000000/* * mptLibrary.h * ------------ * Purpose: Shared library handling. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once OPENMPT_NAMESPACE_BEGIN #if defined(MPT_ENABLE_DYNBIND) namespace mpt { typedef void* (*FuncPtr)(); // pointer to function returning void* class LibraryHandle; enum LibrarySearchPath { LibrarySearchPathInvalid, LibrarySearchPathDefault, LibrarySearchPathApplication, LibrarySearchPathSystem, LibrarySearchPathFullPath, }; class LibraryPath { private: mpt::LibrarySearchPath searchPath; mpt::PathString fileName; private: LibraryPath(mpt::LibrarySearchPath searchPath, const mpt::PathString &fileName); public: mpt::LibrarySearchPath GetSearchPath() const; mpt::PathString GetFileName() const; public: // "lib" on Unix-like systems, "" on Windows static mpt::PathString GetDefaultPrefix(); // ".so" or ".dylib" or ".dll" static mpt::PathString GetDefaultSuffix(); // Returns the library path in the application directory, with os-specific prefix and suffix added to basename. // e.g.: basename = "unmo3" --> "libunmo3.so" / "apppath/unmo3.dll" static LibraryPath App(const mpt::PathString &basename); // Returns the library path in the application directory, with os-specific suffix added to fullname. // e.g.: fullname = "libunmo3" --> "libunmo3.so" / "apppath/libunmo3.dll" static LibraryPath AppFullName(const mpt::PathString &fullname); #if defined(MODPLUG_TRACKER) && !defined(MPT_BUILD_WINESUPPORT) // Returns the library path in the application data directory, with os-specific suffix added to fullname. // e.g.: fullname = "libunmo3" --> "libunmo3.so" / "appdata/libunmo3.dll" (appdata == C:\Users\SOMEUSER\AppData\OpenMPT\Components\) static LibraryPath AppDataFullName(const mpt::PathString &fullname, const mpt::PathString &appdata); #endif // MODPLUG_TRACKER && !MPT_BUILD_WINESUPPORT // Returns a system library name with os-specific prefix and suffix added to basename, but without any full path in order to be searched in the default search path. // e.g.: basename = "unmo3" --> "libunmo3.so" / "unmo3.dll" static LibraryPath System(const mpt::PathString &basename); // Returns a system library name with os-specific suffix added to path. // e.g.: path = "somepath/foo" --> "somepath/foo.so" / "somepath/foo.dll" static LibraryPath FullPath(const mpt::PathString &path); }; class Library { protected: std::shared_ptr m_Handle; public: Library(); Library(const mpt::LibraryPath &path); public: void Unload(); bool IsValid() const; FuncPtr GetProcAddress(const std::string &symbol) const; template bool Bind(Tfunc * & f, const std::string &symbol) const { #if !(MPT_OS_WINDOWS && MPT_COMPILER_GCC) // MinGW64 std::is_function is always false for non __cdecl functions. // See https://connect.microsoft.com/VisualStudio/feedback/details/774720/stl-is-function-bug . STATIC_ASSERT(std::is_function::value); #endif const FuncPtr addr = GetProcAddress(symbol); f = reinterpret_cast(addr); return (addr != nullptr); } }; } // namespace mpt #endif // MPT_ENABLE_DYNBIND OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/CompilerDetect.h0000644000372100037210000002553513212506624020635 00000000000000/* * CompilerDetect.h * ---------------- * Purpose: Detect current compiler and provide readable version test macros. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #define MPT_COMPILER_MAKE_VERSION2(version,sp) ((version) * 100 + (sp)) #define MPT_COMPILER_MAKE_VERSION3(major,minor,patch) ((major) * 10000 + (minor) * 100 + (patch)) #define MPT_COMPILER_MAKE_VERSION3_BUILD(major,minor,build) ((major) * 10000000 + (minor) * 100000 + (patch)) #if defined(MPT_COMPILER_GENERIC) #undef MPT_COMPILER_GENERIC #define MPT_COMPILER_GENERIC 1 #elif defined(__clang__) && defined(_MSC_VER) && defined(__c2__) #define MPT_COMPILER_MSVCCLANGC2 1 #define MPT_COMPILER_MSVCCLANGC2_VERSION (__c2_version__) #define MPT_MSVCCLANGC2_AT_LEAST(major,minor,build) (MPT_COMPILER_MSVCCLANGC2_VERSION >= MPT_COMPILER_MAKE_VERSION3_BUILD((major),(minor),(build))) #define MPT_MSVCCLANGC2_BEFORE(major,minor,build) (MPT_COMPILER_MSVCCLANGC2_VERSION < MPT_COMPILER_MAKE_VERSION3_BUILD((major),(minor),(build))) #elif defined(__clang__) #define MPT_COMPILER_CLANG 1 #define MPT_COMPILER_CLANG_VERSION MPT_COMPILER_MAKE_VERSION3(__clang_major__,__clang_minor__,__clang_patchlevel__) #define MPT_CLANG_AT_LEAST(major,minor,patch) (MPT_COMPILER_CLANG_VERSION >= MPT_COMPILER_MAKE_VERSION3((major),(minor),(patch))) #define MPT_CLANG_BEFORE(major,minor,patch) (MPT_COMPILER_CLANG_VERSION < MPT_COMPILER_MAKE_VERSION3((major),(minor),(patch))) #if MPT_CLANG_BEFORE(3,4,0) #error "clang version 3.4 required" #endif #if defined(__clang_analyzer__) #ifndef MPT_BUILD_ANALYZED #define MPT_BUILD_ANALYZED #endif #endif #elif defined(__GNUC__) #define MPT_COMPILER_GCC 1 #define MPT_COMPILER_GCC_VERSION MPT_COMPILER_MAKE_VERSION3(__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__) #define MPT_GCC_AT_LEAST(major,minor,patch) (MPT_COMPILER_GCC_VERSION >= MPT_COMPILER_MAKE_VERSION3((major),(minor),(patch))) #define MPT_GCC_BEFORE(major,minor,patch) (MPT_COMPILER_GCC_VERSION < MPT_COMPILER_MAKE_VERSION3((major),(minor),(patch))) #if MPT_GCC_BEFORE(4,8,0) #error "GCC version 4.8 required" #endif #elif defined(_MSC_VER) #define MPT_COMPILER_MSVC 1 #if (_MSC_VER >= 1912) #define MPT_COMPILER_MSVC_VERSION MPT_COMPILER_MAKE_VERSION2(2017,5) #elif (_MSC_VER >= 1911) #define MPT_COMPILER_MSVC_VERSION MPT_COMPILER_MAKE_VERSION2(2017,3) #elif (_MSC_VER >= 1910) #define MPT_COMPILER_MSVC_VERSION MPT_COMPILER_MAKE_VERSION2(2017,0) #elif (_MSC_VER >= 1900) #define MPT_COMPILER_MSVC_VERSION MPT_COMPILER_MAKE_VERSION2(2015,0) #elif (_MSC_VER >= 1800) #define MPT_COMPILER_MSVC_VERSION MPT_COMPILER_MAKE_VERSION2(2013,0) #elif (_MSC_VER >= 1700) #define MPT_COMPILER_MSVC_VERSION MPT_COMPILER_MAKE_VERSION2(2012,0) #elif (_MSC_VER >= 1600) #define MPT_COMPILER_MSVC_VERSION MPT_COMPILER_MAKE_VERSION2(2010,0) #elif (_MSC_VER >= 1500) #define MPT_COMPILER_MSVC_VERSION MPT_COMPILER_MAKE_VERSION2(2008,0) #else #define MPT_COMPILER_MSVC_VERSION MPT_COMPILER_MAKE_VERSION2(2005,0) #endif #define MPT_MSVC_AT_LEAST(version,sp) (MPT_COMPILER_MSVC_VERSION >= MPT_COMPILER_MAKE_VERSION2((version),(sp))) #define MPT_MSVC_BEFORE(version,sp) (MPT_COMPILER_MSVC_VERSION < MPT_COMPILER_MAKE_VERSION2((version),(sp))) #if MPT_MSVC_BEFORE(2015,0) #error "MSVC version 2015 required" #endif #if defined(_PREFAST_) #ifndef MPT_BUILD_ANALYZED #define MPT_BUILD_ANALYZED #endif #endif #else #define MPT_COMPILER_GENERIC 1 #endif #ifndef MPT_COMPILER_GENERIC #define MPT_COMPILER_GENERIC 0 #endif #ifndef MPT_COMPILER_MSVCCLANGC2 #define MPT_COMPILER_MSVCCLANGC2 0 #define MPT_MSVCCLANGC2_AT_LEAST(major,minor,build) 0 #define MPT_MSVCCLANGC2_BEFORE(major,minor,build) 0 #endif #ifndef MPT_COMPILER_CLANG #define MPT_COMPILER_CLANG 0 #define MPT_CLANG_AT_LEAST(major,minor,patch) 0 #define MPT_CLANG_BEFORE(major,minor,patch) 0 #endif #ifndef MPT_COMPILER_GCC #define MPT_COMPILER_GCC 0 #define MPT_GCC_AT_LEAST(major,minor,patch) 0 #define MPT_GCC_BEFORE(major,minor,patch) 0 #endif #ifndef MPT_COMPILER_MSVC #define MPT_COMPILER_MSVC 0 #define MPT_MSVC_AT_LEAST(version,sp) 0 #define MPT_MSVC_BEFORE(version,sp) 0 #endif #if MPT_COMPILER_GENERIC || MPT_COMPILER_GCC || MPT_COMPILER_CLANG #if (__cplusplus >= 201703) #define MPT_CXX 17 #elif (__cplusplus >= 201402) #define MPT_CXX 14 #else #define MPT_CXX 11 #endif #elif MPT_COMPILER_MSVC #if MPT_MSVC_AT_LEAST(2017,0) #if (_MSVC_LANG >= 201402) #define MPT_CXX 14 #else #define MPT_CXX 11 #endif #else #define MPT_CXX 11 #endif #else #define MPT_CXX 11 #endif // MPT_CXX is stricter than just using __cplusplus directly. // We will only claim a language version as supported IFF all core language and // library fatures that we need are actually supported AND working correctly // (to our needs). #define MPT_CXX_AT_LEAST(version) (MPT_CXX >= (version)) #define MPT_CXX_BEFORE(version) (MPT_CXX < (version)) #if MPT_COMPILER_MSVC #define MPT_PLATFORM_LITTLE_ENDIAN #elif MPT_COMPILER_GCC #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ #define MPT_PLATFORM_BIG_ENDIAN #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #define MPT_PLATFORM_LITTLE_ENDIAN #endif #elif MPT_COMPILER_CLANG || MPT_COMPILER_MSVCCLANGC2 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ #define MPT_PLATFORM_BIG_ENDIAN #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #define MPT_PLATFORM_LITTLE_ENDIAN #endif #endif // fallback: #if !defined(MPT_PLATFORM_BIG_ENDIAN) && !defined(MPT_PLATFORM_LITTLE_ENDIAN) // taken from boost/detail/endian.hpp #if (defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)) \ || (defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)) \ || (defined(_STLP_BIG_ENDIAN) && !defined(_STLP_LITTLE_ENDIAN)) #define MPT_PLATFORM_BIG_ENDIAN #elif (defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)) \ || (defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)) \ || (defined(_STLP_LITTLE_ENDIAN) && !defined(_STLP_BIG_ENDIAN)) #define MPT_PLATFORM_LITTLE_ENDIAN #elif defined(__sparc) || defined(__sparc__) \ || defined(_POWER) || defined(__powerpc__) \ || defined(__ppc__) || defined(__hpux) || defined(__hppa) \ || defined(_MIPSEB) || defined(_POWER) \ || defined(__s390__) #define MPT_PLATFORM_BIG_ENDIAN #elif defined(__i386__) || defined(__alpha__) \ || defined(__ia64) || defined(__ia64__) \ || defined(_M_IX86) || defined(_M_IA64) \ || defined(_M_ALPHA) || defined(__amd64) \ || defined(__amd64__) || defined(_M_AMD64) \ || defined(__x86_64) || defined(__x86_64__) \ || defined(_M_X64) || defined(__bfin__) #define MPT_PLATFORM_LITTLE_ENDIAN #endif #endif #if defined(MPT_PLATFORM_BIG_ENDIAN) || defined(MPT_PLATFORM_LITTLE_ENDIAN) #define MPT_PLATFORM_ENDIAN_KNOWN 1 #else #define MPT_PLATFORM_ENDIAN_KNOWN 0 #endif // This should really be based on __STDCPP_THREADS__, but that is not defined by // GCC or clang. Stupid. // Just assume multithreaded and disable for platforms we know are // singlethreaded later on. #define MPT_PLATFORM_MULTITHREADED 1 // specific C++ features // C++11 constexpr #if MPT_COMPILER_MSVC #define MPT_COMPILER_QUIRK_CONSTEXPR_NO_STRING_LITERALS #endif #if MPT_COMPILER_MSVC // Compiler has multiplication/division semantics when shifting signed integers. #define MPT_COMPILER_SHIFT_SIGNED 1 #endif #ifndef MPT_COMPILER_SHIFT_SIGNED #define MPT_COMPILER_SHIFT_SIGNED 0 #endif #if MPT_COMPILER_GCC || MPT_COMPILER_MSVC // Compiler supports type-punning through unions. This is not stricly standard-conforming. // For GCC, this is documented, for MSVC this is apparently not documented, but we assume it. #define MPT_COMPILER_UNION_TYPE_ALIASES 1 #endif #ifndef MPT_COMPILER_UNION_TYPE_ALIASES // Compiler does not support type-punning through unions. std::memcpy is used instead. // This is the safe fallback and strictly standard-conforming. // Another standard-compliant alternative would be casting pointers to a character type pointer. // This results in rather unreadable code and, // in most cases, compilers generate better code by just inlining the memcpy anyway. // (see ). #define MPT_COMPILER_UNION_TYPE_ALIASES 0 #endif // The order of the checks matters! #if defined(__EMSCRIPTEN__) #define MPT_OS_EMSCRIPTEN 1 #if defined(__EMSCRIPTEN_major__) && defined(__EMSCRIPTEN_minor__) #if (__EMSCRIPTEN_major__ > 1) #define MPT_OS_EMSCRIPTEN_ANCIENT 0 #elif (__EMSCRIPTEN_major__ == 1) && (__EMSCRIPTEN_minor__ >= 36) #define MPT_OS_EMSCRIPTEN_ANCIENT 0 #else #define MPT_OS_EMSCRIPTEN_ANCIENT 1 #endif #else #define MPT_OS_EMSCRIPTEN_ANCIENT 1 #endif #elif defined(_WIN32) #define MPT_OS_WINDOWS 1 #if defined(WINAPI_FAMILY) #include #if (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP) #define MPT_OS_WINDOWS_WINRT 0 #else #define MPT_OS_WINDOWS_WINRT 1 #endif #else // !WINAPI_FAMILY #define MPT_OS_WINDOWS_WINRT 0 #endif // WINAPI_FAMILY #elif defined(__APPLE__) #define MPT_OS_MACOSX_OR_IOS 1 //#include "TargetConditionals.h" //#if TARGET_IPHONE_SIMULATOR //#elif TARGET_OS_IPHONE //#elif TARGET_OS_MAC //#else //#endif #elif defined(__ANDROID__) || defined(ANDROID) #define MPT_OS_ANDROID 1 #elif defined(__linux__) #define MPT_OS_LINUX 1 #elif defined(__DragonFly__) #define MPT_OS_DRAGONFLYBSD 1 #elif defined(__FreeBSD__) #define MPT_OS_FREEBSD 1 #elif defined(__OpenBSD__) #define MPT_OS_OPENBSD 1 #elif defined(__NetBSD__) #define MPT_OS_NETBSD 1 #elif defined(__unix__) #define MPT_OS_GENERIC_UNIX 1 #else #define MPT_OS_UNKNOWN 1 #endif #ifndef MPT_OS_EMSCRIPTEN #define MPT_OS_EMSCRIPTEN 0 #endif #ifndef MPT_OS_WINDOWS #define MPT_OS_WINDOWS 0 #endif #ifndef MPT_OS_WINDOWS_WINRT #define MPT_OS_WINDOWS_WINRT 0 #endif #ifndef MPT_OS_MACOSX_OR_IOS #define MPT_OS_MACOSX_OR_IOS 0 #endif #ifndef MPT_OS_ANDROID #define MPT_OS_ANDROID 0 #endif #ifndef MPT_OS_LINUX #define MPT_OS_LINUX 0 #endif #ifndef MPT_OS_DRAGONFLYBSD #define MPT_OS_DRAGONFLYBSD 0 #endif #ifndef MPT_OS_FREEBSD #define MPT_OS_FREEBSD 0 #endif #ifndef MPT_OS_OPENBSD #define MPT_OS_OPENBSD 0 #endif #ifndef MPT_OS_NETBSD #define MPT_OS_NETBSD 0 #endif #ifndef MPT_OS_GENERIC_UNIX #define MPT_OS_GENERIC_UNIX 0 #endif #ifndef MPT_OS_UNKNOWN #define MPT_OS_UNKNOWN 0 #endif #ifndef MPT_OS_EMSCRIPTEN_ANCIENT #define MPT_OS_EMSCRIPTEN_ANCIENT 0 #endif #if MPT_OS_EMSCRIPTEN #undef MPT_PLATFORM_MULTITHREADED #define MPT_PLATFORM_MULTITHREADED 0 #endif libopenmpt-0.3.6+release.autotools/common/FileReaderFwd.h0000644000372100037210000000153013070471755020372 00000000000000/* * FileReaderFwd.h * --------------- * Purpose: Forward declaration for class FileReader. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "typedefs.h" OPENMPT_NAMESPACE_BEGIN class FileReaderTraitsMemory; #if defined(MPT_FILEREADER_STD_ISTREAM) class FileReaderTraitsStdStream; typedef FileReaderTraitsStdStream FileReaderTraitsDefault; #else // !MPT_FILEREADER_STD_ISTREAM typedef FileReaderTraitsMemory FileReaderTraitsDefault; #endif // MPT_FILEREADER_STD_ISTREAM namespace detail { template class FileReader; } // namespace detail typedef detail::FileReader FileReader; typedef detail::FileReader MemoryFileReader; OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/Profiler.cpp0000644000372100037210000000704613130377246020051 00000000000000/* * Profiler.cpp * ------------ * Purpose: Performance measuring * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Profiler.h" OPENMPT_NAMESPACE_BEGIN #ifdef USE_PROFILER class Statistics { public: Profile &profile; Profile::Data data; double usage; Statistics(Profile &p) : profile(p) { usage = 0.0; Update(); } void Update() { data = profile.GetAndResetData(); uint64 now = profile.GetTime(); uint64 timewindow = now - data.Start; if(data.Calls > 0 && timewindow > 0) { usage = (double)data.Sum / (double)timewindow; } else { usage = 0.0; } } }; struct ProfileBlock { class Profile * profile; const char * name; class Statistics * stats; }; static const std::size_t MAX_PROFILES = 1024; static ProfileBlock Profiles[ MAX_PROFILES ]; static std::size_t NextProfile = 0; static void RegisterProfile(Profile *newprofile) { if(NextProfile < MAX_PROFILES) { Profiles[NextProfile].profile = newprofile; Profiles[NextProfile].stats = 0; NextProfile++; } } static void UnregisterProfile(Profile *oldprofile) { for(std::size_t i=0; iUpdate(); } } } std::string Profiler::DumpProfiles() { std::string ret; for(std::size_t i=0; i Profiler::DumpCategories() { std::vector ret; ret.resize(Profiler::CategoriesCount); for(std::size_t i=0; iCategory] += Profiles[i].stats->usage; } } return ret; } uint64 Profile::GetTime() const { LARGE_INTEGER ret; ret.QuadPart = 0; QueryPerformanceCounter(&ret); return ret.QuadPart; } uint64 Profile::GetFrequency() const { LARGE_INTEGER ret; ret.QuadPart = 0; QueryPerformanceFrequency(&ret); return ret.QuadPart; } Profile::Profile(Profiler::Category category, const char *name) : Category(category), Name(name) { data.Calls = 0; data.Sum = 0; data.Overhead = 0; data.Start = GetTime(); EnterTime = 0; RegisterProfile(this); } Profile::~Profile() { UnregisterProfile(this); } Profile::Data Profile::GetAndResetData() { Profile::Data ret; datamutex.lock(); ret = data; data.Calls = 0; data.Sum = 0; data.Overhead = 0; data.Start = GetTime(); datamutex.unlock(); return ret; } void Profile::Reset() { datamutex.lock(); data.Calls = 0; data.Sum = 0; data.Overhead = 0; data.Start = GetTime(); datamutex.unlock(); } void Profile::Enter() { EnterTime = GetTime(); } void Profile::Leave() { uint64 LeaveTime = GetTime(); datamutex.lock(); data.Calls += 1; data.Sum += LeaveTime - EnterTime; datamutex.unlock(); } #else // !USE_PROFILER MPT_MSVC_WORKAROUND_LNK4221(Profiler) #endif // USE_PROFILER OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/version.cpp0000644000372100037210000005120513222361677017753 00000000000000/* * version.cpp * ----------- * Purpose: OpenMPT version handling. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "version.h" #include "mptString.h" #include "mptStringFormat.h" #include "mptStringParse.h" #include "versionNumber.h" #include "svn_version.h" OPENMPT_NAMESPACE_BEGIN namespace MptVersion { static_assert((MPT_VERSION_NUMERIC & 0xffff) != 0x0000, "Version numbers ending in .00.00 shall never exist again, as they make interpreting the version number ambiguous for file formats which can only store the two major parts of the version number (e.g. IT and S3M)."); const VersionNum num = MPT_VERSION_NUMERIC; const char * const str = MPT_VERSION_STR; std::string GetOpenMPTVersionStr() { return std::string("OpenMPT " MPT_VERSION_STR); } VersionNum ToNum(const std::string &s) { VersionNum result = 0; std::vector numbers = mpt::String::Split(s, std::string(".")); for(std::size_t i = 0; i < numbers.size() && i < 4; ++i) { result |= (mpt::String::Parse::Hex(numbers[i]) & 0xff) << ((3-i)*8); } return result; } std::string ToStr(const VersionNum v) { if(v == 0) { // Unknown version return "Unknown"; } else if((v & 0xFFFF) == 0) { // Only parts of the version number are known (e.g. when reading the version from the IT or S3M file header) return mpt::format("%1.%2")(mpt::fmt::HEX((v >> 24) & 0xFF), mpt::fmt::HEX0<2>((v >> 16) & 0xFF)); } else { // Full version info available return mpt::format("%1.%2.%3.%4")(mpt::fmt::HEX((v >> 24) & 0xFF), mpt::fmt::HEX0<2>((v >> 16) & 0xFF), mpt::fmt::HEX0<2>((v >> 8) & 0xFF), mpt::fmt::HEX0<2>((v) & 0xFF)); } } mpt::ustring ToUString(const VersionNum v) { if(v == 0) { // Unknown version return MPT_USTRING("Unknown"); } else if((v & 0xFFFF) == 0) { // Only parts of the version number are known (e.g. when reading the version from the IT or S3M file header) return mpt::format(MPT_USTRING("%1.%2"))(mpt::ufmt::HEX((v >> 24) & 0xFF), mpt::ufmt::HEX0<2>((v >> 16) & 0xFF)); } else { // Full version info available return mpt::format(MPT_USTRING("%1.%2.%3.%4"))(mpt::ufmt::HEX((v >> 24) & 0xFF), mpt::ufmt::HEX0<2>((v >> 16) & 0xFF), mpt::ufmt::HEX0<2>((v >> 8) & 0xFF), mpt::ufmt::HEX0<2>((v) & 0xFF)); } } VersionNum RemoveBuildNumber(const VersionNum num_) { return (num_ & 0xFFFFFF00); } bool IsTestBuild(const VersionNum num_) { return ( // Legacy (num_ > MAKE_VERSION_NUMERIC(1,17,02,54) && num_ < MAKE_VERSION_NUMERIC(1,18,02,00) && num_ != MAKE_VERSION_NUMERIC(1,18,00,00)) || // Test builds have non-zero VER_MINORMINOR (num_ > MAKE_VERSION_NUMERIC(1,18,02,00) && RemoveBuildNumber(num_) != num_) ); } bool IsDebugBuild() { #ifdef _DEBUG return true; #else return false; #endif } static std::string GetUrl() { #ifdef OPENMPT_VERSION_URL return OPENMPT_VERSION_URL; #else return ""; #endif } static int GetRevision() { #if defined(OPENMPT_VERSION_REVISION) return OPENMPT_VERSION_REVISION; #elif defined(OPENMPT_VERSION_SVNVERSION) std::string svnversion = OPENMPT_VERSION_SVNVERSION; if(svnversion.length() == 0) { return 0; } if(svnversion.find(":") != std::string::npos) { svnversion = svnversion.substr(svnversion.find(":") + 1); } if(svnversion.find("-") != std::string::npos) { svnversion = svnversion.substr(svnversion.find("-") + 1); } if(svnversion.find("M") != std::string::npos) { svnversion = svnversion.substr(0, svnversion.find("M")); } if(svnversion.find("S") != std::string::npos) { svnversion = svnversion.substr(0, svnversion.find("S")); } if(svnversion.find("P") != std::string::npos) { svnversion = svnversion.substr(0, svnversion.find("P")); } return ConvertStrTo(svnversion); #else #if MPT_COMPILER_MSVC #pragma message("SVN revision unknown. Please check your build system.") #elif MPT_COMPILER_GCC || MPT_COMPILER_CLANG || MPT_COMPILER_MSVCCLANGC2 #warning "SVN revision unknown. Please check your build system." #else // There is no portable way to display a warning. // Try to provoke a warning with an unused variable. int SVN_revision_unknown__Please_check_your_build_system; #endif return 0; #endif } static bool IsDirty() { #if defined(OPENMPT_VERSION_DIRTY) return OPENMPT_VERSION_DIRTY != 0; #elif defined(OPENMPT_VERSION_SVNVERSION) std::string svnversion = OPENMPT_VERSION_SVNVERSION; if(svnversion.length() == 0) { return false; } if(svnversion.find("M") != std::string::npos) { return true; } return false; #else return false; #endif } static bool HasMixedRevisions() { #if defined(OPENMPT_VERSION_MIXEDREVISIONS) return OPENMPT_VERSION_MIXEDREVISIONS != 0; #elif defined(OPENMPT_VERSION_SVNVERSION) std::string svnversion = OPENMPT_VERSION_SVNVERSION; if(svnversion.length() == 0) { return false; } if(svnversion.find(":") != std::string::npos) { return true; } if(svnversion.find("-") != std::string::npos) { return true; } if(svnversion.find("S") != std::string::npos) { return true; } if(svnversion.find("P") != std::string::npos) { return true; } return false; #else return false; #endif } static bool IsPackage() { #if defined(OPENMPT_VERSION_IS_PACKAGE) return OPENMPT_VERSION_IS_PACKAGE != 0; #else return false; #endif } static std::string GetSourceDate() { #if defined(OPENMPT_VERSION_DATE) return OPENMPT_VERSION_DATE; #else return ""; #endif } SourceInfo GetSourceInfo() { SourceInfo result; result.Url = GetUrl(); result.Revision = GetRevision(); result.IsDirty = IsDirty(); result.HasMixedRevisions = HasMixedRevisions(); result.IsPackage = IsPackage(); result.Date = GetSourceDate(); return result; } std::string SourceInfo::GetStateString() const { std::string retval; if(IsDirty) { retval += "+dirty"; } if(HasMixedRevisions) { retval += "+mixed"; } if(retval.empty()) { retval += "clean"; } if(IsPackage) { retval += "-pkg"; } return retval; } std::string GetBuildDateString() { #ifdef MODPLUG_TRACKER #if defined(OPENMPT_BUILD_DATE) return OPENMPT_BUILD_DATE; #else return __DATE__ " " __TIME__ ; #endif #else // !MODPLUG_TRACKER return GetSourceInfo().Date; #endif // MODPLUG_TRACKER } static std::string GetBuildFlagsString() { std::string retval; #ifdef MODPLUG_TRACKER if(IsTestBuild()) { retval += " TEST"; } #endif // MODPLUG_TRACKER if(IsDebugBuild()) { retval += " DEBUG"; } return retval; } std::string GetBuildFeaturesString() { std::string retval; #ifdef LIBOPENMPT_BUILD #if defined(MPT_CHARSET_WIN32) retval += " +WINAPI"; #endif #if defined(MPT_CHARSET_ICONV) retval += " +ICONV"; #endif #if defined(MPT_CHARSET_CODECVTUTF8) retval += " +CODECVTUTF8"; #endif #if defined(MPT_CHARSET_INTERNAL) retval += " +INTERNALCHARSETS"; #endif #if defined(MPT_WITH_ZLIB) retval += " +ZLIB"; #endif #if defined(MPT_WITH_MINIZ) retval += " +MINIZ"; #endif #if !defined(MPT_WITH_ZLIB) && !defined(MPT_WITH_MINIZ) retval += " -INFLATE"; #endif #if defined(MPT_WITH_MPG123) retval += " +MPG123"; #endif #if defined(MPT_WITH_MINIMP3) retval += " +MINIMP3"; #endif #if defined(MPT_WITH_MEDIAFOUNDATION) retval += " +MF"; #endif #if !defined(MPT_WITH_MPG123) && !defined(MPT_WITH_MINIMP3) && !defined(MPT_WITH_MEDIAFOUNDATION) retval += " -MP3"; #endif #if defined(MPT_WITH_OGG) && defined(MPT_WITH_VORBIS) && defined(MPT_WITH_VORBISFILE) retval += " +VORBIS"; #endif #if defined(MPT_WITH_STBVORBIS) retval += " +STBVORBIS"; #endif #if !(defined(MPT_WITH_OGG) && defined(MPT_WITH_VORBIS) && defined(MPT_WITH_VORBISFILE)) && !defined(MPT_WITH_STBVORBIS) retval += " -VORBIS"; #endif #if !defined(NO_PLUGINS) retval += " +PLUGINS"; #else retval += " -PLUGINS"; #endif #if !defined(NO_DMO) retval += " +DMO"; #endif #endif #ifdef MODPLUG_TRACKER #if (MPT_ARCH_BITS == 64) if (true && (mpt::Windows::Version::GetMinimumKernelLevel() <= mpt::Windows::Version::WinXP64) && (mpt::Windows::Version::GetMinimumAPILevel() <= mpt::Windows::Version::WinXP64) ) { retval += " WIN64OLD"; } #elif (MPT_ARCH_BITS == 32) if (true && (mpt::Windows::Version::GetMinimumKernelLevel() <= mpt::Windows::Version::WinXP) && (mpt::Windows::Version::GetMinimumAPILevel() <= mpt::Windows::Version::WinXP) ) { retval += " WIN32OLD"; } #endif #if defined(UNICODE) retval += " UNICODE"; #else retval += " ANSI"; #endif #ifdef NO_VST retval += " NO_VST"; #endif #ifdef NO_DMO retval += " NO_DMO"; #endif #ifdef NO_PLUGINS retval += " NO_PLUGINS"; #endif #ifndef MPT_WITH_ASIO retval += " NO_ASIO"; #endif #ifndef MPT_WITH_DSOUND retval += " NO_DSOUND"; #endif #endif return retval; } std::string GetBuildCompilerString() { std::string retval; #if MPT_COMPILER_GENERIC retval += "*Generic C++11 Compiler"; #elif MPT_COMPILER_MSVC #if defined(_MSC_FULL_VER) && defined(_MSC_BUILD) && (_MSC_BUILD > 0) retval += mpt::format("Microsoft Compiler %1.%2.%3.%4") ( _MSC_FULL_VER / 10000000 , mpt::fmt::dec0<2>((_MSC_FULL_VER / 100000) % 100) , mpt::fmt::dec0<5>(_MSC_FULL_VER % 100000) , mpt::fmt::dec0<2>(_MSC_BUILD) ); #elif defined(_MSC_FULL_VER) retval += mpt::format("Microsoft Compiler %1.%2.%3") ( _MSC_FULL_VER / 10000000 , mpt::fmt::dec0<2>((_MSC_FULL_VER / 100000) % 100) , mpt::fmt::dec0<5>(_MSC_FULL_VER % 100000) ); #else retval += mpt::format("Microsoft Compiler %1.%2")(MPT_COMPILER_MSVC_VERSION / 100, MPT_COMPILER_MSVC_VERSION % 100); #endif #elif MPT_COMPILER_GCC retval += mpt::format("GNU Compiler Collection %1.%2.%3")(MPT_COMPILER_GCC_VERSION / 10000, (MPT_COMPILER_GCC_VERSION / 100) % 100, MPT_COMPILER_GCC_VERSION % 100); #elif MPT_COMPILER_CLANG retval += mpt::format("Clang %1.%2.%3")(MPT_COMPILER_CLANG_VERSION / 10000, (MPT_COMPILER_CLANG_VERSION / 100) % 100, MPT_COMPILER_CLANG_VERSION % 100); #elif MPT_COMPILER_MSVCCLANGC2 retval += mpt::format("MSVC-Clang/C2 %1")(MPT_COMPILER_MSVCCLANGC2_VERSION); #else retval += "*unknown"; #endif return retval; } static std::string GetRevisionString() { std::string result; if(GetRevision() == 0) { return result; } result = std::string("-r") + mpt::fmt::val(GetRevision()); if(HasMixedRevisions()) { result += "!"; } if(IsDirty()) { result += "+"; } if(IsPackage()) { result += "p"; } return result; } mpt::ustring GetDownloadURL() { #ifdef MODPLUG_TRACKER return (MptVersion::IsDebugBuild() || MptVersion::IsTestBuild() || MptVersion::IsDirty() || MptVersion::HasMixedRevisions()) ? MPT_USTRING("https://buildbot.openmpt.org/builds/") : MPT_USTRING("https://openmpt.org/download") ; #else return MPT_USTRING("https://lib.openmpt.org/"); #endif } std::string GetVersionString(FlagSet strings) { std::vector result; if(strings[StringVersion]) { result.push_back(MPT_VERSION_STR); } if(strings[StringRevision]) { if(IsDebugBuild() || IsTestBuild() || IsDirty() || HasMixedRevisions()) { result.push_back(GetRevisionString()); } } if(strings[StringBitness]) { result.push_back(mpt::format(" %1 bit")(sizeof(void*)*8)); } if(strings[StringSourceInfo]) { const SourceInfo sourceInfo = GetSourceInfo(); if(!sourceInfo.GetUrlWithRevision().empty()) { result.push_back(mpt::format(" %1")(sourceInfo.GetUrlWithRevision())); } if(!sourceInfo.Date.empty()) { result.push_back(mpt::format(" (%1)")(sourceInfo.Date)); } if(!sourceInfo.GetStateString().empty()) { result.push_back(mpt::format(" %1")(sourceInfo.GetStateString())); } } if(strings[StringBuildFlags]) { if(IsDebugBuild() || IsTestBuild() || IsDirty() || HasMixedRevisions()) { result.push_back(GetBuildFlagsString()); } } if(strings[StringBuildFeatures]) { result.push_back(GetBuildFeaturesString()); } return mpt::String::Trim(mpt::String::Combine(result, std::string(""))); } std::string GetVersionStringPure() { FlagSet strings; strings |= MptVersion::StringVersion; strings |= MptVersion::StringRevision; #ifdef MODPLUG_TRACKER strings |= MptVersion::StringBitness; #endif return GetVersionString(strings); } std::string GetVersionStringSimple() { FlagSet strings; strings |= MptVersion::StringVersion; strings |= MptVersion::StringRevision; strings |= MptVersion::StringBuildFlags; return GetVersionString(strings); } std::string GetVersionStringExtended() { FlagSet strings; strings |= MptVersion::StringVersion; strings |= MptVersion::StringRevision; #ifdef MODPLUG_TRACKER strings |= MptVersion::StringBitness; #endif #ifndef MODPLUG_TRACKER strings |= MptVersion::StringSourceInfo; #endif strings |= MptVersion::StringBuildFlags; #ifdef MODPLUG_TRACKER strings |= MptVersion::StringBuildFeatures; #endif return GetVersionString(strings); } std::string SourceInfo::GetUrlWithRevision() const { if(Url.empty() || (Revision == 0)) { return std::string(); } return Url + "@" + mpt::fmt::val(Revision); } mpt::ustring GetURL(std::string key) { mpt::ustring result; if(key.empty()) { result = mpt::ustring(); } else if(key == "website") { #ifdef LIBOPENMPT_BUILD result = MPT_USTRING("https://lib.openmpt.org/"); #else result = MPT_USTRING("https://openmpt.org/"); #endif } else if(key == "forum") { result = MPT_USTRING("https://forum.openmpt.org/"); } else if(key == "bugtracker") { result = MPT_USTRING("https://bugs.openmpt.org/"); } else if(key == "updates") { result = MPT_USTRING("https://openmpt.org/download"); } else if(key == "top_picks") { result = MPT_USTRING("https://openmpt.org/top_picks"); } return result; } mpt::ustring GetFullCreditsString() { return mpt::ToUnicode(mpt::CharsetUTF8, #ifdef MODPLUG_TRACKER "OpenMPT / ModPlug Tracker\n" #else "libopenmpt (based on OpenMPT / ModPlug Tracker)\n" #endif "\n" "Copyright \xC2\xA9 2004-2018 Contributors\n" "Copyright \xC2\xA9 1997-2003 Olivier Lapicque\n" "\n" "Contributors:\n" "Johannes Schultz (2008-2018)\n" "J\xC3\xB6rn Heusipp (2012-2018)\n" "Ahti Lepp\xC3\xA4nen (2005-2011)\n" "Robin Fernandes (2004-2007)\n" "Sergiy Pylypenko (2007)\n" "Eric Chavanon (2004-2005)\n" "Trevor Nunes (2004)\n" "Olivier Lapicque (1997-2003)\n" "\n" "Additional patch submitters:\n" "coda (http://coda.s3m.us/)\n" "kode54 (https://kode54.net/)\n" "Revenant (http://revenant1.net/)\n" "xaimus (http://xaimus.com/)\n" "\n" "Thanks to:\n" "\n" "Konstanty for the XMMS-ModPlug resampling implementation\n" "http://modplug-xmms.sourceforge.net/\n" "\n" #ifdef MODPLUG_TRACKER "Stephan M. Bernsee for pitch shifting source code\n" "http://www.dspdimension.com/\n" "\n" "Aleksey Vaneev of Voxengo for r8brain sample rate converter\n" "https://github.com/avaneev/r8brain-free-src\n" "\n" "Olli Parviainen for SoundTouch Library (time stretching)\n" "http://www.surina.net/soundtouch/\n" "\n" #endif #ifndef NO_VST "Hermann Seib for his example VST Host implementation\n" "http://www.hermannseib.com/english/vsthost.htm\n" "\n" #endif "Laurent Cl\xc3\xA9vy for unofficial MO3 documentation and decompression code\n" "https://github.com/lclevy/unmo3\n" "\n" "Ben \"GreaseMonkey\" Russell for IT sample compression code\n" "https://github.com/iamgreaser/it2everything/\n" "\n" "Antti S. Lankila for Amiga resampler implementation\n" "https://bel.fi/alankila/modguide/interpolate.txt\n" "\n" #ifdef MPT_WITH_ZLIB "Jean-loup Gailly and Mark Adler for zlib\n" "http://zlib.net/\n" "\n" #endif #ifdef MPT_WITH_MINIZ "Rich Geldreich et al. for miniz\n" "https://github.com/richgel999/miniz\n" "\n" #endif #ifdef MPT_WITH_LHASA "Simon Howard for lhasa\n" "https://fragglet.github.io/lhasa/\n" "\n" #endif #ifdef MPT_WITH_UNRAR "Alexander L. Roshal for UnRAR\n" "http://rarlab.com/\n" "\n" #endif #ifdef MPT_WITH_PORTAUDIO "PortAudio contributors\n" "http://www.portaudio.com/\n" "\n" #endif #ifdef MPT_WITH_FLAC "Josh Coalson / Xiph.Org Foundation for libFLAC\n" "https://xiph.org/flac/\n" "\n" #endif #if defined(MPT_WITH_MPG123) "The mpg123 project for libmpg123\n" "http://mpg123.de/\n" "\n" #endif #ifdef MPT_WITH_MINIMP3 "Fabrice Bellard, FFMPEG contributors\n" "and Martin J. Fiedler (KeyJ/kakiarts) for minimp3\n" "http://keyj.emphy.de/minimp3/\n" "\n" #endif #ifdef MPT_WITH_STBVORBIS "Sean Barrett for stb_vorbis\n" "https://github.com/nothings/stb/\n" "\n" #endif #ifdef MPT_WITH_OGG "Xiph.Org Foundation for libogg\n" "https://xiph.org/ogg/\n" "\n" #endif #if defined(MPT_WITH_VORBIS) || defined(MPT_WITH_LIBVORBISFILE) "Xiph.Org Foundation for libvorbis\n" "https://xiph.org/vorbis/\n" "\n" #endif #if defined(MPT_WITH_OPUS) "Xiph.Org, Skype Limited, Octasic, Jean-Marc Valin, Timothy B. Terriberry,\n" "CSIRO, Gregory Maxwell, Mark Borgerding, Erik de Castro Lopo,\n" "Xiph.Org Foundation, Microsoft Corporation, Broadcom Corporation for libopus\n" "https://opus-codec.org/\n" "\n" #endif #if defined(MPT_WITH_OPUSFILE) "Xiph.Org Foundation and contributors for libopusfile\n" "https://opus-codec.org/\n" "\n" #endif #if defined(MPT_WITH_OPUSENC) "Xiph.Org Foundation, Jean-Marc Valin and contributors for libopusenc\n" "https://git.xiph.org/?p=libopusenc.git;a=summary\n" "\n" #endif #if defined(MPT_WITH_PICOJSON) "Cybozu Labs Inc. and Kazuho Oku et. al. for picojson\n" "https://github.com/kazuho/picojson\n" "\n" #endif "Storlek for all the IT compatibility hints and testcases\n" "as well as the IMF, MDL, OKT and ULT loaders\n" "http://schismtracker.org/\n" "\n" #ifdef MODPLUG_TRACKER "Lennart Poettering and David Henningsson for RealtimeKit\n" "http://git.0pointer.net/rtkit.git/\n" "\n" "Gary P. Scavone for RtMidi\n" "https://www.music.mcgill.ca/~gary/rtmidi/\n" "\n" "Alexander Uckun for decimal input field\n" "http://www.codeproject.com/Articles/21257/_\n" "\n" "Nobuyuki for application and file icon\n" "https://twitter.com/nobuyukinyuu\n" "\n" #endif "Daniel Collin (emoon/TBL) for providing test infrastructure\n" "https://twitter.com/daniel_collin\n" "\n" "The people at ModPlug forums for crucial contribution\n" "in the form of ideas, testing and support;\n" "thanks particularly to:\n" "33, 8bitbubsy, Anboi, BooT-SectoR-ViruZ, Bvanoudtshoorn\n" "christofori, cubaxd, Diamond, Ganja, Georg, Goor00,\n" "Harbinger, jmkz, KrazyKatz, LPChip, Nofold, Rakib, Sam Zen\n" "Skaven, Skilletaudio, Snu, Squirrel Havoc, Waxhead\n" "\n" #ifndef NO_VST "VST PlugIn Technology by Steinberg Media Technologies GmbH\n" "\n" #endif #ifdef MPT_WITH_ASIO "ASIO Technology by Steinberg Media Technologies GmbH\n" "\n" #endif ); } mpt::ustring GetLicenseString() { return MPT_UTF8( "The OpenMPT code is licensed under the BSD license." "\n" "" "\n" "Copyright (c) 2004-2018, OpenMPT contributors" "\n" "Copyright (c) 1997-2003, Olivier Lapicque" "\n" "All rights reserved." "\n" "" "\n" "Redistribution and use in source and binary forms, with or without" "\n" "modification, are permitted provided that the following conditions are met:" "\n" " * Redistributions of source code must retain the above copyright" "\n" " notice, this list of conditions and the following disclaimer." "\n" " * Redistributions in binary form must reproduce the above copyright" "\n" " notice, this list of conditions and the following disclaimer in the" "\n" " documentation and/or other materials provided with the distribution." "\n" " * Neither the name of the OpenMPT project nor the" "\n" " names of its contributors may be used to endorse or promote products" "\n" " derived from this software without specific prior written permission." "\n" "" "\n" "THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY" "\n" "EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED" "\n" "WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE" "\n" "DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY" "\n" "DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES" "\n" "(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;" "\n" "LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND" "\n" "ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT" "\n" "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS" "\n" "SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." "\n" ); } } // namespace MptVersion OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/ComponentManager.h0000644000372100037210000002515713076654045021200 00000000000000/* * ComponentManager.h * ------------------ * Purpose: Manages loading of optional components. * Notes : (currently none) * Authors: Joern Heusipp * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include #include #include "../common/misc_util.h" #include "../common/mptMutex.h" OPENMPT_NAMESPACE_BEGIN #define MPT_ENABLE_COMPONENTS #if defined(MPT_ENABLE_COMPONENTS) #if defined(MODPLUG_TRACKER) #define MPT_COMPONENT_MANAGER 1 #else #define MPT_COMPONENT_MANAGER 0 #endif enum ComponentType { ComponentTypeUnknown = 0, ComponentTypeBuiltin, // PortAudio ComponentTypeSystem, // mf.dll ComponentTypeSystemInstallable, // acm mp3 codec ComponentTypeBundled, // libsoundtouch ComponentTypeForeign, // libmp3lame }; class ComponentFactoryBase; class IComponent { friend class ComponentFactoryBase; protected: IComponent() { } public: virtual ~IComponent() { } public: virtual ComponentType GetType() const = 0; virtual bool IsInitialized() const = 0; // Initialize() has been called virtual bool IsAvailable() const = 0; // Initialize() has been successfull virtual mpt::ustring GetVersion() const = 0; virtual void Initialize() = 0; // try to load the component }; class ComponentBase : public IComponent { private: ComponentType m_Type; bool m_Initialized; bool m_Available; protected: ComponentBase(ComponentType type); public: virtual ~ComponentBase(); protected: void SetInitialized(); void SetAvailable(); public: virtual ComponentType GetType() const; virtual bool IsInitialized() const; virtual bool IsAvailable() const; virtual mpt::ustring GetVersion() const; public: virtual void Initialize(); protected: virtual bool DoInitialize() = 0; }; class ComponentBuiltin : public ComponentBase { public: ComponentBuiltin() : ComponentBase(ComponentTypeBuiltin) { return; } virtual bool DoInitialize() { return true; } }; #define MPT_GLOBAL_BIND(lib, name) name = &::name; #if defined(MPT_ENABLE_DYNBIND) class ComponentLibrary : public ComponentBase { private: typedef std::map TLibraryMap; TLibraryMap m_Libraries; bool m_BindFailed; protected: ComponentLibrary(ComponentType type); public: virtual ~ComponentLibrary(); protected: bool AddLibrary(const std::string &libName, const mpt::LibraryPath &libPath); void ClearLibraries(); void SetBindFailed(); void ClearBindFailed(); bool HasBindFailed() const; public: virtual mpt::Library GetLibrary(const std::string &libName) const; template bool Bind(Tfunc * & f, const std::string &libName, const std::string &symbol) const { return GetLibrary(libName).Bind(f, symbol); } protected: virtual bool DoInitialize() = 0; }; #define MPT_COMPONENT_BIND(libName, func) MPT_DO { if(!Bind( func , libName , #func )) { SetBindFailed(); } } MPT_WHILE_0 #define MPT_COMPONENT_BIND_OPTIONAL(libName, func) Bind( func , libName , #func ) #define MPT_COMPONENT_BIND_SYMBOL(libName, symbol, func) MPT_DO { if(!Bind( func , libName , symbol )) { SetBindFailed(); } } MPT_WHILE_0 #define MPT_COMPONENT_BIND_SYMBOL_OPTIONAL(libName, symbol, func) Bind( func , libName , symbol ) class ComponentSystemDLL : public ComponentLibrary { private: mpt::PathString m_BaseName; public: ComponentSystemDLL(const mpt::PathString &baseName) : ComponentLibrary(ComponentTypeSystem) , m_BaseName(baseName) { return; } virtual bool DoInitialize() { AddLibrary(m_BaseName.ToUTF8(), mpt::LibraryPath::System(m_BaseName)); return GetLibrary(m_BaseName.ToUTF8()).IsValid(); } }; class ComponentBundledDLL : public ComponentLibrary { private: mpt::PathString m_FullName; public: ComponentBundledDLL(const mpt::PathString &fullName) : ComponentLibrary(ComponentTypeBundled) , m_FullName(fullName) { return; } virtual bool DoInitialize() { AddLibrary(m_FullName.ToUTF8(), mpt::LibraryPath::AppFullName(m_FullName)); return GetLibrary(m_FullName.ToUTF8()).IsValid(); } }; #endif // MPT_ENABLE_DYNBIND #if MPT_COMPONENT_MANAGER class ComponentManager; typedef std::shared_ptr (*ComponentFactoryMethod)(ComponentManager &componentManager); class IComponentFactory { protected: IComponentFactory() { } public: virtual ~IComponentFactory() { } public: virtual std::string GetID() const = 0; virtual std::string GetSettingsKey() const = 0; virtual std::shared_ptr Construct(ComponentManager &componentManager) const = 0; virtual ComponentFactoryMethod GetStaticConstructor() const = 0; }; class ComponentFactoryBase : public IComponentFactory { private: std::string m_ID; std::string m_SettingsKey; protected: ComponentFactoryBase(const std::string &id, const std::string &settingsKey); void PreConstruct() const; void Initialize(ComponentManager &componentManager, std::shared_ptr component) const; public: virtual ~ComponentFactoryBase(); virtual std::string GetID() const; virtual std::string GetSettingsKey() const; virtual std::shared_ptr Construct(ComponentManager &componentManager) const = 0; virtual ComponentFactoryMethod GetStaticConstructor() const = 0; }; template class ComponentFactory : public ComponentFactoryBase { public: ComponentFactory() : ComponentFactoryBase(T::g_ID, T::g_SettingsKey) { return; } virtual ~ComponentFactory() { return; } public: virtual std::shared_ptr Construct(ComponentManager &componentManager) const { PreConstruct(); std::shared_ptr component = std::make_shared(); Initialize(componentManager, component); return component; } static std::shared_ptr StaticConstruct(ComponentManager &componentManager) { return ComponentFactory().Construct(componentManager); } virtual ComponentFactoryMethod GetStaticConstructor() const { return &StaticConstruct; } }; class IComponentManagerSettings { public: virtual bool LoadOnStartup() const = 0; virtual bool KeepLoaded() const = 0; virtual bool IsBlocked(const std::string &key) const = 0; virtual mpt::PathString Path() const = 0; }; class ComponentManagerSettingsDefault : public IComponentManagerSettings { public: virtual bool LoadOnStartup() const { return false; } virtual bool KeepLoaded() const { return true; } virtual bool IsBlocked(const std::string & /*key*/ ) const { return false; } virtual mpt::PathString Path() const { return mpt::PathString(); } }; enum ComponentState { ComponentStateUnregistered, ComponentStateBlocked, ComponentStateUnintialized, ComponentStateUnavailable, ComponentStateAvailable, }; struct ComponentInfo { std::string name; ComponentState state; std::string settingsKey; ComponentType type; }; class ComponentManager { friend class ComponentFactoryBase; public: static void Init(const IComponentManagerSettings &settings); static void Release(); static std::shared_ptr Instance(); private: ComponentManager(const IComponentManagerSettings &settings); private: struct RegisteredComponent { std::string settingsKey; ComponentFactoryMethod factoryMethod; std::shared_ptr instance; std::weak_ptr weakInstance; }; typedef std::map TComponentMap; const IComponentManagerSettings &m_Settings; TComponentMap m_Components; private: bool IsComponentBlocked(const std::string &settingsKey) const; void InitializeComponent(std::shared_ptr component) const; public: void Register(const IComponentFactory &componentFactory); void Startup(); std::shared_ptr GetComponent(const IComponentFactory &componentFactory); std::shared_ptr ReloadComponent(const IComponentFactory &componentFactory); std::vector GetRegisteredComponents() const; ComponentInfo GetComponentInfo(std::string name) const; mpt::PathString GetComponentPath() const; }; struct ComponentListEntry { ComponentListEntry *next; void (*reg)(ComponentManager &componentManager); }; bool ComponentListPush(ComponentListEntry *entry); #define MPT_DECLARE_COMPONENT_MEMBERS public: static const char * const g_ID; static const char * const g_SettingsKey; #define MPT_REGISTERED_COMPONENT(name, settingsKey) \ static void RegisterComponent ## name (ComponentManager &componentManager) \ { \ componentManager.Register(ComponentFactory< name >()); \ } \ static ComponentListEntry Component ## name ## ListEntry = { nullptr, & RegisterComponent ## name }; \ bool Component ## name ## Registered = ComponentListPush(& Component ## name ## ListEntry ); \ const char * const name :: g_ID = #name ; \ const char * const name :: g_SettingsKey = settingsKey ; \ /**/ template std::shared_ptr GetComponent() { return std::dynamic_pointer_cast(ComponentManager::Instance()->GetComponent(ComponentFactory())); } template std::shared_ptr ReloadComponent() { return std::dynamic_pointer_cast(ComponentManager::Instance()->ReloadComponent(ComponentFactory())); } static inline mpt::PathString GetComponentPath() { return ComponentManager::Instance()->GetComponentPath(); } #else // !MPT_COMPONENT_MANAGER #define MPT_DECLARE_COMPONENT_MEMBERS #define MPT_REGISTERED_COMPONENT(name, settingsKey) template std::shared_ptr GetComponent() { static std::weak_ptr cache; static mpt::mutex m; MPT_LOCK_GUARD l(m); std::shared_ptr component = cache.lock(); if(!component) { component = std::make_shared(); component->Initialize(); cache = component; } return component; } static inline mpt::PathString GetComponentPath() { return mpt::PathString(); } #endif // MPT_COMPONENT_MANAGER // Simple wrapper around std::shared_ptr which automatically // gets a reference to the component (or constructs it) on initialization. template class ComponentHandle { private: std::shared_ptr component; public: ComponentHandle() : component(GetComponent()) { return; } ~ComponentHandle() { return; } bool IsAvailable() const { return component && component->IsAvailable(); } const T *get() const { return component.get(); } const T &operator*() const { return *component; } const T *operator->() const { return &*component; } #if MPT_COMPONENT_MANAGER void Reload() { component = nullptr; component = ReloadComponent(); } #endif }; template bool IsComponentAvailable(const ComponentHandle &handle) { return handle.IsAvailable(); } #endif // MPT_ENABLE_COMPONENTS OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/mptTime.cpp0000644000372100037210000001341013203374744017677 00000000000000/* * mptTime.cpp * ----------- * Purpose: Various time utility functions. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "mptTime.h" #include #if MPT_OS_WINDOWS #include #if defined(MODPLUG_TRACKER) #include #endif #endif OPENMPT_NAMESPACE_BEGIN namespace mpt { namespace Date { #if defined(MODPLUG_TRACKER) #if MPT_OS_WINDOWS namespace ANSI { uint64 Now() { FILETIME filetime; GetSystemTimeAsFileTime(&filetime); return ((uint64)filetime.dwHighDateTime << 32 | filetime.dwLowDateTime); } mpt::ustring ToString(uint64 time100ns) { static const std::size_t bufsize = 256; mpt::ustring result; FILETIME filetime; SYSTEMTIME systime; filetime.dwHighDateTime = (DWORD)(((uint64)time100ns) >> 32); filetime.dwLowDateTime = (DWORD)((uint64)time100ns); FileTimeToSystemTime(&filetime, &systime); WCHAR buf[bufsize]; GetDateFormatW(LOCALE_SYSTEM_DEFAULT, 0, &systime, L"yyyy-MM-dd", buf, bufsize); result.append(mpt::ToUnicode(buf)); result.append(MPT_USTRING(" ")); GetTimeFormatW(LOCALE_SYSTEM_DEFAULT, TIME_FORCE24HOURFORMAT, &systime, L"HH:mm:ss", buf, bufsize); result.append(mpt::ToUnicode(buf)); result.append(MPT_USTRING(".")); result.append(mpt::ufmt::dec0<3>((unsigned)systime.wMilliseconds)); return result; } } // namespace ANSI #endif // MPT_OS_WINDOWS #endif // MODPLUG_TRACKER Unix::Unix() : Value(0) { return; } Unix::Unix(int64 unixtime) : Value(unixtime) { return; } Unix::operator int64 () const { return Value; } static int32 ToDaynum(int32 year, int32 month, int32 day) { month = (month + 9) % 12; year = year - (month / 10); int32 daynum = year*365 + year/4 - year/100 + year/400 + (month*306 + 5)/10 + (day - 1); return daynum; } static void FromDaynum(int32 d, int32 & year, int32 & month, int32 & day) { int64 g = d; int64 y,ddd,mi,mm,dd; y = (10000*g + 14780)/3652425; ddd = g - (365*y + y/4 - y/100 + y/400); if(ddd < 0) { y = y - 1; ddd = g - (365*y + y/4 - y/100 + y/400); } mi = (100*ddd + 52)/3060; mm = (mi + 2)%12 + 1; y = y + (mi + 2)/12; dd = ddd - (mi*306 + 5)/10 + 1; year = static_cast(y); month = static_cast(mm); day = static_cast(dd); } mpt::Date::Unix Unix::FromUTC(tm timeUtc) { int32 daynum = ToDaynum(timeUtc.tm_year+1900, timeUtc.tm_mon+1, timeUtc.tm_mday); int64 seconds = static_cast(daynum - ToDaynum(1970,1,1))*24*60*60 + timeUtc.tm_hour*60*60 + timeUtc.tm_min*60 + timeUtc.tm_sec; return mpt::Date::Unix(seconds); } tm Unix::AsUTC() const { int64 tmp = Value; int64 seconds = tmp % 60; tmp /= 60; int64 minutes = tmp % 60; tmp /= 60; int64 hours = tmp % 24; tmp /= 24; int32 year = 0, month = 0, day = 0; FromDaynum(static_cast(tmp) + ToDaynum(1970,1,1), year, month, day); tm result; MemsetZero(result); result.tm_year = year - 1900; result.tm_mon = month - 1; result.tm_mday = day; result.tm_hour = static_cast(hours); result.tm_min = static_cast(minutes); result.tm_sec = static_cast(seconds); return result; } mpt::ustring ToShortenedISO8601(tm date) { // We assume date in UTC here. // There are too many differences in supported format specifiers in strftime() // and strftime does not support reduced precision ISO8601 at all. // Just do the formatting ourselves. mpt::ustring result; mpt::ustring tz = MPT_USTRING("Z"); if(date.tm_year == 0) { return result; } result += mpt::ufmt::dec0<4>(date.tm_year + 1900); if(date.tm_mon < 0 || date.tm_mon > 11) { return result; } result += MPT_USTRING("-") + mpt::ufmt::dec0<2>(date.tm_mon + 1); if(date.tm_mday < 1 || date.tm_mday > 31) { return result; } result += MPT_USTRING("-") + mpt::ufmt::dec0<2>(date.tm_mday); if(date.tm_hour == 0 && date.tm_min == 0 && date.tm_sec == 0) { return result; } if(date.tm_hour < 0 || date.tm_hour > 23) { return result; } if(date.tm_min < 0 || date.tm_min > 59) { return result; } result += MPT_USTRING("T"); if(date.tm_isdst > 0) { tz = MPT_USTRING("+01:00"); } result += mpt::ufmt::dec0<2>(date.tm_hour) + MPT_USTRING(":") + mpt::ufmt::dec0<2>(date.tm_min); if(date.tm_sec < 0 || date.tm_sec > 61) { return result + tz; } result += MPT_USTRING(":") + mpt::ufmt::dec0<2>(date.tm_sec); result += tz; return result; } } // namespace Date } // namespace mpt #ifdef MODPLUG_TRACKER namespace Util { #if MPT_OS_WINDOWS void MultimediaClock::Init() { m_CurrentPeriod = 0; } void MultimediaClock::SetPeriod(uint32 ms) { TIMECAPS caps; MemsetZero(caps); if(timeGetDevCaps(&caps, sizeof(caps)) != MMSYSERR_NOERROR) { return; } if((caps.wPeriodMax == 0) || (caps.wPeriodMin > caps.wPeriodMax)) { return; } ms = mpt::clamp(ms, caps.wPeriodMin, caps.wPeriodMax); if(timeBeginPeriod(ms) != MMSYSERR_NOERROR) { return; } m_CurrentPeriod = ms; } void MultimediaClock::Cleanup() { if(m_CurrentPeriod > 0) { if(timeEndPeriod(m_CurrentPeriod) != MMSYSERR_NOERROR) { // should not happen MPT_ASSERT_NOTREACHED(); } m_CurrentPeriod = 0; } } MultimediaClock::MultimediaClock() { Init(); } MultimediaClock::MultimediaClock(uint32 ms) { Init(); SetResolution(ms); } MultimediaClock::~MultimediaClock() { Cleanup(); } uint32 MultimediaClock::SetResolution(uint32 ms) { if(m_CurrentPeriod == ms) { return m_CurrentPeriod; } Cleanup(); if(ms != 0) { SetPeriod(ms); } return GetResolution(); } uint32 MultimediaClock::GetResolution() const { return m_CurrentPeriod; } uint32 MultimediaClock::Now() const { return timeGetTime(); } uint64 MultimediaClock::NowNanoseconds() const { return (uint64)timeGetTime() * (uint64)1000000; } #endif // MPT_OS_WINDOWS } // namespace Util #endif // MODPLUG_TRACKER OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/mptWine.h0000644000372100037210000000615113054514475017355 00000000000000/* * mptWine.h * --------- * Purpose: Wine stuff. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "mptOS.h" #include "FlagSet.h" #include #include #include OPENMPT_NAMESPACE_BEGIN #if defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS namespace mpt { namespace Wine { class Exception : public std::runtime_error { public: Exception(const std::string &text) : std::runtime_error(text) { return; } }; typedef void (*ExecutePosixCommandProgress)(void *userdata); enum ExecuteProgressResult { ExecuteProgressContinueWaiting = 0, ExecuteProgressAsyncCancel = -1, }; typedef ExecuteProgressResult (*ExecutePosixShellScriptProgress)(void *userdata); enum ExecFlags { ExecFlagNone = 0, ExecFlagSilent = 1<<0, // do not show a terminal window ExecFlagInteractive = 1<<1, // allow interaction (prevents stdout and stderr capturing and implies !silent) ExecFlagAsync = 1<<2, // do not wait for the script to finish ExecFlagProgressWindow = 1<<3, // not implemented by mptOS ExecFlagSplitOutput = 1<<4, // split stdout and stderr (implies silent) ExecFlagsDefault = ExecFlagNone }; MPT_DECLARE_ENUM(ExecFlags) struct ExecResult { int exitcode; std::string output; std::string error; std::map > filetree; static ExecResult Error() { ExecResult result; result.exitcode = -1; return result; } }; class Context { protected: mpt::Wine::VersionContext m_VersionContext; mpt::Library m_Kernel32; private: LPWSTR (*CDECL wine_get_dos_file_name)(LPCSTR str); LPSTR (*CDECL wine_get_unix_file_name)(LPCWSTR str); protected: std::string m_Uname_m; std::string m_HOME; std::string m_XDG_DATA_HOME; std::string m_XDG_CACHE_HOME; std::string m_XDG_CONFIG_HOME; public: Context(mpt::Wine::VersionContext versionContext); public: std::string EscapePosixShell(std::string line); std::string PathToPosix(mpt::PathString windowsPath); mpt::PathString PathToWindows(std::string hostPath); ExecResult ExecutePosixShellScript(std::string script, FlagSet flags, std::map > filetree, std::string title, ExecutePosixCommandProgress progress, ExecutePosixShellScriptProgress progressCancel, void *userdata); int ExecutePosixShellCommand(std::string command, std::string & output, std::string & error); std::string PathToPosixCanonical(mpt::PathString windowsPath); std::string GetPosixEnvVar(std::string var, std::string def = std::string()); public: mpt::Wine::VersionContext VersionContext() const { return m_VersionContext; } mpt::Library Kernel32() const { return m_Kernel32; } std::string Uname_m() const { return m_Uname_m; } std::string HOME() const { return m_HOME; } std::string XDG_DATA_HOME() const { return m_XDG_DATA_HOME; } std::string XDG_CACHE_HOME() const { return m_XDG_CACHE_HOME; } std::string XDG_CONFIG_HOME() const { return m_XDG_CONFIG_HOME; } }; } // namespace Wine } // namespace mpt #endif // MODPLUG_TRACKER && MPT_OS_WINDOWS OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/FlagSet.h0000644000372100037210000004323213066602107017251 00000000000000/* * FlagSet.h * --------- * Purpose: A flexible and typesafe flag set class. * Notes : Originally based on http://stackoverflow.com/questions/4226960/type-safer-bitflags-in-c . * Rewritten to be standard-conforming. * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include OPENMPT_NAMESPACE_BEGIN // Be aware of the required size when specializing this. // We cannot assert the minimum size because some compilers always allocate an 'int', // even for enums that would fit in smaller integral types. template struct enum_traits { typedef typename std::make_unsigned::type store_type; }; // Type-safe wrapper around an enum, that can represent all enum values and bitwise compositions thereof. // Conversions to and from plain integers as well as conversions to the base enum are always explicit. template class enum_value_type { public: typedef enum_t enum_type; typedef enum_value_type value_type; typedef typename enum_traits::store_type store_type; private: store_type bits; public: MPT_CONSTEXPR11_FUN enum_value_type() : bits(0) { } MPT_CONSTEXPR11_FUN enum_value_type(const enum_value_type &x) : bits(x.bits) { } MPT_CONSTEXPR11_FUN enum_value_type(enum_type x) : bits(static_cast(x)) { } private: explicit MPT_CONSTEXPR11_FUN enum_value_type(store_type x) : bits(x) { } // private in order to prevent accidental conversions. use from_bits. MPT_CONSTEXPR11_FUN operator store_type () const { return bits; } // private in order to prevent accidental conversions. use as_bits. public: static MPT_CONSTEXPR11_FUN enum_value_type from_bits(store_type bits) { return value_type(bits); } MPT_CONSTEXPR11_FUN enum_type as_enum() const { return static_cast(bits); } MPT_CONSTEXPR11_FUN store_type as_bits() const { return bits; } public: MPT_CONSTEXPR11_FUN operator bool () const { return bits != store_type(); } MPT_CONSTEXPR11_FUN bool operator ! () const { return bits == store_type(); } MPT_CONSTEXPR11_FUN const enum_value_type operator ~ () const { return enum_value_type(~bits); } friend MPT_CONSTEXPR11_FUN bool operator == (enum_value_type a, enum_value_type b) { return a.bits == b.bits; } friend MPT_CONSTEXPR11_FUN bool operator != (enum_value_type a, enum_value_type b) { return a.bits != b.bits; } friend MPT_CONSTEXPR11_FUN bool operator == (enum_value_type a, enum_t b) { return a == enum_value_type(b); } friend MPT_CONSTEXPR11_FUN bool operator != (enum_value_type a, enum_t b) { return a != enum_value_type(b); } friend MPT_CONSTEXPR11_FUN bool operator == (enum_t a, enum_value_type b) { return enum_value_type(a) == b; } friend MPT_CONSTEXPR11_FUN bool operator != (enum_t a, enum_value_type b) { return enum_value_type(a) != b; } friend MPT_CONSTEXPR11_FUN const enum_value_type operator | (enum_value_type a, enum_value_type b) { return enum_value_type(a.bits | b.bits); } friend MPT_CONSTEXPR11_FUN const enum_value_type operator & (enum_value_type a, enum_value_type b) { return enum_value_type(a.bits & b.bits); } friend MPT_CONSTEXPR11_FUN const enum_value_type operator ^ (enum_value_type a, enum_value_type b) { return enum_value_type(a.bits ^ b.bits); } friend MPT_CONSTEXPR11_FUN const enum_value_type operator | (enum_value_type a, enum_t b) { return a | enum_value_type(b); } friend MPT_CONSTEXPR11_FUN const enum_value_type operator & (enum_value_type a, enum_t b) { return a & enum_value_type(b); } friend MPT_CONSTEXPR11_FUN const enum_value_type operator ^ (enum_value_type a, enum_t b) { return a ^ enum_value_type(b); } friend MPT_CONSTEXPR11_FUN const enum_value_type operator | (enum_t a, enum_value_type b) { return enum_value_type(a) | b; } friend MPT_CONSTEXPR11_FUN const enum_value_type operator & (enum_t a, enum_value_type b) { return enum_value_type(a) & b; } friend MPT_CONSTEXPR11_FUN const enum_value_type operator ^ (enum_t a, enum_value_type b) { return enum_value_type(a) ^ b; } MPT_CONSTEXPR14_FUN enum_value_type &operator |= (enum_value_type b) { *this = *this | b; return *this; } MPT_CONSTEXPR14_FUN enum_value_type &operator &= (enum_value_type b) { *this = *this & b; return *this; } MPT_CONSTEXPR14_FUN enum_value_type &operator ^= (enum_value_type b) { *this = *this ^ b; return *this; } MPT_CONSTEXPR14_FUN enum_value_type &operator |= (enum_t b) { *this = *this | b; return *this; } MPT_CONSTEXPR14_FUN enum_value_type &operator &= (enum_t b) { *this = *this & b; return *this; } MPT_CONSTEXPR14_FUN enum_value_type &operator ^= (enum_t b) { *this = *this ^ b; return *this; } }; // Type-safe enum wrapper that allows type-safe bitwise testing. template class Enum { public: typedef Enum self_type; typedef enum_t enum_type; typedef enum_value_type value_type; typedef typename value_type::store_type store_type; private: enum_type value; public: explicit MPT_CONSTEXPR11_FUN Enum(enum_type val) : value(val) { } MPT_CONSTEXPR11_FUN operator enum_type () const { return value; } MPT_CONSTEXPR14_FUN Enum &operator = (enum_type val) { value = val; return *this; } public: MPT_CONSTEXPR11_FUN const value_type operator ~ () const { return ~value_type(value); } friend MPT_CONSTEXPR11_FUN bool operator == (self_type a, self_type b) { return value_type(a) == value_type(b); } friend MPT_CONSTEXPR11_FUN bool operator != (self_type a, self_type b) { return value_type(a) != value_type(b); } friend MPT_CONSTEXPR11_FUN bool operator == (self_type a, value_type b) { return value_type(a) == value_type(b); } friend MPT_CONSTEXPR11_FUN bool operator != (self_type a, value_type b) { return value_type(a) != value_type(b); } friend MPT_CONSTEXPR11_FUN bool operator == (value_type a, self_type b) { return value_type(a) == value_type(b); } friend MPT_CONSTEXPR11_FUN bool operator != (value_type a, self_type b) { return value_type(a) != value_type(b); } friend MPT_CONSTEXPR11_FUN bool operator == (self_type a, enum_type b) { return value_type(a) == value_type(b); } friend MPT_CONSTEXPR11_FUN bool operator != (self_type a, enum_type b) { return value_type(a) != value_type(b); } friend MPT_CONSTEXPR11_FUN bool operator == (enum_type a, self_type b) { return value_type(a) == value_type(b); } friend MPT_CONSTEXPR11_FUN bool operator != (enum_type a, self_type b) { return value_type(a) != value_type(b); } friend MPT_CONSTEXPR11_FUN const value_type operator | (self_type a, self_type b) { return value_type(a) | value_type(b); } friend MPT_CONSTEXPR11_FUN const value_type operator & (self_type a, self_type b) { return value_type(a) & value_type(b); } friend MPT_CONSTEXPR11_FUN const value_type operator ^ (self_type a, self_type b) { return value_type(a) ^ value_type(b); } friend MPT_CONSTEXPR11_FUN const value_type operator | (self_type a, value_type b) { return value_type(a) | value_type(b); } friend MPT_CONSTEXPR11_FUN const value_type operator & (self_type a, value_type b) { return value_type(a) & value_type(b); } friend MPT_CONSTEXPR11_FUN const value_type operator ^ (self_type a, value_type b) { return value_type(a) ^ value_type(b); } friend MPT_CONSTEXPR11_FUN const value_type operator | (value_type a, self_type b) { return value_type(a) | value_type(b); } friend MPT_CONSTEXPR11_FUN const value_type operator & (value_type a, self_type b) { return value_type(a) & value_type(b); } friend MPT_CONSTEXPR11_FUN const value_type operator ^ (value_type a, self_type b) { return value_type(a) ^ value_type(b); } friend MPT_CONSTEXPR11_FUN const value_type operator | (self_type a, enum_type b) { return value_type(a) | value_type(b); } friend MPT_CONSTEXPR11_FUN const value_type operator & (self_type a, enum_type b) { return value_type(a) & value_type(b); } friend MPT_CONSTEXPR11_FUN const value_type operator ^ (self_type a, enum_type b) { return value_type(a) ^ value_type(b); } friend MPT_CONSTEXPR11_FUN const value_type operator | (enum_type a, self_type b) { return value_type(a) | value_type(b); } friend MPT_CONSTEXPR11_FUN const value_type operator & (enum_type a, self_type b) { return value_type(a) & value_type(b); } friend MPT_CONSTEXPR11_FUN const value_type operator ^ (enum_type a, self_type b) { return value_type(a) ^ value_type(b); } }; template ::store_type > class FlagSet { public: typedef FlagSet self_type; typedef enum_t enum_type; typedef enum_value_type value_type; typedef store_t store_type; private: // support truncated store_type ... : store_type bits_; static MPT_CONSTEXPR11_FUN store_type store_from_value(value_type bits) { return static_cast(bits.as_bits()); } static MPT_CONSTEXPR11_FUN value_type value_from_store(store_type bits) { return value_type::from_bits(static_cast(bits)); } MPT_CONSTEXPR14_FUN FlagSet & store(value_type bits) { bits_ = store_from_value(bits); return *this; } MPT_CONSTEXPR11_FUN value_type load() const { return value_from_store(bits_); } public: // Default constructor (no flags set) MPT_CONSTEXPR11_FUN FlagSet() : bits_(store_from_value(value_type())) { } // Value constructor MPT_CONSTEXPR11_FUN FlagSet(value_type flags) : bits_(store_from_value(value_type(flags))) { } MPT_CONSTEXPR11_FUN FlagSet(enum_type flag) : bits_(store_from_value(value_type(flag))) { } explicit MPT_CONSTEXPR11_FUN FlagSet(store_type flags) : bits_(store_from_value(value_type::from_bits(flags))) { } MPT_CONSTEXPR11_FUN operator bool () const { return load(); } // In order to catch undesired conversions to bool in integer contexts, // add a deprecated conversion operator to store_type. // C++11 explicit conversion cast operators ('explicit operator bool ();') // would solve this in a better way and always fail at compile-time instead of this // solution which just warns in some cases. // The macro-based extended instrument fields writer in InstrumentExtensions.cpp currently needs this conversion, // so it is not marked deprecated (for now). /*MPT_DEPRECATED*/ MPT_CONSTEXPR11_FUN operator store_type () const { return load().as_bits(); } MPT_CONSTEXPR11_FUN value_type value() const { return load(); } MPT_CONSTEXPR11_FUN operator value_type () const { return load(); } // Test if one or more flags are set. Returns true if at least one of the given flags is set. MPT_CONSTEXPR11_FUN bool operator[] (value_type flags) const { return test(flags); } // String representation of flag set std::string to_string() const { std::string str(size_bits(), '0'); for(size_t x = 0; x < size_bits(); ++x) { str[size_bits() - x - 1] = (load() & (1 << x) ? '1' : '0'); } return str; } // Set one or more flags. MPT_CONSTEXPR14_FUN FlagSet &set(value_type flags) { return store(load() | flags); } // Set or clear one or more flags. MPT_CONSTEXPR14_FUN FlagSet &set(value_type flags, bool val) { return store((val ? (load() | flags) : (load() & ~flags))); } // Clear or flags. MPT_CONSTEXPR14_FUN FlagSet &reset() { return store(value_type()); } // Clear one or more flags. MPT_CONSTEXPR14_FUN FlagSet &reset(value_type flags) { return store(load() & ~flags); } // Toggle all flags. MPT_CONSTEXPR14_FUN FlagSet &flip() { return store(~load()); } // Toggle one or more flags. MPT_CONSTEXPR14_FUN FlagSet &flip(value_type flags) { return store(load() ^ flags); } // Returns the size of the flag set in bytes MPT_CONSTEXPR11_FUN std::size_t size() const { return sizeof(store_type); } // Returns the size of the flag set in bits MPT_CONSTEXPR11_FUN std::size_t size_bits() const { return size() * 8; } // Test if one or more flags are set. Returns true if at least one of the given flags is set. MPT_CONSTEXPR11_FUN bool test(value_type flags) const { return (load() & flags); } // Test if all specified flags are set. MPT_CONSTEXPR11_FUN bool test_all(value_type flags) const { return (load() & flags) == flags; } // Test if any but the specified flags are set. MPT_CONSTEXPR11_FUN bool test_any_except(value_type flags) const { return (load() & ~flags); } // Test if any flag is set. MPT_CONSTEXPR11_FUN bool any() const { return load(); } // Test if no flags are set. MPT_CONSTEXPR11_FUN bool none() const { return !load(); } MPT_CONSTEXPR11_FUN store_type GetRaw() const { return bits_; } MPT_CONSTEXPR14_FUN FlagSet & SetRaw(store_type flags) { bits_ = flags; return *this; } MPT_CONSTEXPR14_FUN FlagSet &operator = (value_type flags) { return store(flags); } MPT_CONSTEXPR14_FUN FlagSet &operator = (enum_type flag) { return store(flag); } MPT_CONSTEXPR14_FUN FlagSet &operator = (FlagSet flags) { return store(flags.load()); } MPT_CONSTEXPR14_FUN FlagSet &operator &= (value_type flags) { return store(load() & flags); } MPT_CONSTEXPR14_FUN FlagSet &operator |= (value_type flags) { return store(load() | flags); } MPT_CONSTEXPR14_FUN FlagSet &operator ^= (value_type flags) { return store(load() ^ flags); } friend MPT_CONSTEXPR11_FUN bool operator == (self_type a, self_type b) { return a.load() == b.load(); } friend MPT_CONSTEXPR11_FUN bool operator != (self_type a, self_type b) { return a.load() != b.load(); } friend MPT_CONSTEXPR11_FUN bool operator == (self_type a, value_type b) { return a.load() == value_type(b); } friend MPT_CONSTEXPR11_FUN bool operator != (self_type a, value_type b) { return a.load() != value_type(b); } friend MPT_CONSTEXPR11_FUN bool operator == (value_type a, self_type b) { return value_type(a) == b.load(); } friend MPT_CONSTEXPR11_FUN bool operator != (value_type a, self_type b) { return value_type(a) != b.load(); } friend MPT_CONSTEXPR11_FUN bool operator == (self_type a, enum_type b) { return a.load() == value_type(b); } friend MPT_CONSTEXPR11_FUN bool operator != (self_type a, enum_type b) { return a.load() != value_type(b); } friend MPT_CONSTEXPR11_FUN bool operator == (enum_type a, self_type b) { return value_type(a) == b.load(); } friend MPT_CONSTEXPR11_FUN bool operator != (enum_type a, self_type b) { return value_type(a) != b.load(); } friend MPT_CONSTEXPR11_FUN bool operator == (self_type a, Enum b) { return a.load() == value_type(b); } friend MPT_CONSTEXPR11_FUN bool operator != (self_type a, Enum b) { return a.load() != value_type(b); } friend MPT_CONSTEXPR11_FUN bool operator == (Enum a, self_type b) { return value_type(a) == b.load(); } friend MPT_CONSTEXPR11_FUN bool operator != (Enum a, self_type b) { return value_type(a) != b.load(); } friend MPT_CONSTEXPR11_FUN const value_type operator | (self_type a, self_type b) { return a.load() | b.load(); } friend MPT_CONSTEXPR11_FUN const value_type operator & (self_type a, self_type b) { return a.load() & b.load(); } friend MPT_CONSTEXPR11_FUN const value_type operator ^ (self_type a, self_type b) { return a.load() ^ b.load(); } friend MPT_CONSTEXPR11_FUN const value_type operator | (self_type a, value_type b) { return a.load() | value_type(b); } friend MPT_CONSTEXPR11_FUN const value_type operator & (self_type a, value_type b) { return a.load() & value_type(b); } friend MPT_CONSTEXPR11_FUN const value_type operator ^ (self_type a, value_type b) { return a.load() ^ value_type(b); } friend MPT_CONSTEXPR11_FUN const value_type operator | (value_type a, self_type b) { return value_type(a) | b.load(); } friend MPT_CONSTEXPR11_FUN const value_type operator & (value_type a, self_type b) { return value_type(a) & b.load(); } friend MPT_CONSTEXPR11_FUN const value_type operator ^ (value_type a, self_type b) { return value_type(a) ^ b.load(); } friend MPT_CONSTEXPR11_FUN const value_type operator | (self_type a, enum_type b) { return a.load() | value_type(b); } friend MPT_CONSTEXPR11_FUN const value_type operator & (self_type a, enum_type b) { return a.load() & value_type(b); } friend MPT_CONSTEXPR11_FUN const value_type operator ^ (self_type a, enum_type b) { return a.load() ^ value_type(b); } friend MPT_CONSTEXPR11_FUN const value_type operator | (enum_type a, self_type b) { return value_type(a) | b.load(); } friend MPT_CONSTEXPR11_FUN const value_type operator & (enum_type a, self_type b) { return value_type(a) & b.load(); } friend MPT_CONSTEXPR11_FUN const value_type operator ^ (enum_type a, self_type b) { return value_type(a) ^ b.load(); } friend MPT_CONSTEXPR11_FUN const value_type operator | (self_type a, Enum b) { return a.load() | value_type(b); } friend MPT_CONSTEXPR11_FUN const value_type operator & (self_type a, Enum b) { return a.load() & value_type(b); } friend MPT_CONSTEXPR11_FUN const value_type operator ^ (self_type a, Enum b) { return a.load() ^ value_type(b); } friend MPT_CONSTEXPR11_FUN const value_type operator | (Enum a, self_type b) { return value_type(a) | b.load(); } friend MPT_CONSTEXPR11_FUN const value_type operator & (Enum a, self_type b) { return value_type(a) & b.load(); } friend MPT_CONSTEXPR11_FUN const value_type operator ^ (Enum a, self_type b) { return value_type(a) ^ b.load(); } }; // Declare typesafe logical operators for enum_t #define MPT_DECLARE_ENUM(enum_t) \ MPT_CONSTEXPR11_FUN enum_value_type operator | (enum_t a, enum_t b) { return enum_value_type(a) | enum_value_type(b); } \ MPT_CONSTEXPR11_FUN enum_value_type operator & (enum_t a, enum_t b) { return enum_value_type(a) & enum_value_type(b); } \ MPT_CONSTEXPR11_FUN enum_value_type operator ^ (enum_t a, enum_t b) { return enum_value_type(a) ^ enum_value_type(b); } \ MPT_CONSTEXPR11_FUN enum_value_type operator ~ (enum_t a) { return ~enum_value_type(a); } \ /**/ // backwards compatibility #define DECLARE_FLAGSET MPT_DECLARE_ENUM OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/versionNumber.h0000644000372100037210000000167313235360351020565 00000000000000/* * versionNumber.h * --------------- * Purpose: OpenMPT version handling. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once OPENMPT_NAMESPACE_BEGIN #define VER_HELPER_STRINGIZE(x) #x #define VER_STRINGIZE(x) VER_HELPER_STRINGIZE(x) //Version definitions. The only thing that needs to be changed when changing version number. #define VER_MAJORMAJOR 1 #define VER_MAJOR 27 #define VER_MINOR 04 #define VER_MINORMINOR 02 //Version string. For example "1.17.02.28" #define MPT_VERSION_STR VER_STRINGIZE(VER_MAJORMAJOR) "." VER_STRINGIZE(VER_MAJOR) "." VER_STRINGIZE(VER_MINOR) "." VER_STRINGIZE(VER_MINORMINOR) //Numerical value of the version. #define MPT_VERSION_NUMERIC MAKE_VERSION_NUMERIC(VER_MAJORMAJOR,VER_MAJOR,VER_MINOR,VER_MINORMINOR) OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/mptStringFormat.h0000644000372100037210000007446713177035777021122 00000000000000/* * mptStringFormat.h * ----------------- * Purpose: Convert other types to strings. * Notes : Currently none. * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "mptString.h" OPENMPT_NAMESPACE_BEGIN // The following section demands a rationale. // 1. mpt::fmt::val(), mpt::wfmt::val() and mpt::ufmt::val() mimic the semantics of c++11 std::to_string() and std::to_wstring(). // There is an important difference though. The c++11 versions are specified in terms of sprintf formatting which in turn // depends on the current C locale. This renders these functions unusable in a library context because the current // C locale is set by the library-using application and could be anything. There is no way a library can get reliable semantics // out of these functions. It is thus better to just avoid them. // ToString() and ToWString() are based on iostream internally, but the the locale of the stream is forced to std::locale::classic(), // which results in "C" ASCII locale behavior. // 2. The full suite of printf-like or iostream like number formatting is generally not required. Instead, a sane subset functionality // is provided here. // For convenience, mpt::fmt::f(const char *, float) allows formatting a single floating point value with a // standard printf-like format string. This itself relies on iostream with classic() locale internally and is thus current locale // agnostic. // When formatting integers, it is recommended to use mpt::fmt::dec or mpt::fmt::hex. Appending a template argument '' sets the width, // the same way as '%nd' would do. Appending a '0' to the function name causes zero-filling as print-like '%0nd' would do. Spelling 'HEX' // in upper-case generates upper-case hex digits. If these are not known at compile-time, a more verbose FormatVal(int, format) can be // used. // 3. mpt::format(format)(...) provides simplified and type-safe message and localization string formatting. // The only specifier allowed is '%' followed by a single digit n. It references to n-th parameter after the format string (1-based). // This mimics the behaviour of QString::arg() in QT4/5 or MFC AfxFormatString2(). C printf-like functions offer similar functionality // with a '%n$TYPE' syntax. In .NET, the syntax is '{n}'. This is useful to support localization strings that can change the parameter // ordering. // There are macro verions (MPT_FORMAT and variants) which properly use wide string literals for the format parameter. // 4. Every function is available for std::string, std::wstring and mpt::ustring. std::string makes no assumption about the encoding, which // basically means, it should work for any 7-bit or 8-bit encoding, including for example ASCII, UTF8 or the current locale encoding. // std::string std::wstring mpt::ustring CString // mpt::fmt::val mpt::wfmt::val mpt::ufmt::val mpt::tfmt::val // mpt::FormatVal mpt::FormatValW mpt::FormatValTFunctor() mpt::FormatValTFunctor() // mpt::fmt mpt::wfmt mpt::ufmt mpt::tfmt // mpt::format mpt::format mpt::format mpt::format // 5. All functionality here delegates real work outside of the header file so that and do not need to be included when // using this functionality. // Advantages: // - Avoids binary code bloat when too much of iostream operator << gets inlined at every usage site. // - Faster compile times because and (2 very complex headers) are not included everywhere. // Disadvantages: // - Slightly more c++ code is required for delegating work. // - As the header does not use iostreams, custom types need to overload mpt::String, mpt::ToWstring and mpt::UString instead of // iostream operator << to allow for custom type formatting. // - std::string, std::wstring and mpt::ustring are returned from somewhat deep cascades of helper functions. Where possible, code is // written in such a way that return-value-optimization (RVO) or named-return-value-optimization (NRVO) should be able to eliminate // almost all these copies. This should not be a problem for any decent modern compiler (and even less so for a c++11 compiler where // move-semantics will kick in if RVO/NRVO fails). namespace mpt { // ToString() converts various built-in types to a well-defined, locale-independent string representation. // This is also used as a type-tunnel pattern for mpt::format. // Custom types that need to be converted to strings are encouraged to overload ToString() and ToWString(). // fallback to member function ToString() template auto ToString(const T & x) -> decltype(x.ToString()) { return x.ToString(); } static inline std::string ToString(const std::string & x) { return x; } static inline std::string ToString(const char * const & x) { return x; } MPT_DEPRECATED static inline std::string ToString(const char & x) { return std::string(1, x); } // deprecated to catch potential API mis-use, use std::string(1, x) instead #if MPT_WSTRING_FORMAT MPT_DEPRECATED std::string ToString(const std::wstring & x); // Unknown encoding. MPT_DEPRECATED std::string ToString(const wchar_t * const & x); // Unknown encoding. MPT_DEPRECATED std::string ToString(const wchar_t & x); // deprecated to catch potential API mis-use, use std::wstring(1, x) instead #endif #if MPT_USTRING_MODE_UTF8 MPT_DEPRECATED std::string ToString(const mpt::ustring & x); // Unknown encoding. #endif #if defined(_MFC_VER) MPT_DEPRECATED std::string ToString(const mpt::ustring & x); // Unknown encoding. #endif #if defined(_MFC_VER) MPT_DEPRECATED std::string ToString(const CString & x); #endif std::string ToString(const bool & x); std::string ToString(const signed char & x); std::string ToString(const unsigned char & x); std::string ToString(const signed short & x); std::string ToString(const unsigned short & x); std::string ToString(const signed int & x); std::string ToString(const unsigned int & x); std::string ToString(const signed long & x); std::string ToString(const unsigned long & x); std::string ToString(const signed long long & x); std::string ToString(const unsigned long long & x); std::string ToString(const float & x); std::string ToString(const double & x); std::string ToString(const long double & x); // fallback to member function ToUString() template auto ToUString(const T & x) -> decltype(x.ToUString()) { return x.ToUString(); } static inline mpt::ustring ToUString(const mpt::ustring & x) { return x; } MPT_DEPRECATED mpt::ustring ToUString(const std::string & x); // Unknown encoding. MPT_DEPRECATED mpt::ustring ToUString(const char * const & x); // Unknown encoding. Note that this also applies to TCHAR in !UNICODE builds as the type is indistinguishable from char. Wrap with CString or FromTcharStr in this case. MPT_DEPRECATED mpt::ustring ToUString(const char & x); // deprecated to catch potential API mis-use, use std::string(1, x) instead #if MPT_WSTRING_FORMAT #if MPT_USTRING_MODE_UTF8 mpt::ustring ToUString(const std::wstring & x); #endif mpt::ustring ToUString(const wchar_t * const & x); MPT_DEPRECATED mpt::ustring ToUString(const wchar_t & x); // deprecated to catch potential API mis-use, use std::wstring(1, x) instead #endif #if defined(_MFC_VER) mpt::ustring ToUString(const CString & x); #endif mpt::ustring ToUString(const bool & x); mpt::ustring ToUString(const signed char & x); mpt::ustring ToUString(const unsigned char & x); mpt::ustring ToUString(const signed short & x); mpt::ustring ToUString(const unsigned short & x); mpt::ustring ToUString(const signed int & x); mpt::ustring ToUString(const unsigned int & x); mpt::ustring ToUString(const signed long & x); mpt::ustring ToUString(const unsigned long & x); mpt::ustring ToUString(const signed long long & x); mpt::ustring ToUString(const unsigned long long & x); mpt::ustring ToUString(const float & x); mpt::ustring ToUString(const double & x); mpt::ustring ToUString(const long double & x); #if MPT_WSTRING_FORMAT MPT_DEPRECATED std::wstring ToWString(const std::string & x); // Unknown encoding. MPT_DEPRECATED std::wstring ToWString(const char * const & x); // Unknown encoding. Note that this also applies to TCHAR in !UNICODE builds as the type is indistinguishable from char. Wrap with CString or FromTcharStr in this case. MPT_DEPRECATED std::wstring ToWString(const char & x); // deprecated to catch potential API mis-use, use std::string(1, x) instead static inline std::wstring ToWString(const std::wstring & x) { return x; } static inline std::wstring ToWString(const wchar_t * const & x) { return x; } MPT_DEPRECATED static inline std::wstring ToWString(const wchar_t & x) { return std::wstring(1, x); } // deprecated to catch potential API mis-use, use std::wstring(1, x) instead #if MPT_USTRING_MODE_UTF8 std::wstring ToWString(const mpt::ustring & x); #endif #if defined(_MFC_VER) std::wstring ToWString(const CString & x); #endif std::wstring ToWString(const bool & x); std::wstring ToWString(const signed char & x); std::wstring ToWString(const unsigned char & x); std::wstring ToWString(const signed short & x); std::wstring ToWString(const unsigned short & x); std::wstring ToWString(const signed int & x); std::wstring ToWString(const unsigned int & x); std::wstring ToWString(const signed long & x); std::wstring ToWString(const unsigned long & x); std::wstring ToWString(const signed long long & x); std::wstring ToWString(const unsigned long long & x); std::wstring ToWString(const float & x); std::wstring ToWString(const double & x); std::wstring ToWString(const long double & x); #endif #if defined(_MFC_VER) #ifdef UNICODE #if MPT_WSTRING_FORMAT template static inline CString ToCStringHelper(const T & x) { return mpt::ToCString(ToWString(x)); } #else template static inline CString ToCStringHelper(const T & x) { return mpt::ToCString(ToUString(x)); } #endif #else namespace detail { template struct CstringToStdStringImpl { CString operator () (const T & v) { return mpt::ToCString(mpt::CharsetLocale, ToString(v)); } }; template <> struct CstringToStdStringImpl { CString operator () (const CString & v) { return v; } }; } template static inline CString ToCStringHelper(const T & x) { return mpt::detail::CstringToStdStringImpl()(x); } #endif #endif template struct ToStringTFunctor {}; template <> struct ToStringTFunctor { template inline std::string operator() (const T & x) { return ToString(x); } }; template <> struct ToStringTFunctor { template inline mpt::ustring operator() (const T & x) { return ToUString(x); } }; #if MPT_WSTRING_FORMAT && MPT_USTRING_MODE_UTF8 template <> struct ToStringTFunctor { template inline std::wstring operator() (const T & x) { return ToWString(x); } }; #endif #if defined(_MFC_VER) template <> struct ToStringTFunctor { template inline CString operator() (const T & x) { return mpt::ToCStringHelper(x); } }; #endif template inline Tstring ToStringT(const T & x) { return ToStringTFunctor()(x); } struct fmt_base { enum FormatFlagsEnum { BaseDec = 0x0001, // base 10 (integers only) BaseHex = 0x0002, // base 16 (integers only) CaseLow = 0x0010, // lower case hex digits CaseUpp = 0x0020, // upper case hex digits FillOff = 0x0100, // do not fill up width FillSpc = 0x0200, // fill up width with spaces FillNul = 0x0400, // fill up width with zeros NotaNrm = 0x1000, // float: normal/default notation NotaFix = 0x2000, // float: fixed point notation NotaSci = 0x4000, // float: scientific notation }; }; // struct fmt_base typedef unsigned int FormatFlags; STATIC_ASSERT(sizeof(FormatFlags) >= sizeof(fmt_base::FormatFlagsEnum)); class FormatSpec; MPT_DEPRECATED std::string FormatVal(const char & x, const FormatSpec & f); // deprecated to catch potential API mis-use, use std::string(1, x) instead MPT_DEPRECATED std::string FormatVal(const wchar_t & x, const FormatSpec & f); // deprecated to catch potential API mis-use, use std::wstring(1, x) instead std::string FormatVal(const bool & x, const FormatSpec & f); std::string FormatVal(const signed char & x, const FormatSpec & f); std::string FormatVal(const unsigned char & x, const FormatSpec & f); std::string FormatVal(const signed short & x, const FormatSpec & f); std::string FormatVal(const unsigned short & x, const FormatSpec & f); std::string FormatVal(const signed int & x, const FormatSpec & f); std::string FormatVal(const unsigned int & x, const FormatSpec & f); std::string FormatVal(const signed long & x, const FormatSpec & f); std::string FormatVal(const unsigned long & x, const FormatSpec & f); std::string FormatVal(const signed long long & x, const FormatSpec & f); std::string FormatVal(const unsigned long long & x, const FormatSpec & f); std::string FormatVal(const float & x, const FormatSpec & f); std::string FormatVal(const double & x, const FormatSpec & f); std::string FormatVal(const long double & x, const FormatSpec & f); #if MPT_WSTRING_FORMAT MPT_DEPRECATED std::wstring FormatValW(const char & x, const FormatSpec & f); // deprecated to catch potential API mis-use, use std::string(1, x) instead MPT_DEPRECATED std::wstring FormatValW(const wchar_t & x, const FormatSpec & f); // deprecated to catch potential API mis-use, use std::wstring(1, x) instead std::wstring FormatValW(const bool & x, const FormatSpec & f); std::wstring FormatValW(const signed char & x, const FormatSpec & f); std::wstring FormatValW(const unsigned char & x, const FormatSpec & f); std::wstring FormatValW(const signed short & x, const FormatSpec & f); std::wstring FormatValW(const unsigned short & x, const FormatSpec & f); std::wstring FormatValW(const signed int & x, const FormatSpec & f); std::wstring FormatValW(const unsigned int & x, const FormatSpec & f); std::wstring FormatValW(const signed long & x, const FormatSpec & f); std::wstring FormatValW(const unsigned long & x, const FormatSpec & f); std::wstring FormatValW(const signed long long & x, const FormatSpec & f); std::wstring FormatValW(const unsigned long long & x, const FormatSpec & f); std::wstring FormatValW(const float & x, const FormatSpec & f); std::wstring FormatValW(const double & x, const FormatSpec & f); std::wstring FormatValW(const long double & x, const FormatSpec & f); #endif template struct FormatValTFunctor {}; template <> struct FormatValTFunctor { template inline std::string operator() (const T & x, const FormatSpec & f) { return FormatVal(x, f); } }; #if MPT_WSTRING_FORMAT template <> struct FormatValTFunctor { template inline std::wstring operator() (const T & x, const FormatSpec & f) { return FormatValW(x, f); } }; #endif #if MPT_USTRING_MODE_UTF8 template <> struct FormatValTFunctor { template inline mpt::ustring operator() (const T & x, const FormatSpec & f) { return mpt::ToUnicode(mpt::CharsetUTF8, FormatVal(x, f)); } }; #endif #if defined(_MFC_VER) #ifdef UNICODE template <> struct FormatValTFunctor { template inline CString operator() (const T & x, const FormatSpec & f) { return mpt::ToCString(FormatValW(x, f)); } }; #else template <> struct FormatValTFunctor { template inline CString operator() (const T & x, const FormatSpec & f) { return mpt::ToCString(mpt::CharsetLocale, FormatVal(x, f)); } }; #endif #endif class FormatSpec { private: FormatFlags flags; std::size_t width; int precision; public: FormatSpec() : flags(0), width(0), precision(-1) {} FormatFlags GetFlags() const { return flags; } std::size_t GetWidth() const { return width; } int GetPrecision() const { return precision; } FormatSpec & SetFlags(FormatFlags f) { flags = f; return *this; } FormatSpec & SetWidth(std::size_t w) { width = w; return *this; } FormatSpec & SetPrecision(int p) { precision = p; return *this; } public: // short-hand construction explicit FormatSpec(FormatFlags f, std::size_t w = 0, int p = -1) : flags(f), width(w), precision(p) {} explicit FormatSpec(const char * format) : flags(0), width(0), precision(-1) { ParsePrintf(format); } explicit FormatSpec(const wchar_t * format) : flags(0), width(0), precision(-1) { ParsePrintf(format); } explicit FormatSpec(const std::string & format) : flags(0), width(0), precision(-1) { ParsePrintf(format); } explicit FormatSpec(const std::wstring & format) : flags(0), width(0), precision(-1) { ParsePrintf(format); } public: // only for floating point formats FormatSpec & ParsePrintf(const char * format); FormatSpec & ParsePrintf(const wchar_t * format); FormatSpec & ParsePrintf(const std::string & format); FormatSpec & ParsePrintf(const std::wstring & format); public: FormatSpec & BaseDec() { flags &= ~(fmt_base::BaseDec|fmt_base::BaseHex); flags |= fmt_base::BaseDec; return *this; } FormatSpec & BaseHex() { flags &= ~(fmt_base::BaseDec|fmt_base::BaseHex); flags |= fmt_base::BaseHex; return *this; } FormatSpec & CaseLow() { flags &= ~(fmt_base::CaseLow|fmt_base::CaseUpp); flags |= fmt_base::CaseLow; return *this; } FormatSpec & CaseUpp() { flags &= ~(fmt_base::CaseLow|fmt_base::CaseUpp); flags |= fmt_base::CaseUpp; return *this; } FormatSpec & FillOff() { flags &= ~(fmt_base::FillOff|fmt_base::FillSpc|fmt_base::FillNul); flags |= fmt_base::FillOff; return *this; } FormatSpec & FillSpc() { flags &= ~(fmt_base::FillOff|fmt_base::FillSpc|fmt_base::FillNul); flags |= fmt_base::FillSpc; return *this; } FormatSpec & FillNul() { flags &= ~(fmt_base::FillOff|fmt_base::FillSpc|fmt_base::FillNul); flags |= fmt_base::FillNul; return *this; } FormatSpec & NotaNrm() { flags &= ~(fmt_base::NotaNrm|fmt_base::NotaFix|fmt_base::NotaSci); flags |= fmt_base::NotaNrm; return *this; } FormatSpec & NotaFix() { flags &= ~(fmt_base::NotaNrm|fmt_base::NotaFix|fmt_base::NotaSci); flags |= fmt_base::NotaFix; return *this; } FormatSpec & NotaSci() { flags &= ~(fmt_base::NotaNrm|fmt_base::NotaFix|fmt_base::NotaSci); flags |= fmt_base::NotaSci; return *this; } FormatSpec & Width(std::size_t w) { width = w; return *this; } FormatSpec & Prec(int p) { precision = p; return *this; } public: FormatSpec & Dec() { return BaseDec(); } FormatSpec & Hex() { return BaseHex(); } FormatSpec & Low() { return CaseLow(); } FormatSpec & Upp() { return CaseUpp(); } FormatSpec & Off() { return FillOff(); } FormatSpec & Spc() { return FillSpc(); } FormatSpec & Nul() { return FillNul(); } FormatSpec & Nrm() { return NotaNrm(); } FormatSpec & Fix() { return NotaFix(); } FormatSpec & Sci() { return NotaSci(); } public: FormatSpec & Decimal() { return BaseDec(); } FormatSpec & Hexadecimal() { return BaseHex(); } FormatSpec & Lower() { return CaseLow(); } FormatSpec & Upper() { return CaseUpp(); } FormatSpec & FillNone() { return FillOff(); } FormatSpec & FillSpace() { return FillSpc(); } FormatSpec & FillZero() { return FillNul(); } FormatSpec & FloatNormal() { return NotaNrm(); } FormatSpec & FloatFixed() { return NotaFix(); } FormatSpec & FloatScientific() { return NotaSci(); } FormatSpec & Precision(int p) { return Prec(p); } template inline Tstring ToStringT(const T & x) const { return FormatValTFunctor()(x, *this); } template inline std::string ToString(const T & x) const { return FormatVal(x, *this); } #if MPT_WSTRING_FORMAT template inline std::wstring ToWString(const T & x) const { return FormatValW(x, *this); } #endif }; template struct fmtT : fmt_base { template static inline Tstring val(const T& x) { return ToStringTFunctor()(x); } template static inline Tstring dec(const T& x) { STATIC_ASSERT(std::numeric_limits::is_integer); return FormatValTFunctor()(x, FormatSpec().BaseDec().FillOff()); } template static inline Tstring dec(const T& x) { STATIC_ASSERT(std::numeric_limits::is_integer); return FormatValTFunctor()(x, FormatSpec().BaseDec().FillSpc().Width(width)); } template static inline Tstring dec0(const T& x) { STATIC_ASSERT(std::numeric_limits::is_integer); return FormatValTFunctor()(x, FormatSpec().BaseDec().FillNul().Width(width)); } template static inline Tstring hex(const T& x) { STATIC_ASSERT(std::numeric_limits::is_integer); return FormatValTFunctor()(x, FormatSpec().BaseHex().CaseLow().FillOff()); } template static inline Tstring HEX(const T& x) { STATIC_ASSERT(std::numeric_limits::is_integer); return FormatValTFunctor()(x, FormatSpec().BaseHex().CaseUpp().FillOff()); } template static inline Tstring hex(const T& x) { STATIC_ASSERT(std::numeric_limits::is_integer); return FormatValTFunctor()(x, FormatSpec().BaseHex().CaseLow().FillSpc().Width(width)); } template static inline Tstring HEX(const T& x) { STATIC_ASSERT(std::numeric_limits::is_integer); return FormatValTFunctor()(x, FormatSpec().BaseHex().CaseUpp().FillSpc().Width(width)); } template static inline Tstring hex0(const T& x) { STATIC_ASSERT(std::numeric_limits::is_integer); return FormatValTFunctor()(x, FormatSpec().BaseHex().CaseLow().FillNul().Width(width)); } template static inline Tstring HEX0(const T& x) { STATIC_ASSERT(std::numeric_limits::is_integer); return FormatValTFunctor()(x, FormatSpec().BaseHex().CaseUpp().FillNul().Width(width)); } template static inline Tstring flt(const T& x, std::size_t width = 0, int precision = -1) { STATIC_ASSERT(std::is_floating_point::value); if(width == 0) { return FormatValTFunctor()(x, FormatSpec().NotaNrm().FillOff().Precision(precision)); } else { return FormatValTFunctor()(x, FormatSpec().NotaNrm().FillSpc().Width(width).Precision(precision)); } } template static inline Tstring fix(const T& x, std::size_t width = 0, int precision = -1) { STATIC_ASSERT(std::is_floating_point::value); if(width == 0) { return FormatValTFunctor()(x, FormatSpec().NotaFix().FillOff().Precision(precision)); } else { return FormatValTFunctor()(x, FormatSpec().NotaFix().FillSpc().Width(width).Precision(precision)); } } template static inline Tstring sci(const T& x, std::size_t width = 0, int precision = -1) { STATIC_ASSERT(std::is_floating_point::value); if(width == 0) { return FormatValTFunctor()(x, FormatSpec().NotaSci().FillOff().Precision(precision)); } else { return FormatValTFunctor()(x, FormatSpec().NotaSci().FillSpc().Width(width).Precision(precision)); } } template static inline Tstring f(const Tformat & format, const T& x) { STATIC_ASSERT(std::is_floating_point::value); return FormatValTFunctor()(x, FormatSpec().ParsePrintf(format)); } }; // struct fmtT typedef fmtT fmt; #if MPT_WSTRING_FORMAT typedef fmtT wfmt; #endif #if MPT_USTRING_MODE_WIDE typedef fmtT ufmt; #else typedef fmtT ufmt; #endif #if defined(_MFC_VER) typedef fmtT tfmt; #endif } // namespace mpt namespace mpt { namespace String { namespace detail { template struct to_string_type { }; template <> struct to_string_type { typedef std::string type; }; template <> struct to_string_type { typedef std::string type; }; template <> struct to_string_type { typedef std::string type; }; template <> struct to_string_type { typedef std::string type; }; template <> struct to_string_type { typedef std::string type; }; template <> struct to_string_type { typedef std::wstring type; }; template <> struct to_string_type { typedef std::wstring type; }; template <> struct to_string_type { typedef std::wstring type; }; template <> struct to_string_type { typedef std::wstring type; }; template <> struct to_string_type { typedef std::wstring type; }; #if MPT_USTRING_MODE_UTF8 template <> struct to_string_type { typedef mpt::ustring type; }; #endif #if defined(_MFC_VER) template <> struct to_string_type { typedef CString type; }; #endif template struct to_string_type { typedef typename to_string_type::type type; }; std::string PrintImpl(const std::string & format , const std::string & x1 = std::string() , const std::string & x2 = std::string() , const std::string & x3 = std::string() , const std::string & x4 = std::string() , const std::string & x5 = std::string() , const std::string & x6 = std::string() , const std::string & x7 = std::string() , const std::string & x8 = std::string() ); #if MPT_WSTRING_FORMAT std::wstring PrintImpl(const std::wstring & format , const std::wstring & x1 = std::wstring() , const std::wstring & x2 = std::wstring() , const std::wstring & x3 = std::wstring() , const std::wstring & x4 = std::wstring() , const std::wstring & x5 = std::wstring() , const std::wstring & x6 = std::wstring() , const std::wstring & x7 = std::wstring() , const std::wstring & x8 = std::wstring() ); #endif #if MPT_USTRING_MODE_UTF8 mpt::ustring PrintImpl(const mpt::ustring & format , const mpt::ustring & x1 = mpt::ustring() , const mpt::ustring & x2 = mpt::ustring() , const mpt::ustring & x3 = mpt::ustring() , const mpt::ustring & x4 = mpt::ustring() , const mpt::ustring & x5 = mpt::ustring() , const mpt::ustring & x6 = mpt::ustring() , const mpt::ustring & x7 = mpt::ustring() , const mpt::ustring & x8 = mpt::ustring() ); #endif #if defined(_MFC_VER) CString PrintImpl(const CString & format , const CString & x1 = CString() , const CString & x2 = CString() , const CString & x3 = CString() , const CString & x4 = CString() , const CString & x5 = CString() , const CString & x6 = CString() , const CString & x7 = CString() , const CString & x8 = CString() ); #endif } // namespace detail } // namespace String template struct message_formatter { typedef typename mpt::String::detail::to_string_type::type Tstring; Tstring format; message_formatter(const Tstring & format) : format(format) {} Tstring operator() ( ) const { return mpt::String::detail::PrintImpl(format ); } template< typename T1 > Tstring operator() ( const T1& x1 ) const { return mpt::String::detail::PrintImpl(format , ToStringTFunctor()(x1) ); } template< typename T1 , typename T2 > Tstring operator() ( const T1& x1 , const T2& x2 ) const { return mpt::String::detail::PrintImpl(format , ToStringTFunctor()(x1) , ToStringTFunctor()(x2) ); } template< typename T1 , typename T2 , typename T3 > Tstring operator() ( const T1& x1 , const T2& x2 , const T3& x3 ) const { return mpt::String::detail::PrintImpl(format , ToStringTFunctor()(x1) , ToStringTFunctor()(x2) , ToStringTFunctor()(x3) ); } template< typename T1 , typename T2 , typename T3 , typename T4 > Tstring operator() ( const T1& x1 , const T2& x2 , const T3& x3 , const T4& x4 ) const { return mpt::String::detail::PrintImpl(format , ToStringTFunctor()(x1) , ToStringTFunctor()(x2) , ToStringTFunctor()(x3) , ToStringTFunctor()(x4) ); } template< typename T1 , typename T2 , typename T3 , typename T4 , typename T5 > Tstring operator() ( const T1& x1 , const T2& x2 , const T3& x3 , const T4& x4 , const T5& x5 ) const { return mpt::String::detail::PrintImpl(format , ToStringTFunctor()(x1) , ToStringTFunctor()(x2) , ToStringTFunctor()(x3) , ToStringTFunctor()(x4) , ToStringTFunctor()(x5) ); } template< typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 > Tstring operator() ( const T1& x1 , const T2& x2 , const T3& x3 , const T4& x4 , const T5& x5 , const T6& x6 ) const { return mpt::String::detail::PrintImpl(format , ToStringTFunctor()(x1) , ToStringTFunctor()(x2) , ToStringTFunctor()(x3) , ToStringTFunctor()(x4) , ToStringTFunctor()(x5) , ToStringTFunctor()(x6) ); } template< typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 > Tstring operator() ( const T1& x1 , const T2& x2 , const T3& x3 , const T4& x4 , const T5& x5 , const T6& x6 , const T7& x7 ) const { return mpt::String::detail::PrintImpl(format , ToStringTFunctor()(x1) , ToStringTFunctor()(x2) , ToStringTFunctor()(x3) , ToStringTFunctor()(x4) , ToStringTFunctor()(x5) , ToStringTFunctor()(x6) , ToStringTFunctor()(x7) ); } template< typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 > Tstring operator() ( const T1& x1 , const T2& x2 , const T3& x3 , const T4& x4 , const T5& x5 , const T6& x6 , const T7& x7 , const T8& x8 ) const { return mpt::String::detail::PrintImpl(format , ToStringTFunctor()(x1) , ToStringTFunctor()(x2) , ToStringTFunctor()(x3) , ToStringTFunctor()(x4) , ToStringTFunctor()(x5) , ToStringTFunctor()(x6) , ToStringTFunctor()(x7) , ToStringTFunctor()(x8) ); } }; // struct message_formatter template message_formatter::type> format(const Tformat &format) { typedef typename mpt::String::detail::to_string_type::type Tstring; return message_formatter(Tstring(format)); } #if MPT_WSTRING_FORMAT static inline message_formatter wformat(const std::wstring &format) { return message_formatter(format); } #endif static inline message_formatter uformat(const mpt::ustring &format) { return message_formatter(format); } #if defined(_MFC_VER) static inline message_formatter tformat(const CString &format) { return message_formatter(format); } #endif } // namespace mpt OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/mptTypeTraits.h0000644000372100037210000001202013076367670020562 00000000000000/* * mptTypeTraits.h * --------------- * Purpose: C++11 similar type_traits header plus some OpenMPT specific traits. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include OPENMPT_NAMESPACE_BEGIN namespace mpt { template struct int_of_size { }; template <> struct int_of_size<1> { typedef int8 type; }; template <> struct int_of_size<2> { typedef int16 type; }; template <> struct int_of_size<3> { typedef int32 type; }; template <> struct int_of_size<4> { typedef int32 type; }; template <> struct int_of_size<5> { typedef int64 type; }; template <> struct int_of_size<6> { typedef int64 type; }; template <> struct int_of_size<7> { typedef int64 type; }; template <> struct int_of_size<8> { typedef int64 type; }; template struct uint_of_size { }; template <> struct uint_of_size<1> { typedef uint8 type; }; template <> struct uint_of_size<2> { typedef uint16 type; }; template <> struct uint_of_size<3> { typedef uint32 type; }; template <> struct uint_of_size<4> { typedef uint32 type; }; template <> struct uint_of_size<5> { typedef uint64 type; }; template <> struct uint_of_size<6> { typedef uint64 type; }; template <> struct uint_of_size<7> { typedef uint64 type; }; template <> struct uint_of_size<8> { typedef uint64 type; }; // Tell which types are safe for mpt::byte_cast. // signed char is actually not allowed to alias into an object representation, // which means that, if the actual type is not itself signed char but char or // unsigned char instead, dereferencing the signed char pointer is undefined // behaviour. template struct is_byte_castable : public std::false_type { }; template <> struct is_byte_castable : public std::true_type { }; template <> struct is_byte_castable : public std::true_type { }; template <> struct is_byte_castable : public std::true_type { }; template <> struct is_byte_castable : public std::true_type { }; // Tell which types are safe to binary write into files. // By default, no types are safe. // When a safe type gets defined, // also specialize this template so that IO functions will work. template struct is_binary_safe : public std::false_type { }; // Specialization for byte types. template <> struct is_binary_safe : public std::true_type { }; template <> struct is_binary_safe : public std::true_type { }; template <> struct is_binary_safe : public std::true_type { }; // Generic Specialization for arrays. template struct is_binary_safe : public is_binary_safe { }; template struct is_binary_safe : public is_binary_safe { }; template struct GetRawBytesFunctor { inline const mpt::byte * operator () (const T & v) const { STATIC_ASSERT(mpt::is_binary_safe::type>::value); return reinterpret_cast(&v); } inline mpt::byte * operator () (T & v) const { STATIC_ASSERT(mpt::is_binary_safe::type>::value); return reinterpret_cast(&v); } }; template struct GetRawBytesFunctor { inline const mpt::byte * operator () (const T (&v)[N]) const { STATIC_ASSERT(mpt::is_binary_safe::type>::value); return reinterpret_cast(v); } inline mpt::byte * operator () (T (&v)[N]) const { STATIC_ASSERT(mpt::is_binary_safe::type>::value); return reinterpret_cast(v); } }; template struct GetRawBytesFunctor { inline const mpt::byte * operator () (const T (&v)[N]) const { STATIC_ASSERT(mpt::is_binary_safe::type>::value); return reinterpret_cast(v); } }; // In order to be able to partially specialize it, // as_raw_memory is implemented via a class template. // Do not overload or specialize as_raw_memory directly. // Using a wrapper (by default just around a cast to const mpt::byte *), // allows for implementing raw memory access // via on-demand generating a cached serialized representation. template inline const mpt::byte * as_raw_memory(const T & v) { STATIC_ASSERT(mpt::is_binary_safe::type>::value); return mpt::GetRawBytesFunctor()(v); } template inline mpt::byte * as_raw_memory(T & v) { STATIC_ASSERT(mpt::is_binary_safe::type>::value); return mpt::GetRawBytesFunctor()(v); } } // namespace mpt #define MPT_BINARY_STRUCT(type, size) \ MPT_STATIC_ASSERT(sizeof( type ) == (size) ); \ MPT_STATIC_ASSERT(alignof( type ) == 1); \ MPT_STATIC_ASSERT(std::is_standard_layout< type >::value); \ namespace mpt { \ template <> struct is_binary_safe< type > : public std::true_type { }; \ } \ /**/ OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/mptWine.cpp0000644000372100037210000005353113152522075017706 00000000000000/* * mptWine.cpp * ----------- * Purpose: Wine stuff. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "mptWine.h" #include "mptOS.h" #include "mptFileIO.h" #include #include #if MPT_OS_WINDOWS #include #endif OPENMPT_NAMESPACE_BEGIN #if defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS namespace mpt { namespace Wine { Context::Context(mpt::Wine::VersionContext versionContext) : m_VersionContext(versionContext) , wine_get_dos_file_name(nullptr) , wine_get_unix_file_name(nullptr) { if(!mpt::Windows::IsWine()) { throw mpt::Wine::Exception("Wine not detected."); } if(!m_VersionContext.Version().IsValid()) { throw mpt::Wine::Exception("Unknown Wine version detected."); } m_Kernel32 = mpt::Library(mpt::LibraryPath::FullPath(MPT_PATHSTRING("kernel32.dll"))); if(!m_Kernel32.IsValid()) { throw mpt::Wine::Exception("Could not load Wine kernel32.dll."); } if(!m_Kernel32.Bind(wine_get_unix_file_name, "wine_get_unix_file_name")) { throw mpt::Wine::Exception("Could not bind Wine kernel32.dll:wine_get_unix_file_name."); } if(!m_Kernel32.Bind(wine_get_dos_file_name, "wine_get_dos_file_name")) { throw mpt::Wine::Exception("Could not bind Wine kernel32.dll:wine_get_dos_file_name."); } { std::string out; std::string err; try { if(ExecutePosixShellCommand("uname -m", out, err) != 0) { throw mpt::Wine::Exception("Wine 'uname -m' failed."); } if(!err.empty()) { throw mpt::Wine::Exception("Wine 'uname -m' failed."); } out = mpt::String::Trim(out, std::string("\r\n")); m_Uname_m = out; } catch(const std::exception &) { m_Uname_m = std::string(); } } try { m_HOME = GetPosixEnvVar("HOME"); } catch(const std::exception &) { m_HOME = std::string(); } try { m_XDG_DATA_HOME = GetPosixEnvVar("XDG_DATA_HOME"); if(m_XDG_DATA_HOME.empty()) { m_XDG_DATA_HOME = m_HOME + "/.local/share"; } } catch(const std::exception &) { m_XDG_DATA_HOME = std::string(); } try { m_XDG_CACHE_HOME = GetPosixEnvVar("XDG_CACHE_HOME"); if(m_XDG_CACHE_HOME.empty()) { m_XDG_CACHE_HOME = m_HOME + "/.cache"; } } catch(const std::exception &) { m_XDG_CACHE_HOME = std::string(); } try { m_XDG_CONFIG_HOME = GetPosixEnvVar("XDG_CONFIG_HOME"); if(m_XDG_CONFIG_HOME.empty()) { m_XDG_CONFIG_HOME = m_HOME + "/.config"; } } catch(const std::exception &) { m_XDG_CONFIG_HOME = std::string(); } } std::string Context::PathToPosix(mpt::PathString windowsPath) { std::string result; if(windowsPath.empty()) { return result; } if(windowsPath.Length() >= 32000) { throw mpt::Wine::Exception("Path too long."); } LPSTR tmp = nullptr; tmp = wine_get_unix_file_name(windowsPath.AsNative().c_str()); if(!tmp) { throw mpt::Wine::Exception("Wine kernel32.dll:wine_get_unix_file_name failed."); } result = tmp; HeapFree(GetProcessHeap(), 0, tmp); tmp = nullptr; return result; } mpt::PathString Context::PathToWindows(std::string hostPath) { mpt::PathString result; if(hostPath.empty()) { return result; } if(hostPath.length() >= 32000) { throw mpt::Wine::Exception("Path too long."); } LPWSTR tmp = nullptr; tmp = wine_get_dos_file_name(hostPath.c_str()); if(!tmp) { throw mpt::Wine::Exception("Wine kernel32.dll:wine_get_dos_file_name failed."); } result = mpt::PathString::FromNative(tmp); HeapFree(GetProcessHeap(), 0, tmp); tmp = nullptr; return result; } std::string Context::PathToPosixCanonical(mpt::PathString windowsPath) { std::string result; std::string hostPath = PathToPosix(windowsPath); if(hostPath.empty()) { return result; } std::string output; std::string error; int exitcode = ExecutePosixShellCommand(std::string() + "readlink -f " + EscapePosixShell(hostPath), output, error); if(!error.empty()) { throw mpt::Wine::Exception("Wine readlink failed: " + error); } if(exitcode != 0 && exitcode != 1) { throw mpt::Wine::Exception("Wine readlink failed."); } std::string trimmedOutput = mpt::String::Trim(output, std::string("\r\n")); result = trimmedOutput; return result; } static void ExecutePosixCommandProgressDefault(void * /*userdata*/ ) { ::Sleep(10); return; } static ExecuteProgressResult ExecutePosixShellScriptProgressDefault(void * /*userdata*/ ) { ::Sleep(10); return ExecuteProgressContinueWaiting; } std::string Context::EscapePosixShell(std::string line) { const char escape_chars [] = { '|', '&', ';', '<', '>', '(', ')', '$', '`', '"', '\'', ' ', '\t' }; const char maybe_escape_chars [] = { '*', '?', '[', '#', '~', '=', '%' }; line = mpt::String::Replace(line, "\\", "\\\\"); for(std::size_t i = 0; i < mpt::size(escape_chars); ++i) { line = mpt::String::Replace(line, std::string(1, escape_chars[i]), "\\" + std::string(1, escape_chars[i])); } for(std::size_t i = 0; i < mpt::size(maybe_escape_chars); ++i) { line = mpt::String::Replace(line, std::string(1, maybe_escape_chars[i]), "\\" + std::string(1, maybe_escape_chars[i])); } return line; } ExecResult Context::ExecutePosixShellScript(std::string script, FlagSet flags, std::map > filetree, std::string title, ExecutePosixCommandProgress progress, ExecutePosixShellScriptProgress progressCancel, void *userdata) { // Relevant documentation: // https://stackoverflow.com/questions/6004070/execute-shell-commands-from-program-running-in-wine // https://www.winehq.org/pipermail/wine-bugs/2014-January/374918.html // https://bugs.winehq.org/show_bug.cgi?id=34730 if(!progress) progress = &ExecutePosixCommandProgressDefault; if(!progressCancel) progressCancel = &ExecutePosixShellScriptProgressDefault; if(flags[ExecFlagInteractive]) flags.reset(ExecFlagSilent); if(flags[ExecFlagSplitOutput]) flags.set(ExecFlagSilent); std::vector tempfiles; progress(userdata); mpt::TempDirGuard dirWindowsTemp(mpt::CreateTempFileName()); if(dirWindowsTemp.GetDirname().empty()) { throw mpt::Wine::Exception("Creating temporary directoy failed."); } std::string dirPosix = PathToPosix(dirWindowsTemp.GetDirname()); if(dirPosix.empty()) { throw mpt::Wine::Exception("mpt::Wine::ConvertWindowsPathToHost returned empty path."); } const mpt::PathString dirWindows = dirWindowsTemp.GetDirname(); progress(userdata); // write the script to disk mpt::PathString scriptFilenameWindows = dirWindows + MPT_PATHSTRING("script.sh"); { mpt::ofstream tempfile(scriptFilenameWindows, std::ios::binary); tempfile << script; tempfile.flush(); if(!tempfile) { throw mpt::Wine::Exception("Error writing script.sh."); } } std::string scriptFilenamePosix = PathToPosix(scriptFilenameWindows); if(scriptFilenamePosix.empty()) { throw mpt::Wine::Exception("Error converting script.sh path."); } progress(userdata); // create a wrapper that will call the script and gather result. mpt::PathString wrapperstarterFilenameWindows = dirWindows + MPT_PATHSTRING("wrapperstarter.sh"); { mpt::ofstream tempfile(wrapperstarterFilenameWindows, std::ios::binary); std::string wrapperstarterscript; wrapperstarterscript += std::string() + "#!/usr/bin/env sh" + "\n"; wrapperstarterscript += std::string() + "exec /usr/bin/env sh " + EscapePosixShell(dirPosix) + "wrapper.sh" + "\n"; tempfile << wrapperstarterscript; tempfile.flush(); if(!tempfile) { throw mpt::Wine::Exception("Error writing wrapper.sh."); } } mpt::PathString wrapperFilenameWindows = dirWindows + MPT_PATHSTRING("wrapper.sh"); std::string cleanupscript; { mpt::ofstream tempfile(wrapperFilenameWindows, std::ios::binary); std::string wrapperscript; if(!flags[ExecFlagSilent]) { wrapperscript += std::string() + "printf \"\\033]0;" + title + "\\a\"" + "\n"; } wrapperscript += std::string() + "chmod u+x " + EscapePosixShell(scriptFilenamePosix) + "\n"; wrapperscript += std::string() + "cd " + EscapePosixShell(dirPosix) + "filetree" + "\n"; if(flags[ExecFlagInteractive]) { // no stdout/stderr capturing for interactive scripts wrapperscript += std::string() + EscapePosixShell(scriptFilenamePosix) + "\n"; wrapperscript += std::string() + "MPT_RESULT=$?" + "\n"; wrapperscript += std::string() + "echo ${MPT_RESULT} > " + EscapePosixShell(dirPosix) + "exit" + "\n"; } else if(flags[ExecFlagSplitOutput]) { wrapperscript += std::string() + "(" + EscapePosixShell(scriptFilenamePosix) + "; echo $? >&4) 4>" + EscapePosixShell(dirPosix) + "exit 1>" + EscapePosixShell(dirPosix) + "out 2>" + EscapePosixShell(dirPosix) + "err" + "\n"; } else { wrapperscript += std::string() + "(" + EscapePosixShell(scriptFilenamePosix) + "; echo $? >&4) 2>&1 4>" + EscapePosixShell(dirPosix) + "exit | tee " + EscapePosixShell(dirPosix) + "out" + "\n"; } wrapperscript += std::string() + "echo done > " + EscapePosixShell(dirPosix) + "done" + "\n"; cleanupscript += std::string() + "rm " + EscapePosixShell(dirPosix) + "done" + "\n"; cleanupscript += std::string() + "rm " + EscapePosixShell(dirPosix) + "exit" + "\n"; if(flags[ExecFlagInteractive]) { // nothing } else if(flags[ExecFlagSplitOutput]) { cleanupscript += std::string() + "rm " + EscapePosixShell(dirPosix) + "out" + "\n"; cleanupscript += std::string() + "rm " + EscapePosixShell(dirPosix) + "err" + "\n"; } else { cleanupscript += std::string() + "rm " + EscapePosixShell(dirPosix) + "out" + "\n"; } cleanupscript += std::string() + "rm -r " + EscapePosixShell(dirPosix) + "filetree" + "\n"; cleanupscript += std::string() + "rm " + EscapePosixShell(dirPosix) + "script.sh" + "\n"; cleanupscript += std::string() + "rm " + EscapePosixShell(dirPosix) + "wrapper.sh" + "\n"; cleanupscript += std::string() + "rm " + EscapePosixShell(dirPosix) + "wrapperstarter.sh" + "\n"; cleanupscript += std::string() + "rm " + EscapePosixShell(dirPosix) + "terminal.sh" + "\n"; if(flags[ExecFlagAsync]) { wrapperscript += cleanupscript; cleanupscript.clear(); } tempfile << wrapperscript; tempfile.flush(); if(!tempfile) { throw mpt::Wine::Exception("Error writing wrapper.sh."); } } progress(userdata); ::CreateDirectoryW((dirWindows + MPT_PATHSTRING("filetree")).AsNative().c_str(), NULL); for(const auto &file : filetree) { std::vector path = mpt::String::Split(mpt::ToUnicode(mpt::CharsetUTF8, file.first), MPT_USTRING("/")); mpt::PathString combinedPath = dirWindows + MPT_PATHSTRING("filetree") + MPT_PATHSTRING("\\"); if(path.size() > 1) { for(std::size_t singlepath = 0; singlepath < path.size() - 1; ++singlepath) { if(path[singlepath].empty()) { continue; } combinedPath += mpt::PathString::FromUnicode(path[singlepath]); if(!combinedPath.IsDirectory()) { if(::CreateDirectoryW(combinedPath.AsNative().c_str(), NULL) == 0) { throw mpt::Wine::Exception("Error writing filetree."); } } combinedPath += MPT_PATHSTRING("\\"); } } try { mpt::LazyFileRef out(dirWindows + MPT_PATHSTRING("filetree") + MPT_PATHSTRING("\\") + mpt::PathString::FromUTF8(mpt::String::Replace(file.first, "/", "\\"))); out = file.second; } catch(std::exception &) { throw mpt::Wine::Exception("Error writing filetree."); } } progress(userdata); // create a wrapper that will find a suitable terminal and run the wrapper script in the terminal window. mpt::PathString terminalWrapperFilenameWindows = dirWindows + MPT_PATHSTRING("terminal.sh"); { mpt::ofstream tempfile(terminalWrapperFilenameWindows, std::ios::binary); // NOTE: // Modern terminals detach themselves from the invoking shell if another instance is already present. // This means we cannot rely on terminal invocation being syncronous. std::vector terminals; terminals.push_back("x-terminal-emulator"); terminals.push_back("konsole"); terminals.push_back("mate-terminal"); terminals.push_back("xfce4-terminal"); terminals.push_back("gnome-terminal"); terminals.push_back("uxterm"); terminals.push_back("xterm"); terminals.push_back("rxvt"); std::map terminalLanchers; for(std::size_t i = 0; i < terminals.size(); ++i) { // mate-terminal on Debian 8 cannot execute commands with arguments, // thus we use a separate script that requires no arguments to execute. terminalLanchers[terminals[i]] += std::string() + "if command -v " + terminals[i] + " 2>/dev/null 1>/dev/null ; then" + "\n"; terminalLanchers[terminals[i]] += std::string() + " chmod u+x " + EscapePosixShell(dirPosix) + "wrapperstarter.sh" + "\n"; terminalLanchers[terminals[i]] += std::string() + " exec `command -v " + terminals[i] + "` -e \"" + EscapePosixShell(dirPosix) + "wrapperstarter.sh\"" + "\n"; terminalLanchers[terminals[i]] += std::string() + "fi" + "\n"; } std::string terminalscript; terminalscript += std::string() + "\n"; for(std::size_t i = 0; i < terminals.size(); ++i) { terminalscript += terminalLanchers[terminals[i]]; } tempfile << terminalscript; tempfile.flush(); if(!tempfile) { return ExecResult::Error(); } } progress(userdata); // build unix command line std::string unixcommand; bool createProcessSuccess = false; if(!createProcessSuccess) { if(flags[ExecFlagSilent]) { unixcommand = "/usr/bin/env sh \"" + EscapePosixShell(dirPosix) + "wrapper.sh\""; } else { unixcommand = "/usr/bin/env sh \"" + EscapePosixShell(dirPosix) + "terminal.sh\""; } progress(userdata); std::wstring unixcommandW = mpt::ToWide(mpt::CharsetUTF8, unixcommand); std::vector commandline = std::vector(unixcommandW.data(), unixcommandW.data() + unixcommandW.length() + 1); std::wstring titleW = mpt::ToWide(mpt::CharsetUTF8, title); std::vector titleWv = std::vector(titleW.data(), titleW.data() + titleW.length() + 1); STARTUPINFOW startupInfo; MemsetZero(startupInfo); startupInfo.lpTitle = &titleWv[0]; startupInfo.cb = sizeof(startupInfo); PROCESS_INFORMATION processInformation; MemsetZero(processInformation); progress(userdata); BOOL success = FALSE; if(flags[ExecFlagSilent]) { success = CreateProcessW(NULL, &commandline[0], NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, &startupInfo, &processInformation); } else { success = CreateProcessW(NULL, &commandline[0], NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startupInfo, &processInformation); } progress(userdata); createProcessSuccess = (success ? true : false); progress(userdata); if(success) { if(!flags[ExecFlagAsync]) { // note: execution is not syncronous with all Wine versions, // we additionally explicitly wait for "done" later while(WaitForSingleObject(processInformation.hProcess, 0) == WAIT_TIMEOUT) { // wait if(progressCancel(userdata) != ExecuteProgressContinueWaiting) { CloseHandle(processInformation.hThread); CloseHandle(processInformation.hProcess); throw mpt::Wine::Exception("Canceled."); } } } progress(userdata); CloseHandle(processInformation.hThread); CloseHandle(processInformation.hProcess); } } progress(userdata); // Work around Wine being able to execute PIE binaries on Debian 9. // Luckily, /bin/bash is still non-PIE on Debian 9. if(!createProcessSuccess) { if(flags[ExecFlagSilent]) { unixcommand = "/bin/bash \"" + EscapePosixShell(dirPosix) + "wrapper.sh\""; } else { unixcommand = "/bin/bash \"" + EscapePosixShell(dirPosix) + "terminal.sh\""; } progress(userdata); std::wstring unixcommandW = mpt::ToWide(mpt::CharsetUTF8, unixcommand); std::vector commandline = std::vector(unixcommandW.data(), unixcommandW.data() + unixcommandW.length() + 1); std::wstring titleW = mpt::ToWide(mpt::CharsetUTF8, title); std::vector titleWv = std::vector(titleW.data(), titleW.data() + titleW.length() + 1); STARTUPINFOW startupInfo; MemsetZero(startupInfo); startupInfo.lpTitle = &titleWv[0]; startupInfo.cb = sizeof(startupInfo); PROCESS_INFORMATION processInformation; MemsetZero(processInformation); progress(userdata); BOOL success = FALSE; if(flags[ExecFlagSilent]) { success = CreateProcessW(NULL, &commandline[0], NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, &startupInfo, &processInformation); } else { success = CreateProcessW(NULL, &commandline[0], NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startupInfo, &processInformation); } progress(userdata); createProcessSuccess = (success ? true : false); progress(userdata); if(success) { if(!flags[ExecFlagAsync]) { // note: execution is not syncronous with all Wine versions, // we additionally explicitly wait for "done" later while(WaitForSingleObject(processInformation.hProcess, 0) == WAIT_TIMEOUT) { // wait if(progressCancel(userdata) != ExecuteProgressContinueWaiting) { CloseHandle(processInformation.hThread); CloseHandle(processInformation.hProcess); throw mpt::Wine::Exception("Canceled."); } } } progress(userdata); CloseHandle(processInformation.hThread); CloseHandle(processInformation.hProcess); } } progress(userdata); if(!createProcessSuccess) { throw mpt::Wine::Exception("CreateProcess failed."); } progress(userdata); if(flags[ExecFlagAsync]) { ExecResult result; result.exitcode = 0; return result; } while(!(dirWindows + MPT_PATHSTRING("done")).IsFile()) { // wait if(progressCancel(userdata) != ExecuteProgressContinueWaiting) { throw mpt::Wine::Exception("Canceled."); } } progress(userdata); int exitCode = 0; { mpt::ifstream exitFile(dirWindows + MPT_PATHSTRING("exit"), std::ios::binary); if(!exitFile) { throw mpt::Wine::Exception("Script .exit file not found."); } std::string exitString; exitFile >> exitString; if(exitString.empty()) { throw mpt::Wine::Exception("Script .exit file empty."); } exitCode = ConvertStrTo(exitString); } progress(userdata); std::string outputString; if(!flags[ExecFlagInteractive]) { mpt::ifstream outputFile(dirWindows + MPT_PATHSTRING("out"), std::ios::binary); if(outputFile) { outputFile.seekg(0, std::ios::end); std::streampos outputFileSize = outputFile.tellg(); outputFile.seekg(0, std::ios::beg); std::vector outputFileBuf(mpt::saturate_cast(static_cast(outputFileSize))); outputFile.read(&outputFileBuf[0], outputFileBuf.size()); outputString = std::string(outputFileBuf.begin(), outputFileBuf.end()); } } progress(userdata); std::string errorString; if(flags[ExecFlagSplitOutput]) { mpt::ifstream errorFile(dirWindows + MPT_PATHSTRING("err"), std::ios::binary); if(errorFile) { errorFile.seekg(0, std::ios::end); std::streampos errorFileSize = errorFile.tellg(); errorFile.seekg(0, std::ios::beg); std::vector errorFileBuf(mpt::saturate_cast(static_cast(errorFileSize))); errorFile.read(&errorFileBuf[0], errorFileBuf.size()); errorString = std::string(errorFileBuf.begin(), errorFileBuf.end()); } } progress(userdata); ExecResult result; result.exitcode = exitCode; result.output = outputString; result.error = errorString; std::deque paths; paths.push_back(dirWindows + MPT_PATHSTRING("filetree")); mpt::PathString basePath = (dirWindows + MPT_PATHSTRING("filetree")).EnsureTrailingSlash(); while(!paths.empty()) { mpt::PathString path = paths.front(); paths.pop_front(); path.EnsureTrailingSlash(); HANDLE hFind = NULL; WIN32_FIND_DATAW wfd; MemsetZero(wfd); hFind = FindFirstFileW((path + MPT_PATHSTRING("*.*")).AsNative().c_str(), &wfd); if(hFind != NULL && hFind != INVALID_HANDLE_VALUE) { do { mpt::PathString filename = mpt::PathString::FromNative(wfd.cFileName); if(filename != MPT_PATHSTRING(".") && filename != MPT_PATHSTRING("..")) { filename = path + filename; filetree[filename.ToUTF8()] = std::vector(); if(filename.IsDirectory()) { paths.push_back(filename); } else if(filename.IsFile()) { try { mpt::LazyFileRef f(filename); std::vector buf = f; mpt::PathString treeFilename = mpt::PathString::FromNative(filename.AsNative().substr(basePath.AsNative().length())); result.filetree[treeFilename.ToUTF8()] = buf; } catch (std::exception &) { // nothing?! } } } } while(FindNextFileW(hFind, &wfd)); FindClose(hFind); } } mpt::DeleteWholeDirectoryTree(dirWindows); return result; } int Context::ExecutePosixShellCommand(std::string command, std::string & output, std::string & error) { std::string script; script += std::string() + "#!/usr/bin/env sh" + "\n"; script += std::string() + "exec " + command + "\n"; mpt::Wine::ExecResult execResult = ExecutePosixShellScript ( script , mpt::Wine::ExecFlagSilent | mpt::Wine::ExecFlagSplitOutput, std::map >() , std::string() , nullptr , nullptr , nullptr ); output = execResult.output; error = execResult.error; return execResult.exitcode; } std::string Context::GetPosixEnvVar(std::string var, std::string def) { // We cannot use std::getenv here because Wine overrides SOME env vars, // in particular, HOME is unset in the Wine environment. // Instead, we just spawn a shell that will catch up a sane environment on // its own. std::string output; std::string error; int exitcode = ExecutePosixShellCommand(std::string() + "echo $" + var, output, error); if(!error.empty()) { throw mpt::Wine::Exception("Wine echo $var failed: " + error); } if(exitcode != 0) { throw mpt::Wine::Exception("Wine echo $var failed."); } std::string result = mpt::String::RTrim(output, std::string("\r\n")); if(result.empty()) { result = def; } return result; } } // namespace Wine } // namespace mpt #else // !(MODPLUG_TRACKER && MPT_OS_WINDOWS) MPT_MSVC_WORKAROUND_LNK4221(mptWine) #endif // MODPLUG_TRACKER && MPT_OS_WINDOWS OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/misc_util.h0000644000372100037210000010067313202101275017707 00000000000000/* * misc_util.h * ----------- * Purpose: Various useful utility functions. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "mptStringParse.h" #include "mptCPU.h" #include "mptOS.h" #include "mptTime.h" #include "mptLibrary.h" #include "mptTypeTraits.h" #include #include #include #include #include #include #include #include #include OPENMPT_NAMESPACE_BEGIN // cmath fixups #ifndef M_PI #define M_PI 3.14159265358979323846 #endif #ifndef M_PI_2 #define M_PI_2 1.57079632679489661923 #endif #ifndef M_LN2 #define M_LN2 0.69314718055994530942 #endif namespace mpt { namespace String { // Combine a vector of values into a string, separated with the given separator. // No escaping is performed. template mpt::ustring Combine(const std::vector &vals, const mpt::ustring &sep=MPT_USTRING(",")) { mpt::ustring str; for(std::size_t i = 0; i < vals.size(); ++i) { if(i > 0) { str += sep; } str += mpt::ufmt::val(vals[i]); } return str; } template std::string Combine(const std::vector &vals, const std::string &sep=std::string(",")) { std::string str; for(std::size_t i = 0; i < vals.size(); ++i) { if(i > 0) { str += sep; } str += mpt::fmt::val(vals[i]); } return str; } // Split the given string at separator positions into individual values returned as a vector. // An empty string results in an empty vector. // Leading or trailing separators result in a default-constructed element being inserted before or after the other elements. template std::vector Split(const mpt::ustring &str, const mpt::ustring &sep=MPT_USTRING(",")) { std::vector vals; std::size_t pos = 0; while(str.find(sep, pos) != std::string::npos) { vals.push_back(ConvertStrTo(str.substr(pos, str.find(sep, pos) - pos))); pos = str.find(sep, pos) + sep.length(); } if(!vals.empty() || (str.substr(pos).length() > 0)) { vals.push_back(ConvertStrTo(str.substr(pos))); } return vals; } template std::vector Split(const std::string &str, const std::string &sep=std::string(",")) { std::vector vals; std::size_t pos = 0; while(str.find(sep, pos) != std::string::npos) { vals.push_back(ConvertStrTo(str.substr(pos, str.find(sep, pos) - pos))); pos = str.find(sep, pos) + sep.length(); } if(!vals.empty() || (str.substr(pos).length() > 0)) { vals.push_back(ConvertStrTo(str.substr(pos))); } return vals; } } } // namespace mpt::String namespace mpt { // GCC 4.5 and up provides templated overloads of std::abs that convert // integer type narrower than int to double. // As this is apparently valid by the current standard, Library Working Group // Issue #2735 has been filed (see // ). // In any case, avoid this insanity and provide our own mpt::abs implementation // for signed integer and floating point types. // Note: We stick to a C++98-style implementation only overloading int and // greater types in order to keep promotion rules consistent for narrower types, // which a templated version returning the argument type would not do. OpenMPT // probably assumes this semantic when calling abs(int8) in various places. inline int abs(int x) { return std::abs(x); } inline long abs(long x) { return std::abs(x); } inline long long abs(long long x) { return std::abs(x); } inline float abs(float x) { return std::fabs(x); } inline double abs(double x) { return std::fabs(x); } inline long double abs(long double x) { return std::fabs(x); } // Modulo with more intuitive behaviour for some contexts: // Instead of being symmetrical around 0, the pattern for positive numbers is repeated in the negative range. // For example, wrapping_modulo(-1, m) == (m - 1). // Behaviour is undefined if m<=0. template MPT_CONSTEXPR11_FUN auto wrapping_modulo(T x, M m) -> decltype(x % m) { return (x >= 0) ? (x % m) : (m - 1 - ((-1 - x) % m)); } template MPT_CONSTEXPR11_FUN auto wrapping_divide(T x, D d) -> decltype(x / d) { return (x >= 0) ? (x / d) : (((x + 1) / d) - 1); } } // namespace mpt // Memset given object to zero. template inline void MemsetZero(T &a) { static_assert(std::is_pointer::value == false, "Won't memset pointers."); #if MPT_GCC_BEFORE(5,1,0) || MPT_CLANG_BEFORE(3,5,0) || (MPT_COMPILER_CLANG && defined(__GLIBCXX__)) MPT_STATIC_ASSERT(std::is_standard_layout::value); MPT_STATIC_ASSERT(std::is_trivial::value); // approximation #else // default MPT_STATIC_ASSERT(std::is_standard_layout::value); MPT_STATIC_ASSERT(std::is_trivially_copyable::value); // C++11, but not supported on most compilers we care about #endif std::memset(&a, 0, sizeof(T)); } #ifdef MODPLUG_TRACKER // Copy given object to other location. template void MemCopy(T &destination, const T &source) { static_assert(std::is_pointer::value == false, "Won't copy pointers."); #if MPT_GCC_BEFORE(5,1,0) || MPT_CLANG_BEFORE(3,5,0) || (MPT_COMPILER_CLANG && defined(__GLIBCXX__)) MPT_STATIC_ASSERT(std::is_trivial::value); // approximation #else // default MPT_STATIC_ASSERT(std::is_trivially_copyable::value); // C++11, but not supported on most compilers we care about #endif std::memcpy(&destination, &source, sizeof(T)); } #endif // MODPLUG_TRACKER namespace mpt { // Simplified version of gsl::span. // Non-owning read-only or read-write view into a contiguous block of T // objects, i.e. equivalent to a (beg,end) or (data,size) tuple. // Can eventually be replaced without further modifications with a full // gsl::span. template class span { public: typedef std::size_t size_type; typedef T value_type; typedef T & reference; typedef T * pointer; typedef const T * const_pointer; typedef const T & const_reference; typedef pointer iterator; typedef const_pointer const_iterator; typedef typename std::iterator_traits::difference_type difference_type; private: T * m_beg; T * m_end; public: span() : m_beg(nullptr), m_end(nullptr) { } span(pointer beg, pointer end) : m_beg(beg), m_end(end) { } span(pointer data, size_type size) : m_beg(data), m_end(data + size) { } template span(U (&arr)[N]) : m_beg(arr), m_end(arr + N) { } template span(Cont &cont) : m_beg(cont.empty() ? nullptr : &(cont[0])), m_end(cont.empty() ? nullptr : &(cont[0]) + cont.size()) { } span(const span &other) : m_beg(other.begin()), m_end(other.end()) { } template span(const span &other) : m_beg(other.begin()), m_end(other.end()) { } span & operator = (span other) { m_beg = other.begin(); m_end = other.end(); return *this; } iterator begin() const { return iterator(m_beg); } iterator end() const { return iterator(m_end); } const_iterator cbegin() const { return const_iterator(begin()); } const_iterator cend() const { return const_iterator(end()); } operator bool () const throw() { return m_beg != nullptr; } reference operator[](size_type index) { return at(index); } const_reference operator[](size_type index) const { return at(index); } bool operator==(span const & other) const throw() { return size() == other.size() && (m_beg == other.m_beg || std::equal(begin(), end(), other.begin())); } bool operator!=(span const & other) const throw() { return !(*this == other); } reference at(size_type index) { return m_beg[index]; } const_reference at(size_type index) const { return m_beg[index]; } pointer data() const throw() { return m_beg; } bool empty() const throw() { return size() == 0; } size_type size() const throw() { return std::distance(m_beg, m_end); } size_type length() const throw() { return size(); } }; // class span template inline span as_span(T * beg, T * end) { return span(beg, end); } template inline span as_span(T * data, std::size_t size) { return span(data, size); } template inline span as_span(T (&arr)[N]) { return span(std::begin(arr), std::end(arr)); } template inline span as_span(std::vector & cont) { return span(cont); } template inline span as_span(const std::vector & cont) { return span(cont); } template inline span as_span(std::basic_string & str) { return span(&(str[0]), str.length()); } template inline span as_span(const std::basic_string & str) { return span(&(str[0]), str.length()); } typedef mpt::span byte_span; typedef mpt::span const_byte_span; template inline std::vector::type> make_vector(T * beg, T * end) { return std::vector::type>(beg, end); } template inline std::vector::type> make_vector(T * data, std::size_t size) { return std::vector::type>(data, data + size); } template inline std::vector::type> make_vector(mpt::span data) { return std::vector::type>(data.data(), data.data() + data.size()); } template inline std::vector::type> make_vector(T (&arr)[N]) { return std::vector::type>(std::begin(arr), std::end(arr)); } template inline std::vector::type> make_vector(const std::basic_string & str) { return std::vector::type>(str.begin(), str.end()); } template struct byte_cast_impl { inline Tdst operator () (Tsrc src) const { STATIC_ASSERT(sizeof(Tsrc) == sizeof(mpt::byte)); STATIC_ASSERT(sizeof(Tdst) == sizeof(mpt::byte)); // not checking is_byte_castable here because we are actually // doing a static_cast and converting the value STATIC_ASSERT(std::is_integral::value); STATIC_ASSERT(std::is_integral::value); return static_cast(src); } }; template struct byte_cast_impl, mpt::span > { inline mpt::span operator () (mpt::span src) const { STATIC_ASSERT(sizeof(Tsrc) == sizeof(mpt::byte)); STATIC_ASSERT(sizeof(Tdst) == sizeof(mpt::byte)); STATIC_ASSERT(mpt::is_byte_castable::value); STATIC_ASSERT(mpt::is_byte_castable::value); STATIC_ASSERT(std::is_integral::value); STATIC_ASSERT(std::is_integral::value); return mpt::as_span(mpt::byte_cast_impl()(src.begin()), mpt::byte_cast_impl()(src.end())); } }; template struct byte_cast_impl { inline Tdst* operator () (Tsrc* src) const { STATIC_ASSERT(sizeof(Tsrc) == sizeof(mpt::byte)); STATIC_ASSERT(sizeof(Tdst) == sizeof(mpt::byte)); STATIC_ASSERT(mpt::is_byte_castable::value); STATIC_ASSERT(mpt::is_byte_castable::value); STATIC_ASSERT(std::is_integral::value); STATIC_ASSERT(std::is_integral::value); return reinterpret_cast(src); } }; template struct void_cast_impl; template struct void_cast_impl { inline Tdst* operator () (void* src) const { STATIC_ASSERT(sizeof(Tdst) == sizeof(mpt::byte)); STATIC_ASSERT(mpt::is_byte_castable::value); STATIC_ASSERT(std::is_integral::value); return reinterpret_cast(src); } }; template struct void_cast_impl { inline Tdst* operator () (const void* src) const { STATIC_ASSERT(sizeof(Tdst) == sizeof(mpt::byte)); STATIC_ASSERT(mpt::is_byte_castable::value); STATIC_ASSERT(std::is_integral::value); return reinterpret_cast(src); } }; template struct void_cast_impl { inline void* operator () (Tsrc* src) const { STATIC_ASSERT(sizeof(Tsrc) == sizeof(mpt::byte)); STATIC_ASSERT(mpt::is_byte_castable::value); STATIC_ASSERT(std::is_integral::value); return reinterpret_cast(src); } }; template struct void_cast_impl { inline const void* operator () (Tsrc* src) const { STATIC_ASSERT(sizeof(Tsrc) == sizeof(mpt::byte)); STATIC_ASSERT(mpt::is_byte_castable::value); STATIC_ASSERT(std::is_integral::value); return reinterpret_cast(src); } }; // casts between different byte (char) types or pointers to these types template inline Tdst byte_cast(Tsrc src) { return byte_cast_impl()(src); } // casts between pointers to void and pointers to byte template inline Tdst void_cast(Tsrc src) { return void_cast_impl()(src); } // Saturate the value of src to the domain of Tdst template inline Tdst saturate_cast(Tsrc src) { // This code tries not only to obviously avoid overflows but also to avoid signed/unsigned comparison warnings and type truncation warnings (which in fact would be safe here) by explicit casting. STATIC_ASSERT(std::numeric_limits::is_integer); STATIC_ASSERT(std::numeric_limits::is_integer); MPT_CONSTANT_IF(std::numeric_limits::is_signed && std::numeric_limits::is_signed) { MPT_CONSTANT_IF(sizeof(Tdst) >= sizeof(Tsrc)) { return static_cast(src); } return static_cast(std::max(static_cast(std::numeric_limits::min()), std::min(src, static_cast(std::numeric_limits::max())))); } else MPT_CONSTANT_IF(!std::numeric_limits::is_signed && !std::numeric_limits::is_signed) { MPT_CONSTANT_IF(sizeof(Tdst) >= sizeof(Tsrc)) { return static_cast(src); } return static_cast(std::min(src, static_cast(std::numeric_limits::max()))); } else MPT_CONSTANT_IF(std::numeric_limits::is_signed && !std::numeric_limits::is_signed) { MPT_CONSTANT_IF(sizeof(Tdst) > sizeof(Tsrc)) { return static_cast(src); } MPT_CONSTANT_IF(sizeof(Tdst) == sizeof(Tsrc)) { return static_cast(std::min(src, static_cast(std::numeric_limits::max()))); } return static_cast(std::min(src, static_cast(std::numeric_limits::max()))); } else // Tdst unsigned, Tsrc signed { MPT_CONSTANT_IF(sizeof(Tdst) >= sizeof(Tsrc)) { return static_cast(std::max(0, src)); } return static_cast(std::max(0, std::min(src, static_cast(std::numeric_limits::max())))); } } template inline Tdst saturate_cast(double src) { if(src >= std::numeric_limits::max()) { return std::numeric_limits::max(); } if(src <= std::numeric_limits::min()) { return std::numeric_limits::min(); } return static_cast(src); } template inline Tdst saturate_cast(float src) { if(src >= std::numeric_limits::max()) { return std::numeric_limits::max(); } if(src <= std::numeric_limits::min()) { return std::numeric_limits::min(); } return static_cast(src); } } // namespace mpt #if defined(MODPLUG_TRACKER) // Tracker code requires MIN/MAX to work in constexpr contexts. // We could make MIN/MAX constexpr for supporting compilers, // but that would just needlessly complicate the support matrix // for now. #ifndef MPT_MINMAX_MACROS #define MPT_MINMAX_MACROS #endif #endif #if MPT_COMPILER_MSVC // MSVC disables a bunch of type conversion warnings once a macro is involved. // Replacing the macro with a template thus spews a TON OF WARNINGS for now. #ifndef MPT_MINMAX_MACROS #define MPT_MINMAX_MACROS #endif #endif #if defined(MPT_MINMAX_MACROS) #define MAX(a,b) (((a) > (b)) ? (a) : (b)) #define MIN(a,b) (((a) < (b)) ? (a) : (b)) #else namespace mpt { namespace Legacy { template MPT_FORCEINLINE auto MAX(const Ta &a, const Tb &b) -> decltype((a>b)?a:b) { return (a > b) ? a : b; } template MPT_FORCEINLINE auto MIN(const Ta &a, const Tb &b) -> decltype((a struct ModIfNotZeroImpl { template inline Tval mod(Tval x) { STATIC_ASSERT(std::numeric_limits::is_integer); STATIC_ASSERT(!std::numeric_limits::is_signed); STATIC_ASSERT(std::numeric_limits::is_integer); STATIC_ASSERT(!std::numeric_limits::is_signed); return static_cast(x % m); } }; template <> struct ModIfNotZeroImpl { template inline Tval mod(Tval x) { return x; } }; template <> struct ModIfNotZeroImpl { template inline Tval mod(Tval x) { return x; } }; template <> struct ModIfNotZeroImpl { template inline Tval mod(Tval x) { return x; } }; template <> struct ModIfNotZeroImpl { template inline Tval mod(Tval x) { return x; } }; } // namespace detail // Returns x % m if m != 0, x otherwise. // i.e. "return (m == 0) ? x : (x % m);", but without causing a warning with stupid older compilers template inline Tval ModIfNotZero(Tval x) { return detail::ModIfNotZeroImpl().mod(x); } // Returns true iff Tdst can represent the value val. // Use as if(Util::TypeCanHoldValue(-1)). template inline bool TypeCanHoldValue(Tsrc val) { return (static_cast(mpt::saturate_cast(val)) == val); } // Grows x with an exponential factor suitable for increasing buffer sizes. // Clamps the result at limit. // And avoids integer overflows while doing its business. // The growth factor is 1.5, rounding down, execpt for the initial x==1 case. template inline T ExponentialGrow(const T &x, const Tlimit &limit) { MPT_ASSERT(x > 0); MPT_ASSERT(limit > 0); if(x == 1) { return 2; } T add = std::min(x >> 1, std::numeric_limits::max() - x); return std::min(x + add, mpt::saturate_cast(limit)); } template inline T ExponentialGrow(const T &x) { return Util::ExponentialGrow(x, std::numeric_limits::max()); } } //namespace Util namespace mpt { // C++17 clamp template MPT_CONSTEXPR11_FUN const T & clamp(const T & v, const T & lo, const T & hi, Compare comp) { return comp(v, lo) ? lo : comp(hi, v) ? hi : v; } template MPT_CONSTEXPR11_FUN const T & clamp(const T & v, const T & lo, const T & hi) { return mpt::clamp(v, lo, hi, std::less()); } } // namespace mpt // Limits 'val' to given range. If 'val' is less than 'lowerLimit', 'val' is set to value 'lowerLimit'. // Similarly if 'val' is greater than 'upperLimit', 'val' is set to value 'upperLimit'. // If 'lowerLimit' > 'upperLimit', 'val' won't be modified. template inline void Limit(T& val, const C lowerLimit, const C upperLimit) { if(lowerLimit > upperLimit) return; if(val < lowerLimit) val = lowerLimit; else if(val > upperLimit) val = upperLimit; } // Like Limit, but returns value template inline T Clamp(T val, const C lowerLimit, const C upperLimit) { if(val < lowerLimit) return lowerLimit; else if(val > upperLimit) return upperLimit; else return val; } // Check if val is in [lo,hi] without causing compiler warnings // if theses checks are always true due to the domain of T. // GCC does not warn if the type is templated. template inline bool IsInRange(T val, C lo, C hi) { return lo <= val && val <= hi; } // Like Limit, but with upperlimit only. template inline void LimitMax(T& val, const C upperLimit) { if(val > upperLimit) val = upperLimit; } // Returns sign of a number (-1 for negative numbers, 1 for positive numbers, 0 for 0) template int sgn(T value) { return (value > T(0)) - (value < T(0)); } // mpt::rshift_signed // mpt::lshift_signed // Shift a signed integer value in a well-defined manner. // Does the same thing as MSVC would do. This is verified by the test suite. namespace mpt { template MPT_FORCEINLINE auto rshift_signed_standard(T x, int y) -> decltype(x >> y) { MPT_STATIC_ASSERT(std::numeric_limits::is_integer); MPT_STATIC_ASSERT(std::numeric_limits::is_signed); typedef decltype(x >> y) result_type; typedef typename std::make_unsigned::type unsigned_result_type; const unsigned_result_type roffset = static_cast(1) << ((sizeof(result_type) * 8) - 1); result_type rx = x; unsigned_result_type urx = static_cast(rx); urx += roffset; urx >>= y; urx -= roffset >> y; return static_cast(urx); } template MPT_FORCEINLINE auto lshift_signed_standard(T x, int y) -> decltype(x << y) { MPT_STATIC_ASSERT(std::numeric_limits::is_integer); MPT_STATIC_ASSERT(std::numeric_limits::is_signed); typedef decltype(x << y) result_type; typedef typename std::make_unsigned::type unsigned_result_type; const unsigned_result_type roffset = static_cast(1) << ((sizeof(result_type) * 8) - 1); result_type rx = x; unsigned_result_type urx = static_cast(rx); urx += roffset; urx <<= y; urx -= roffset << y; return static_cast(urx); } #if MPT_COMPILER_SHIFT_SIGNED template MPT_FORCEINLINE auto rshift_signed_undefined(T x, int y) -> decltype(x >> y) { MPT_STATIC_ASSERT(std::numeric_limits::is_integer); MPT_STATIC_ASSERT(std::numeric_limits::is_signed); return x >> y; } template MPT_FORCEINLINE auto lshift_signed_undefined(T x, int y) -> decltype(x << y) { MPT_STATIC_ASSERT(std::numeric_limits::is_integer); MPT_STATIC_ASSERT(std::numeric_limits::is_signed); return x << y; } template MPT_FORCEINLINE auto rshift_signed(T x, int y) -> decltype(x >> y) { return mpt::rshift_signed_undefined(x, y); } template MPT_FORCEINLINE auto lshift_signed(T x, int y) -> decltype(x << y) { return mpt::lshift_signed_undefined(x, y); } #else template MPT_FORCEINLINE auto rshift_signed(T x, int y) -> decltype(x >> y) { return mpt::rshift_signed_standard(x, y); } template MPT_FORCEINLINE auto lshift_signed(T x, int y) -> decltype(x << y) { return mpt::lshift_signed_standard(x, y); } #endif } // namespace mpt namespace Util { // Returns maximum value of given integer type. template constexpr T MaxValueOfType(const T&) {static_assert(std::numeric_limits::is_integer == true, "Only integer types are allowed."); return (std::numeric_limits::max)();} // The following MPT_MAX_* macros are useful as std::numeric_limits is not // usable in constexpr-like contexts like static_assert in pre-C++11 // compilers. // Returns the maximum value for the signed type or expression at compile time. #define MPT_MAX_SIGNED_VALUE(integral_expression_or_type) ( ( 1ull << ( sizeof(integral_expression_or_type) * 8 - 1 ) ) - 1 ) // Returns the maximum value for the unsigned type or expression at compile time. // Implemented in terms of MPT_MAX_SIGNED_VALUE in order to avoid overflow in left-shift. #define MPT_MAX_UNSIGNED_VALUE(integral_expression_or_type) ( ( MPT_MAX_SIGNED_VALUE(integral_expression_or_type) << 1 ) | 1ull ) // Return the maximum value of an integral type at compile time. #define MPT_MAX_VALUE_OF_TYPE(integral_type) ( std::numeric_limits::is_signed ? MPT_MAX_SIGNED_VALUE(integral_type) : MPT_MAX_UNSIGNED_VALUE(integral_type) ) /// Returns value rounded to nearest integer. #if (MPT_OS_EMSCRIPTEN && MPT_OS_EMSCRIPTEN_ANCIENT) // MSVC before 2013 does not support C99/C++11. // Certain emscripten versions and/or combinations with nodejs (at least the following combination: emscripten 1.34.8, clang 3.7.0, nodejs 0.10.38) fail assert(std::round(1.5)==2.0). The work-around always works. inline double Round(const double& val) {if(val >= 0.0) return std::floor(val + 0.5); else return std::ceil(val - 0.5);} inline float Round(const float& val) {if(val >= 0.0f) return std::floor(val + 0.5f); else return std::ceil(val - 0.5f);} #elif MPT_OS_ANDROID && defined(__GLIBCXX__) && !defined(_LIBCPP_VERSION) // NDK 12b gnustl_shared armeabi-v7a only provides round() in ::. // NDK 12b gnustl_shared arm64-v8a has round() in std::. // NDK 12b c++_shared armeabi-v7a has round() in std::. // Just fallback to :: for Android gnustl_shared. // This work-around can be removed once Android switches to LLVM libc++. // Currently (ndk-r12b), libc++ has problems with exceptions. inline double Round(const double& val) { return ::round(val); } inline float Round(const float& val) { return ::roundf(val); } #else inline double Round(const double& val) { return std::round(val); } inline float Round(const float& val) { return std::round(val); } #endif /// Rounds given double value to nearest integer value of type T. template inline T Round(const double& val) { static_assert(std::numeric_limits::is_integer == true, "Type is a not an integer"); const double valRounded = Round(val); MPT_ASSERT(valRounded >= (std::numeric_limits::min)() && valRounded <= (std::numeric_limits::max)()); const T intval = static_cast(valRounded); return intval; } template inline T Round(const float& val) { static_assert(std::numeric_limits::is_integer == true, "Type is a not an integer"); const float valRounded = Round(val); MPT_ASSERT(valRounded >= (std::numeric_limits::min)() && valRounded <= (std::numeric_limits::max)()); const T intval = static_cast(valRounded); return intval; } template T Weight(T x) { STATIC_ASSERT(std::numeric_limits::is_integer); T c; for(c = 0; x; x >>= 1) { c += x & 1; } return c; } } namespace Util { // Multiply two 32-bit integers, receive 64-bit result. // MSVC generates unnecessarily complicated code for the unoptimized variant using _allmul. MPT_FORCEINLINE int64 mul32to64(int32 a, int32 b) { #if MPT_COMPILER_MSVC && (defined(_M_IX86) || defined(_M_X64)) return __emul(a, b); #else return static_cast(a) * b; #endif } MPT_FORCEINLINE uint64 mul32to64_unsigned(uint32 a, uint32 b) { #if MPT_COMPILER_MSVC && (defined(_M_IX86) || defined(_M_X64)) return __emulu(a, b); #else return static_cast(a) * b; #endif } MPT_FORCEINLINE int32 muldiv(int32 a, int32 b, int32 c) { return mpt::saturate_cast( mul32to64( a, b ) / c ); } MPT_FORCEINLINE int32 muldivr(int32 a, int32 b, int32 c) { return mpt::saturate_cast( ( mul32to64( a, b ) + ( c / 2 ) ) / c ); } // Do not use overloading because catching unsigned version by accident results in slower X86 code. MPT_FORCEINLINE uint32 muldiv_unsigned(uint32 a, uint32 b, uint32 c) { return mpt::saturate_cast( mul32to64_unsigned( a, b ) / c ); } MPT_FORCEINLINE uint32 muldivr_unsigned(uint32 a, uint32 b, uint32 c) { return mpt::saturate_cast( ( mul32to64_unsigned( a, b ) + ( c / 2u ) ) / c ); } MPT_FORCEINLINE int32 muldivrfloor(int64 a, uint32 b, uint32 c) { a *= b; a += c / 2u; return (a >= 0) ? mpt::saturate_cast(a / c) : mpt::saturate_cast((a - (c - 1)) / c); } // rounds x up to multiples of target template inline T AlignUp(T x, T target) { return ((x + (target - 1)) / target) * target; } // rounds x down to multiples of target template inline T AlignDown(T x, T target) { return (x / target) * target; } // Insert a range of items [insStart, insEnd], and possibly shift item fix to the left. template void InsertItem(const T insStart, const T insEnd, T &fix) { MPT_ASSERT(insEnd >= insStart); if(fix >= insStart) { fix += (insEnd - insStart + 1); } } // Insert a range of items [insStart, insEnd], and possibly shift items in range [fixStart, fixEnd] to the right. template void InsertRange(const T insStart, const T insEnd, T &fixStart, T &fixEnd) { MPT_ASSERT(insEnd >= insStart); const T insLength = insEnd - insStart + 1; if(fixStart >= insEnd) { fixStart += insLength; } if(fixEnd >= insEnd) { fixEnd += insLength; } } // Delete a range of items [delStart, delEnd], and possibly shift item fix to the left. template void DeleteItem(const T delStart, const T delEnd, T &fix) { MPT_ASSERT(delEnd >= delStart); if(fix > delEnd) { fix -= (delEnd - delStart + 1); } } // Delete a range of items [delStart, delEnd], and possibly shift items in range [fixStart, fixEnd] to the left. template void DeleteRange(const T delStart, const T delEnd, T &fixStart, T &fixEnd) { MPT_ASSERT(delEnd >= delStart); const T delLength = delEnd - delStart + 1; if(delStart < fixStart && delEnd < fixStart) { // cut part is before loop start fixStart -= delLength; fixEnd -= delLength; } else if(delStart < fixStart && delEnd < fixEnd) { // cut part is partly before loop start fixStart = delStart; fixEnd -= delLength; } else if(delStart >= fixStart && delEnd < fixEnd) { // cut part is in the loop fixEnd -= delLength; } else if(delStart >= fixStart && delStart < fixEnd && delEnd > fixEnd) { // cut part is partly before loop end fixEnd = delStart; } } } // namespace Util namespace mpt { // Greatest Common Divisor. Always returns non-negative number. // compatible with C++17 std::gcd template inline typename std::common_type::type gcd(A a_, B b_) { typename std::common_type::type a = a_; typename std::common_type::type b = b_; if(a < 0) a = -a; if(b < 0) b = -b; for(;;) { if(a == 0) return b; b %= a; if(b == 0) return a; a %= b; } } // Least Common Multiple. Always returns non-negative number. // compatible with C++17 std::lcm template inline typename std::common_type::type lcm(A a_, B b_) { typename std::common_type::type a = a_; typename std::common_type::type b = b_; if(a < 0) a = -a; if(b < 0) b = -b; if((a | b) == 0) return 0; return a / mpt::gcd(a, b) * b; } } // namespace mpt namespace Util { template class fixed_size_queue { private: T buffer[n+1]; std::size_t read_position; std::size_t write_position; public: fixed_size_queue() : read_position(0), write_position(0) { return; } void clear() { read_position = 0; write_position = 0; } std::size_t read_size() const { if ( write_position > read_position ) { return write_position - read_position; } else if ( write_position < read_position ) { return write_position - read_position + n + 1; } else { return 0; } } std::size_t write_size() const { if ( write_position > read_position ) { return read_position - write_position + n; } else if ( write_position < read_position ) { return read_position - write_position - 1; } else { return n; } } bool push( const T & v ) { if ( !write_size() ) { return false; } buffer[write_position] = v; write_position = ( write_position + 1 ) % ( n + 1 ); return true; } bool pop() { if ( !read_size() ) { return false; } read_position = ( read_position + 1 ) % ( n + 1 ); return true; } T peek() { if ( !read_size() ) { return T(); } return buffer[read_position]; } const T * peek_p() { if ( !read_size() ) { return nullptr; } return &(buffer[read_position]); } const T * peek_next_p() { if ( read_size() < 2 ) { return nullptr; } return &(buffer[(read_position+1)%(n+1)]); } }; } // namespace Util namespace Util { std::vector HexToBin(const mpt::ustring &src); mpt::ustring BinToHex(mpt::const_byte_span src); template inline mpt::ustring BinToHex(mpt::span src) { return Util::BinToHex(mpt::byte_cast(src)); } } // namespace Util #if defined(MODPLUG_TRACKER) || (defined(LIBOPENMPT_BUILD) && defined(LIBOPENMPT_BUILD_TEST)) namespace mpt { // Wrapper around std::getenv. // Instead of returning null pointer if the environment variable is not set, // this wrapper returns the provided default value. std::string getenv(const std::string &env_var, const std::string &def = std::string()); } // namespace mpt #endif // MODPLUG_TRACKER || (LIBOPENMPT_BUILD && LIBOPENMPT_BUILD_TEST) OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/mptString.cpp0000644000372100037210000015413213161656666020267 00000000000000/* * mptString.cpp * ------------- * Purpose: Small string-related utilities, number and message formatting. * Notes : Currently none. * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "mptString.h" #include "Endianness.h" #if defined(MPT_CHARSET_CODECVTUTF8) #include #endif #if defined(MPT_CHARSET_INTERNAL) || defined(MPT_CHARSET_WIN32) #include #endif #include #include #include #include #if defined(MODPLUG_TRACKER) #include #endif // MODPLUG_TRACKER #if defined(MODPLUG_TRACKER) #include #endif // MODPLUG_TRACKER #if MPT_OS_WINDOWS #include #endif #if defined(MPT_CHARSET_ICONV) #include #include #endif OPENMPT_NAMESPACE_BEGIN /* Quick guide to the OpenMPT string type jungle ============================================= This quick guide is only meant as a hint. There may be valid reasons to not honor the recommendations found here. Staying consistent with surrounding and/or related code sections may also be important. List of string types -------------------- * std::string (OpenMPT, libopenmpt) C++ string of unspecifed 8bit encoding. Try to always document the encoding if not clear from context. Do not use unless there is an obvious reason to do so. * std::wstring (OpenMPT) UTF16 (on windows) or UTF32 (otherwise). Do not use unless there is an obvious reason to do so. * char* (OpenMPT, libopenmpt) C string of unspecified encoding. Use only for static literals or in performance critical inner loops where full control and avoidance of memory allocations is required. * wchar_t* (OpenMPT) C wide string. Use only if Unicode is required for static literals or in performance critical inner loops where full control and avoidance of memory allocation is required. * CString (OpenMPT) MFC string type, either encoded in locale/CP_ACP (if !UNICODE) or UTF16 (if UNICODE). Specify literals with _T(""). Use in MFC GUI code. * CStringA (OpenMPT) MFC ANSI string type. The encoding is always CP_ACP. Do not use unless there is an obvious reason to do so. * CStringW (OpenMPT) MFC Unicode string type. Use in MFC GUI code when explicit Unicode support is required. * mpt::PathString (OpenMPT, libopenmpt) String type representing paths and filenames. Always use for these in order to avoid potentially lossy conversions. Use MPT_PATHSTRING("") macro for literals. * mpt::ustring (OpenMPT, libopenmpt) The default unicode string type. Can be encoded in UTF8 or UTF16 or UTF32, depending on MPT_USTRING_MODE_* and sizeof(wchar_t). Literals can written as MPT_USTRING(""). Use as your default string type if no other string type is a measurably better fit. * MPT_UTF8 (OpenMPT, libopenmpt) Macro that generates a mpt::ustring from string literals containing non-ascii characters. In order to keep the source code in ascii encoding, always express non-ascii characters using explicit \x23 escaping. Note that depending on the underlying type of mpt::ustring, MPT_UTF8 *requires* a runtime conversion. Only use for string literals containing non-ascii characters (use MPT_USTRING otherwise). * MPT_ULITERAL / MPT_UCHAR / MPT_UCHAR_TYPE (OpenMPT, libopenmpt) Macros which generate string literals, char literals and the char literal type respectively. These are especially useful in constexpr contexts or global data where MPT_USTRING is either unusable or requires a global contructor to run. Do NOT use as a performance optimization in place of MPT_USTRING however, because MPT_USTRING can be converted to C++11/14 user defined literals eventually, while MPT_ULITERAL cannot because of constexpr requirements. * mpt::RawPathString (OpenMPT, libopenmpt) Internal representation of mpt::PathString. Only use for parsing path fragments. * mpt::u8string (OpenMPT, libopenmpt) Internal representation of mpt::ustring. Do not use directly. Ever. * std::basic_string (OpenMPT) Same as std::string. Do not use std::basic_string in the templated form. * std::basic_string (OpenMPT) Same as std::wstring. Do not use std::basic_string in the templated form. The following string types are available in order to avoid the need to overload functions on a huge variety of string types. Use only ever as function argument types. Note that the locale charset is not available on all libopenmpt builds (in which case the option is ignored or a sensible fallback is used; these types are always available). All these types publicly inherit from mpt::ustring and do not contain any additional state. This means that they work the same way as mpt::ustring does and do support type-slicing for both, read and write accesses. These types only add conversion constructors for all string types that have a defined encoding and for all 8bit string types using the specified encoding heuristic. * AnyUnicodeString (OpenMPT, libopenmpt) Is constructible from any Unicode string. * AnyString (OpenMPT, libopenmpt) Tries to do the smartest auto-magic we can do. * AnyLocaleString (OpenMPT, libopenmpt) char-based strings are assumed to be in locale encoding. * AnyStringUTF8orLocale (OpenMPT, libopenmpt) char-based strings are tried in UTF8 first, if this fails, locale is used. * AnyStringUTF8 (OpenMPT, libopenmpt) char-based strings are assumed to be in UTF8. Encoding of 8bit strings ------------------------ 8bit strings have an unspecified encoding. When the string is contained within a CSoundFile object, the encoding is most likely CSoundFile::GetCharsetInternal(), otherwise, try to gather the most probable encoding from surrounding or related code sections. Decision tree to help deciding which string type to use ------------------------------------------------------- if in libopenmpt if in libopenmpt c++ interface T = std::string, the encoding is utf8 elif in libopenmpt c interface T = char*, the encoding is utf8 elif performance critical inner loop T = char*, document the encoding if not clear from context elif string literal containing non-ascii characters T = MPT_UTF8 elif path or file if parsing path fragments T = mpt::RawPathString template your function on the concrete underlying string type (std::string and std::wstring) or use preprocessor MPT_OS_WINDOWS else T = mpt::PathString fi else T = mpt::ustring fi else if performance critical inner loop if needs unicode support T = MPT_UCHAR_TYPE* / MPT_ULITERAL else T = char*, document the encoding if not clear from context fi elif string literal containing non-ascii characters T = MPT_UTF8 elif path or file if parsing path fragments T = mpt::RawPathString template your function on the concrete underlying string type (std::string and std::wstring) or use preprocessor MPT_OS_WINDOWS else T = mpt::PathString fi elif mfc/gui code if directly interface with wide winapi T = CStringW elif needs unicode support T = CStringW else T = CString fi else if directly interfacing with wide winapi T = std::wstring else if constexpr context or global data T = MPT_UCHAR_TYPE* / MPT_ULITERAL else T = mpt::ustring fi fi fi fi This boils down to: Prefer mpt::PathString and mpt::ustring, and only use any other string type if there is an obvious reason to do so. Character set conversions ------------------------- Character set conversions in OpenMPT are always fuzzy. Behaviour in case of an invalid source encoding and behaviour in case of an unrepresentable destination encoding can be any of the following: * The character is replaced by some replacement character ('?' or L'\ufffd' in most cases). * The character is replaced by a similar character (either semantically similiar or visually similar). * The character is transcribed with some ASCII text. * The character is discarded. * Conversion stops at this very character. Additionally. conversion may stop or continue on \0 characters in the middle of the string. Behaviour can vary from one conversion tuple to any other. If you need to ensure lossless conversion, do a roundtrip conversion and check for equality. Unicode handling ---------------- OpenMPT is generally not aware of and does not handle different Unicode normalization forms. You should be aware of the following possibilities: * Conversion between UTF8, UTF16, UTF32 may or may not change between NFC and NFD. * Conversion from any non-Unicode 8bit encoding can result in both, NFC or NFD forms. * Conversion to any non-Unicode 8bit encoding may or may not involve conversion to NFC, NFD, NFKC or NFKD during the conversion. This in particular means that conversion of decomposed german umlauts to ISO8859-1 may fail. * Changing the normalization form of path strings may render the file inaccessible. Unicode BOM may or may not be preserved and/or discarded during conversion. Invalid Unicode code points may be treated as invalid or as valid characters when converting between different Unicode encodings. Interfacing with WinAPI ----------------------- When in MFC code, use CString or CStringW as appropriate. When in non MFC code, either use std::wstring when directly interfacing with the Unicode API, or use the TCHAR helper functions: ToTcharBuf, FromTcharBuf, ToTcharStr, FromTcharStr. */ namespace mpt { namespace String { /* default 1:1 mapping static const uint32 CharsetTableISO8859_1[256] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x000e,0x000f, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,0x0018,0x0019,0x001a,0x001b,0x001c,0x001d,0x001e,0x001f, 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f, 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f, 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f, 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f, 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f, 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x007f, 0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,0x0088,0x0089,0x008a,0x008b,0x008c,0x008d,0x008e,0x008f, 0x0090,0x0091,0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,0x0098,0x0099,0x009a,0x009b,0x009c,0x009d,0x009e,0x009f, 0x00a0,0x00a1,0x00a2,0x00a3,0x00a4,0x00a5,0x00a6,0x00a7,0x00a8,0x00a9,0x00aa,0x00ab,0x00ac,0x00ad,0x00ae,0x00af, 0x00b0,0x00b1,0x00b2,0x00b3,0x00b4,0x00b5,0x00b6,0x00b7,0x00b8,0x00b9,0x00ba,0x00bb,0x00bc,0x00bd,0x00be,0x00bf, 0x00c0,0x00c1,0x00c2,0x00c3,0x00c4,0x00c5,0x00c6,0x00c7,0x00c8,0x00c9,0x00ca,0x00cb,0x00cc,0x00cd,0x00ce,0x00cf, 0x00d0,0x00d1,0x00d2,0x00d3,0x00d4,0x00d5,0x00d6,0x00d7,0x00d8,0x00d9,0x00da,0x00db,0x00dc,0x00dd,0x00de,0x00df, 0x00e0,0x00e1,0x00e2,0x00e3,0x00e4,0x00e5,0x00e6,0x00e7,0x00e8,0x00e9,0x00ea,0x00eb,0x00ec,0x00ed,0x00ee,0x00ef, 0x00f0,0x00f1,0x00f2,0x00f3,0x00f4,0x00f5,0x00f6,0x00f7,0x00f8,0x00f9,0x00fa,0x00fb,0x00fc,0x00fd,0x00fe,0x00ff }; */ #if defined(MPT_CHARSET_CODECVTUTF8) || defined(MPT_CHARSET_INTERNAL) || defined(MPT_CHARSET_WIN32) static const uint32 CharsetTableISO8859_15[256] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x000e,0x000f, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,0x0018,0x0019,0x001a,0x001b,0x001c,0x001d,0x001e,0x001f, 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f, 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f, 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f, 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f, 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f, 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x007f, 0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,0x0088,0x0089,0x008a,0x008b,0x008c,0x008d,0x008e,0x008f, 0x0090,0x0091,0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,0x0098,0x0099,0x009a,0x009b,0x009c,0x009d,0x009e,0x009f, 0x00a0,0x00a1,0x00a2,0x00a3,0x20ac,0x00a5,0x0160,0x00a7,0x0161,0x00a9,0x00aa,0x00ab,0x00ac,0x00ad,0x00ae,0x00af, 0x00b0,0x00b1,0x00b2,0x00b3,0x017d,0x00b5,0x00b6,0x00b7,0x017e,0x00b9,0x00ba,0x00bb,0x0152,0x0153,0x0178,0x00bf, 0x00c0,0x00c1,0x00c2,0x00c3,0x00c4,0x00c5,0x00c6,0x00c7,0x00c8,0x00c9,0x00ca,0x00cb,0x00cc,0x00cd,0x00ce,0x00cf, 0x00d0,0x00d1,0x00d2,0x00d3,0x00d4,0x00d5,0x00d6,0x00d7,0x00d8,0x00d9,0x00da,0x00db,0x00dc,0x00dd,0x00de,0x00df, 0x00e0,0x00e1,0x00e2,0x00e3,0x00e4,0x00e5,0x00e6,0x00e7,0x00e8,0x00e9,0x00ea,0x00eb,0x00ec,0x00ed,0x00ee,0x00ef, 0x00f0,0x00f1,0x00f2,0x00f3,0x00f4,0x00f5,0x00f6,0x00f7,0x00f8,0x00f9,0x00fa,0x00fb,0x00fc,0x00fd,0x00fe,0x00ff }; static const uint32 CharsetTableWindows1252[256] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x000e,0x000f, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,0x0018,0x0019,0x001a,0x001b,0x001c,0x001d,0x001e,0x001f, 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f, 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f, 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f, 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f, 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f, 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x007f, 0x20ac,0x0081,0x201a,0x0192,0x201e,0x2026,0x2020,0x2021,0x02c6,0x2030,0x0160,0x2039,0x0152,0x008d,0x017d,0x008f, 0x0090,0x2018,0x2019,0x201c,0x201d,0x2022,0x2013,0x2014,0x02dc,0x2122,0x0161,0x203a,0x0153,0x009d,0x017e,0x0178, 0x00a0,0x00a1,0x00a2,0x00a3,0x00a4,0x00a5,0x00a6,0x00a7,0x00a8,0x00a9,0x00aa,0x00ab,0x00ac,0x00ad,0x00ae,0x00af, 0x00b0,0x00b1,0x00b2,0x00b3,0x00b4,0x00b5,0x00b6,0x00b7,0x00b8,0x00b9,0x00ba,0x00bb,0x00bc,0x00bd,0x00be,0x00bf, 0x00c0,0x00c1,0x00c2,0x00c3,0x00c4,0x00c5,0x00c6,0x00c7,0x00c8,0x00c9,0x00ca,0x00cb,0x00cc,0x00cd,0x00ce,0x00cf, 0x00d0,0x00d1,0x00d2,0x00d3,0x00d4,0x00d5,0x00d6,0x00d7,0x00d8,0x00d9,0x00da,0x00db,0x00dc,0x00dd,0x00de,0x00df, 0x00e0,0x00e1,0x00e2,0x00e3,0x00e4,0x00e5,0x00e6,0x00e7,0x00e8,0x00e9,0x00ea,0x00eb,0x00ec,0x00ed,0x00ee,0x00ef, 0x00f0,0x00f1,0x00f2,0x00f3,0x00f4,0x00f5,0x00f6,0x00f7,0x00f8,0x00f9,0x00fa,0x00fb,0x00fc,0x00fd,0x00fe,0x00ff }; static const uint32 CharsetTableCP437[256] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x000e,0x000f, 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,0x0018,0x0019,0x001a,0x001b,0x001c,0x001d,0x001e,0x001f, 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f, 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f, 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f, 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f, 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f, 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x2302, 0x00c7,0x00fc,0x00e9,0x00e2,0x00e4,0x00e0,0x00e5,0x00e7,0x00ea,0x00eb,0x00e8,0x00ef,0x00ee,0x00ec,0x00c4,0x00c5, 0x00c9,0x00e6,0x00c6,0x00f4,0x00f6,0x00f2,0x00fb,0x00f9,0x00ff,0x00d6,0x00dc,0x00a2,0x00a3,0x00a5,0x20a7,0x0192, 0x00e1,0x00ed,0x00f3,0x00fa,0x00f1,0x00d1,0x00aa,0x00ba,0x00bf,0x2310,0x00ac,0x00bd,0x00bc,0x00a1,0x00ab,0x00bb, 0x2591,0x2592,0x2593,0x2502,0x2524,0x2561,0x2562,0x2556,0x2555,0x2563,0x2551,0x2557,0x255d,0x255c,0x255b,0x2510, 0x2514,0x2534,0x252c,0x251c,0x2500,0x253c,0x255e,0x255f,0x255a,0x2554,0x2569,0x2566,0x2560,0x2550,0x256c,0x2567, 0x2568,0x2564,0x2565,0x2559,0x2558,0x2552,0x2553,0x256b,0x256a,0x2518,0x250c,0x2588,0x2584,0x258c,0x2590,0x2580, 0x03b1,0x00df,0x0393,0x03c0,0x03a3,0x03c3,0x00b5,0x03c4,0x03a6,0x0398,0x03a9,0x03b4,0x221e,0x03c6,0x03b5,0x2229, 0x2261,0x00b1,0x2265,0x2264,0x2320,0x2321,0x00f7,0x2248,0x00b0,0x2219,0x00b7,0x221a,0x207f,0x00b2,0x25a0,0x00a0 }; #endif // MPT_CHARSET_CODECVTUTF8 || MPT_CHARSET_INTERNAL || MPT_CHARSET_WIN32 #define C(x) (static_cast((x))) // AMS1 actually only supports ASCII plus the modified control characters and no high chars at all. // Just default to CP437 for those to keep things simple. static const uint32 CharsetTableCP437AMS[256] = { C(' '),0x0001,0x0002,0x0003,0x00e4,0x0005,0x00e5,0x0007,0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x00c4,0x00c5, // differs from CP437 0x0010,0x0011,0x0012,0x0013,0x00f6,0x0015,0x0016,0x0017,0x0018,0x00d6,0x001a,0x001b,0x001c,0x001d,0x001e,0x001f, // differs from CP437 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f, 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f, 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f, 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f, 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f, 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x2302, 0x00c7,0x00fc,0x00e9,0x00e2,0x00e4,0x00e0,0x00e5,0x00e7,0x00ea,0x00eb,0x00e8,0x00ef,0x00ee,0x00ec,0x00c4,0x00c5, 0x00c9,0x00e6,0x00c6,0x00f4,0x00f6,0x00f2,0x00fb,0x00f9,0x00ff,0x00d6,0x00dc,0x00a2,0x00a3,0x00a5,0x20a7,0x0192, 0x00e1,0x00ed,0x00f3,0x00fa,0x00f1,0x00d1,0x00aa,0x00ba,0x00bf,0x2310,0x00ac,0x00bd,0x00bc,0x00a1,0x00ab,0x00bb, 0x2591,0x2592,0x2593,0x2502,0x2524,0x2561,0x2562,0x2556,0x2555,0x2563,0x2551,0x2557,0x255d,0x255c,0x255b,0x2510, 0x2514,0x2534,0x252c,0x251c,0x2500,0x253c,0x255e,0x255f,0x255a,0x2554,0x2569,0x2566,0x2560,0x2550,0x256c,0x2567, 0x2568,0x2564,0x2565,0x2559,0x2558,0x2552,0x2553,0x256b,0x256a,0x2518,0x250c,0x2588,0x2584,0x258c,0x2590,0x2580, 0x03b1,0x00df,0x0393,0x03c0,0x03a3,0x03c3,0x00b5,0x03c4,0x03a6,0x0398,0x03a9,0x03b4,0x221e,0x03c6,0x03b5,0x2229, 0x2261,0x00b1,0x2265,0x2264,0x2320,0x2321,0x00f7,0x2248,0x00b0,0x2219,0x00b7,0x221a,0x207f,0x00b2,0x25a0,0x00a0 }; // AMS2: Looking at Velvet Studio's bitmap font (TPIC32.PCX), these appear to be the only supported non-ASCII chars. static const uint32 CharsetTableCP437AMS2[256] = { C(' '),0x00a9,0x221a,0x00b7,C('0'),C('1'),C('2'),C('3'),C('4'),C('5'),C('6'),C('7'),C('8'),C('9'),C('A'),C('B'), // differs from CP437 C('C'),C('D'),C('E'),C('F'),C(' '),0x00a7,C(' '),C(' '),C(' '),C(' '),C(' '),C(' '),C(' '),C(' '),C(' '),C(' '), // differs from CP437 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f, 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f, 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f, 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f, 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f, 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x2302, 0x00c7,0x00fc,0x00e9,0x00e2,0x00e4,0x00e0,0x00e5,0x00e7,0x00ea,0x00eb,0x00e8,0x00ef,0x00ee,0x00ec,0x00c4,0x00c5, 0x00c9,0x00e6,0x00c6,0x00f4,0x00f6,0x00f2,0x00fb,0x00f9,0x00ff,0x00d6,0x00dc,0x00a2,0x00a3,0x00a5,0x20a7,0x0192, 0x00e1,0x00ed,0x00f3,0x00fa,0x00f1,0x00d1,0x00aa,0x00ba,0x00bf,0x2310,0x00ac,0x00bd,0x00bc,0x00a1,0x00ab,0x00bb, 0x2591,0x2592,0x2593,0x2502,0x2524,0x2561,0x2562,0x2556,0x2555,0x2563,0x2551,0x2557,0x255d,0x255c,0x255b,0x2510, 0x2514,0x2534,0x252c,0x251c,0x2500,0x253c,0x255e,0x255f,0x255a,0x2554,0x2569,0x2566,0x2560,0x2550,0x256c,0x2567, 0x2568,0x2564,0x2565,0x2559,0x2558,0x2552,0x2553,0x256b,0x256a,0x2518,0x250c,0x2588,0x2584,0x258c,0x2590,0x2580, 0x03b1,0x00df,0x0393,0x03c0,0x03a3,0x03c3,0x00b5,0x03c4,0x03a6,0x0398,0x03a9,0x03b4,0x221e,0x03c6,0x03b5,0x2229, 0x2261,0x00b1,0x2265,0x2264,0x2320,0x2321,0x00f7,0x2248,0x00b0,0x2219,0x00b7,0x221a,0x207f,0x00b2,0x25a0,0x00a0 }; #undef C #if MPT_COMPILER_MSVC #pragma warning(disable:4428) // universal-character-name encountered in source #endif static std::wstring From8bit(const std::string &str, const uint32 (&table)[256], wchar_t replacement = L'\uFFFD') { std::wstring res; res.reserve(str.length()); for(std::size_t i = 0; i < str.length(); ++i) { uint32 c = static_cast(static_cast(str[i])); if(c < mpt::size(table)) { res.push_back(static_cast(static_cast(table[c]))); } else { res.push_back(replacement); } } return res; } static std::string To8bit(const std::wstring &str, const uint32 (&table)[256], char replacement = '?') { std::string res; res.reserve(str.length()); for(std::size_t i = 0; i < str.length(); ++i) { uint32 c = str[i]; bool found = false; // Try non-control characters first. // In cases where there are actual characters mirrored in this range (like in AMS/AMS2 character sets), // characters in the common range are preferred this way. for(std::size_t x = 0x20; x < mpt::size(table); ++x) { if(c == table[x]) { res.push_back(static_cast(static_cast(x))); found = true; break; } } if(!found) { // try control characters for(std::size_t x = 0x00; x < mpt::size(table) && x < 0x20; ++x) { if(c == table[x]) { res.push_back(static_cast(static_cast(x))); found = true; break; } } } if(!found) { res.push_back(replacement); } } return res; } #if defined(MPT_CHARSET_CODECVTUTF8) || defined(MPT_CHARSET_INTERNAL) || defined(MPT_CHARSET_WIN32) static std::wstring FromAscii(const std::string &str, wchar_t replacement = L'\uFFFD') { std::wstring res; res.reserve(str.length()); for(std::size_t i = 0; i < str.length(); ++i) { uint8 c = str[i]; if(c <= 0x7f) { res.push_back(static_cast(static_cast(c))); } else { res.push_back(replacement); } } return res; } static std::string ToAscii(const std::wstring &str, char replacement = '?') { std::string res; res.reserve(str.length()); for(std::size_t i = 0; i < str.length(); ++i) { uint32 c = str[i]; if(c <= 0x7f) { res.push_back(static_cast(static_cast(c))); } else { res.push_back(replacement); } } return res; } static std::wstring FromISO_8859_1(const std::string &str, wchar_t replacement = L'\uFFFD') { MPT_UNREFERENCED_PARAMETER(replacement); std::wstring res; res.reserve(str.length()); for(std::size_t i = 0; i < str.length(); ++i) { uint8 c = str[i]; res.push_back(static_cast(static_cast(c))); } return res; } static std::string ToISO_8859_1(const std::wstring &str, char replacement = '?') { std::string res; res.reserve(str.length()); for(std::size_t i = 0; i < str.length(); ++i) { uint32 c = str[i]; if(c <= 0xff) { res.push_back(static_cast(static_cast(c))); } else { res.push_back(replacement); } } return res; } #if defined(MPT_ENABLE_CHARSET_LOCALE) // Note: // // std::codecvt::out in LLVM libc++ does not advance in and out pointers when // running into a non-convertible cahracter. This can happen when no locale is // set on FreeBSD or MacOSX. This behaviour violates the C++ standard. // // We apply the following (albeit costly, even on other platforms) work-around: // If the conversion errors out and does not advance the pointers at all, we // retry the conversion with a space character prepended to the string. If it // still does error our, we retry the whole conversion character by character. // This is costly even on other platforms in one single case: The first // character is an invalid Unicode code point or otherwise not convertible. Any // following non-convertible characters are not a problem. static std::wstring LocaleDecode(const std::string &str, const std::locale & locale, wchar_t replacement = L'\uFFFD', int retry = 0, bool * progress = nullptr) { if(str.empty()) { return std::wstring(); } std::vector out; typedef std::codecvt codecvt_type; std::mbstate_t state = std::mbstate_t(); const codecvt_type & facet = std::use_facet(locale); codecvt_type::result result = codecvt_type::partial; const char * in_begin = str.data(); const char * in_end = in_begin + str.size(); out.resize((in_end - in_begin) * (facet.max_length() + 1)); wchar_t * out_begin = &(out[0]); wchar_t * out_end = &(out[0]) + out.size(); const char * in_next = nullptr; wchar_t * out_next = nullptr; do { if(retry == 2) { for(;;) { in_next = nullptr; out_next = nullptr; result = facet.in(state, in_begin, in_begin + 1, in_next, out_begin, out_end, out_next); if(result == codecvt_type::partial && in_next == in_begin + 1) { in_begin = in_next; out_begin = out_next; continue; } else { break; } } } else { in_next = nullptr; out_next = nullptr; result = facet.in(state, in_begin, in_end, in_next, out_begin, out_end, out_next); } if(result == codecvt_type::partial || (result == codecvt_type::error && out_next == out_end)) { out.resize(out.size() * 2); in_begin = in_next; out_begin = &(out[0]) + (out_next - out_begin); out_end = &(out[0]) + out.size(); continue; } if(retry == 0) { if(result == codecvt_type::error && in_next == in_begin && out_next == out_begin) { bool made_progress = true; LocaleDecode(std::string(" ") + str, locale, replacement, 1, &made_progress); if(!made_progress) { return LocaleDecode(str, locale, replacement, 2); } } } else if(retry == 1) { if(result == codecvt_type::error && in_next == in_begin && out_next == out_begin) { *progress = false; } else { *progress = true; } return std::wstring(); } if(result == codecvt_type::error) { ++in_next; *out_next = replacement; ++out_next; } in_begin = in_next; out_begin = out_next; } while((result == codecvt_type::error && in_next < in_end && out_next < out_end) || (retry == 2 && in_next < in_end)); return std::wstring(&(out[0]), out_next); } static std::string LocaleEncode(const std::wstring &str, const std::locale & locale, char replacement = '?', int retry = 0, bool * progress = nullptr) { if(str.empty()) { return std::string(); } std::vector out; typedef std::codecvt codecvt_type; std::mbstate_t state = std::mbstate_t(); const codecvt_type & facet = std::use_facet(locale); codecvt_type::result result = codecvt_type::partial; const wchar_t * in_begin = str.data(); const wchar_t * in_end = in_begin + str.size(); out.resize((in_end - in_begin) * (facet.max_length() + 1)); char * out_begin = &(out[0]); char * out_end = &(out[0]) + out.size(); const wchar_t * in_next = nullptr; char * out_next = nullptr; do { if(retry == 2) { for(;;) { in_next = nullptr; out_next = nullptr; result = facet.out(state, in_begin, in_begin + 1, in_next, out_begin, out_end, out_next); if(result == codecvt_type::partial && in_next == in_begin + 1) { in_begin = in_next; out_begin = out_next; continue; } else { break; } } } else { in_next = nullptr; out_next = nullptr; result = facet.out(state, in_begin, in_end, in_next, out_begin, out_end, out_next); } if(result == codecvt_type::partial || (result == codecvt_type::error && out_next == out_end)) { out.resize(out.size() * 2); in_begin = in_next; out_begin = &(out[0]) + (out_next - out_begin); out_end = &(out[0]) + out.size(); continue; } if(retry == 0) { if(result == codecvt_type::error && in_next == in_begin && out_next == out_begin) { bool made_progress = true; LocaleEncode(std::wstring(L" ") + str, locale, replacement, 1, &made_progress); if(!made_progress) { return LocaleEncode(str, locale, replacement, 2); } } } else if(retry == 1) { if(result == codecvt_type::error && in_next == in_begin && out_next == out_begin) { *progress = false; } else { *progress = true; } return std::string(); } if(result == codecvt_type::error) { ++in_next; *out_next = replacement; ++out_next; } in_begin = in_next; out_begin = out_next; } while((result == codecvt_type::error && in_next < in_end && out_next < out_end) || (retry == 2 && in_next < in_end)); return std::string(&(out[0]), out_next); } static std::wstring FromLocale(const std::string &str, wchar_t replacement = L'\uFFFD') { try { std::locale locale(""); // user locale return String::LocaleDecode(str, locale, replacement); } catch(...) { // nothing } try { std::locale locale; // current c++ locale return String::LocaleDecode(str, locale, replacement); } catch(...) { // nothing } try { std::locale locale = std::locale::classic(); // "C" locale return String::LocaleDecode(str, locale, replacement); } catch(...) { // nothing } MPT_ASSERT_NOTREACHED(); return String::FromAscii(str, replacement); // fallback } static std::string ToLocale(const std::wstring &str, char replacement = '?') { try { std::locale locale(""); // user locale return String::LocaleEncode(str, locale, replacement); } catch(...) { // nothing } try { std::locale locale; // current c++ locale return String::LocaleEncode(str, locale, replacement); } catch(...) { // nothing } try { std::locale locale = std::locale::classic(); // "C" locale return String::LocaleEncode(str, locale, replacement); } catch(...) { // nothing } MPT_ASSERT_NOTREACHED(); return String::ToAscii(str, replacement); // fallback } #endif #endif // MPT_CHARSET_CODECVTUTF8 || MPT_CHARSET_INTERNAL || MPT_CHARSET_WIN32 #if defined(MPT_CHARSET_CODECVTUTF8) static std::wstring FromUTF8(const std::string &str, wchar_t replacement = L'\uFFFD') { MPT_UNREFERENCED_PARAMETER(replacement); std::wstring_convert > conv; return conv.from_bytes(str); } static std::string ToUTF8(const std::wstring &str, char replacement = '?') { MPT_UNREFERENCED_PARAMETER(replacement); std::wstring_convert > conv; return conv.to_bytes(str); } #endif // MPT_CHARSET_CODECVTUTF8 #if defined(MPT_CHARSET_INTERNAL) || defined(MPT_CHARSET_WIN32) static std::wstring FromUTF8(const std::string &str, wchar_t replacement = L'\uFFFD') { const std::string &in = str; std::wstring out; // state: std::size_t charsleft = 0; uint32 ucs4 = 0; for ( uint8 c : in ) { if ( charsleft == 0 ) { if ( ( c & 0x80 ) == 0x00 ) { out.push_back( (wchar_t)c ); } else if ( ( c & 0xE0 ) == 0xC0 ) { ucs4 = c & 0x1F; charsleft = 1; } else if ( ( c & 0xF0 ) == 0xE0 ) { ucs4 = c & 0x0F; charsleft = 2; } else if ( ( c & 0xF8 ) == 0xF0 ) { ucs4 = c & 0x07; charsleft = 3; } else { out.push_back( replacement ); ucs4 = 0; charsleft = 0; } } else { if ( ( c & 0xC0 ) != 0x80 ) { out.push_back( replacement ); ucs4 = 0; charsleft = 0; } ucs4 <<= 6; ucs4 |= c & 0x3F; charsleft--; if ( charsleft == 0 ) { MPT_CONSTANT_IF ( sizeof( wchar_t ) == 2 ) { if ( ucs4 > 0x1fffff ) { out.push_back( replacement ); ucs4 = 0; charsleft = 0; } if ( ucs4 <= 0xffff ) { out.push_back( (uint16)ucs4 ); } else { uint32 surrogate = ucs4 - 0x10000; uint16 hi_sur = static_cast( ( 0x36 << 10 ) | ( (surrogate>>10) & ((1<<10)-1) ) ); uint16 lo_sur = static_cast( ( 0x37 << 10 ) | ( (surrogate>> 0) & ((1<<10)-1) ) ); out.push_back( hi_sur ); out.push_back( lo_sur ); } } else { out.push_back( static_cast( ucs4 ) ); } ucs4 = 0; } } } if ( charsleft != 0 ) { out.push_back( replacement ); ucs4 = 0; charsleft = 0; } return out; } static std::string ToUTF8(const std::wstring &str, char replacement = '?') { const std::wstring &in = str; std::string out; for ( std::size_t i=0; i( wc ); if ( i + 1 < in.length() ) { // check for surrogate pair uint16 hi_sur = in[i+0]; uint16 lo_sur = in[i+1]; if ( hi_sur >> 10 == 0x36 && lo_sur >> 10 == 0x37 ) { // surrogate pair ++i; hi_sur &= (1<<10)-1; lo_sur &= (1<<10)-1; ucs4 = ( static_cast(hi_sur) << 10 ) | ( static_cast(lo_sur) << 0 ); } else { // no surrogate pair ucs4 = static_cast( c ); } } else { // no surrogate possible ucs4 = static_cast( c ); } } else { ucs4 = static_cast( wc ); } if ( ucs4 > 0x1fffff ) { out.push_back( replacement ); continue; } uint8 utf8[6]; std::size_t numchars = 0; for ( numchars = 0; numchars < 6; numchars++ ) { utf8[numchars] = ucs4 & 0x3F; ucs4 >>= 6; if ( ucs4 == 0 ) { break; } } numchars++; if ( numchars == 1 ) { out.push_back( utf8[0] ); continue; } if ( numchars == 2 && utf8[numchars-1] == 0x01 ) { // generate shortest form out.push_back( utf8[0] | 0x40 ); continue; } std::size_t charsleft = numchars; while ( charsleft > 0 ) { if ( charsleft == numchars ) { out.push_back( utf8[ charsleft - 1 ] | ( ((1< Tdststring EncodeImplFallback(Charset charset, const std::wstring &src); #endif // !MPT_CHARSET_ICONV // templated on 8bit strings because of type-safe variants template Tdststring EncodeImpl(Charset charset, const std::wstring &src) { STATIC_ASSERT(sizeof(typename Tdststring::value_type) == sizeof(char)); if(charset == CharsetCP437AMS || charset == CharsetCP437AMS2) { std::string out; if(charset == CharsetCP437AMS ) out = String::To8bit(src, CharsetTableCP437AMS ); if(charset == CharsetCP437AMS2) out = String::To8bit(src, CharsetTableCP437AMS2); return Tdststring(out.begin(), out.end()); } #if defined(MPT_ENABLE_CHARSET_LOCALE) #if defined(MPT_LOCALE_ASSUME_CHARSET) if(charset == CharsetLocale) { charset = MPT_LOCALE_ASSUME_CHARSET; } #endif #endif #if defined(MPT_CHARSET_WIN32) if(!HasCharset(charset)) { return EncodeImplFallback(charset, src); } const UINT codepage = CharsetToCodepage(charset); int required_size = WideCharToMultiByte(codepage, 0, src.c_str(), -1, nullptr, 0, nullptr, nullptr); if(required_size <= 0) { return Tdststring(); } std::vector encoded_string(required_size); WideCharToMultiByte(codepage, 0, src.c_str(), -1, encoded_string.data(), required_size, nullptr, nullptr); return reinterpret_cast(encoded_string.data()); #elif defined(MPT_CHARSET_ICONV) iconv_t conv = iconv_t(); conv = iconv_open(CharsetToStringTranslit(charset), Charset_wchar_t()); if(!conv) { conv = iconv_open(CharsetToString(charset), Charset_wchar_t()); if(!conv) { throw std::runtime_error("iconv conversion not working"); } } std::vector wide_string(src.c_str(), src.c_str() + src.length() + 1); std::vector encoded_string(wide_string.size() * 8); // large enough char * inbuf = reinterpret_cast(wide_string.data()); size_t inbytesleft = wide_string.size() * sizeof(wchar_t); char * outbuf = encoded_string.data(); size_t outbytesleft = encoded_string.size(); while(iconv(conv, &inbuf, &inbytesleft, &outbuf, &outbytesleft) == static_cast(-1)) { if(errno == EILSEQ || errno == EILSEQ) { inbuf += sizeof(wchar_t); inbytesleft -= sizeof(wchar_t); outbuf[0] = '?'; outbuf++; outbytesleft--; iconv(conv, NULL, NULL, NULL, NULL); // reset state } else { iconv_close(conv); conv = iconv_t(); return Tdststring(); } } iconv_close(conv); conv = iconv_t(); return reinterpret_cast(encoded_string.data()); #else return EncodeImplFallback(charset, src); #endif } #if !defined(MPT_CHARSET_ICONV) template Tdststring EncodeImplFallback(Charset charset, const std::wstring &src) { std::string out; switch(charset) { #if defined(MPT_ENABLE_CHARSET_LOCALE) case CharsetLocale: out = String::ToLocale(src); break; #endif case CharsetUTF8: out = String::ToUTF8(src); break; case CharsetASCII: out = String::ToAscii(src); break; case CharsetISO8859_1: out = String::ToISO_8859_1(src); break; case CharsetISO8859_15: out = String::To8bit(src, CharsetTableISO8859_15); break; case CharsetCP437: out = String::To8bit(src, CharsetTableCP437); break; case CharsetCP437AMS: out = String::To8bit(src, CharsetTableCP437AMS); break; case CharsetCP437AMS2: out = String::To8bit(src, CharsetTableCP437AMS2); break; case CharsetWindows1252: out = String::To8bit(src, CharsetTableWindows1252); break; } return Tdststring(out.begin(), out.end()); } #endif // !MPT_CHARSET_ICONV #if !defined(MPT_CHARSET_ICONV) template std::wstring DecodeImplFallback(Charset charset, const Tsrcstring &src); #endif // !MPT_CHARSET_ICONV // templated on 8bit strings because of type-safe variants template std::wstring DecodeImpl(Charset charset, const Tsrcstring &src) { STATIC_ASSERT(sizeof(typename Tsrcstring::value_type) == sizeof(char)); if(charset == CharsetCP437AMS || charset == CharsetCP437AMS2) { std::string in(src.begin(), src.end()); std::wstring out; if(charset == CharsetCP437AMS ) out = String::From8bit(in, CharsetTableCP437AMS ); if(charset == CharsetCP437AMS2) out = String::From8bit(in, CharsetTableCP437AMS2); return out; } #if defined(MPT_ENABLE_CHARSET_LOCALE) #if defined(MPT_LOCALE_ASSUME_CHARSET) if(charset == CharsetLocale) { charset = MPT_LOCALE_ASSUME_CHARSET; } #endif #endif #if defined(MPT_CHARSET_WIN32) if(!HasCharset(charset)) { return DecodeImplFallback(charset, src); } const UINT codepage = CharsetToCodepage(charset); int required_size = MultiByteToWideChar(codepage, 0, reinterpret_cast(src.c_str()), -1, nullptr, 0); if(required_size <= 0) { return std::wstring(); } std::vector decoded_string(required_size); MultiByteToWideChar(codepage, 0, reinterpret_cast(src.c_str()), -1, decoded_string.data(), required_size); return decoded_string.data(); #elif defined(MPT_CHARSET_ICONV) iconv_t conv = iconv_t(); conv = iconv_open(Charset_wchar_t(), CharsetToString(charset)); if(!conv) { throw std::runtime_error("iconv conversion not working"); } std::vector encoded_string(reinterpret_cast(src.c_str()), reinterpret_cast(src.c_str()) + src.length() + 1); std::vector wide_string(encoded_string.size() * 8); // large enough char * inbuf = encoded_string.data(); size_t inbytesleft = encoded_string.size(); char * outbuf = reinterpret_cast(wide_string.data()); size_t outbytesleft = wide_string.size() * sizeof(wchar_t); while(iconv(conv, &inbuf, &inbytesleft, &outbuf, &outbytesleft) == static_cast(-1)) { if(errno == EILSEQ || errno == EILSEQ) { inbuf++; inbytesleft--; for(std::size_t i = 0; i < sizeof(wchar_t); ++i) { outbuf[i] = 0; } #if defined(MPT_PLATFORM_LITTLE_ENDIAN) outbuf[1] = uint8(0xff); outbuf[0] = uint8(0xfd); #elif defined(MPT_PLATFORM_BIG_ENDIAN) outbuf[sizeof(wchar_t)-1 - 1] = uint8(0xff); outbuf[sizeof(wchar_t)-1 - 0] = uint8(0xfd); #else MPT_MAYBE_CONSTANT_IF(mpt::endian_is_little()) { outbuf[1] = uint8(0xff); outbuf[0] = uint8(0xfd); } MPT_MAYBE_CONSTANT_IF(mpt::endian_is_big()) { outbuf[sizeof(wchar_t)-1 - 1] = uint8(0xff); outbuf[sizeof(wchar_t)-1 - 0] = uint8(0xfd); } #endif outbuf += sizeof(wchar_t); outbytesleft -= sizeof(wchar_t); iconv(conv, NULL, NULL, NULL, NULL); // reset state } else { iconv_close(conv); conv = iconv_t(); return std::wstring(); } } iconv_close(conv); conv = iconv_t(); return wide_string.data(); #else return DecodeImplFallback(charset, src); #endif } #if !defined(MPT_CHARSET_ICONV) template std::wstring DecodeImplFallback(Charset charset, const Tsrcstring &src) { std::string in(src.begin(), src.end()); std::wstring out; switch(charset) { #if defined(MPT_ENABLE_CHARSET_LOCALE) case CharsetLocale: out = String::FromLocale(in); break; #endif case CharsetUTF8: out = String::FromUTF8(in); break; case CharsetASCII: out = String::FromAscii(in); break; case CharsetISO8859_1: out = String::FromISO_8859_1(in); break; case CharsetISO8859_15: out = String::From8bit(in, CharsetTableISO8859_15); break; case CharsetCP437: out = String::From8bit(in, CharsetTableCP437); break; case CharsetCP437AMS: out = String::From8bit(in, CharsetTableCP437AMS); break; case CharsetCP437AMS2: out = String::From8bit(in, CharsetTableCP437AMS2); break; case CharsetWindows1252: out = String::From8bit(in, CharsetTableWindows1252); break; } return out; } #endif // !MPT_CHARSET_ICONV // templated on 8bit strings because of type-safe variants template Tdststring ConvertImpl(Charset to, Charset from, const Tsrcstring &src) { STATIC_ASSERT(sizeof(typename Tdststring::value_type) == sizeof(char)); STATIC_ASSERT(sizeof(typename Tsrcstring::value_type) == sizeof(char)); if(to == from) { const typename Tsrcstring::value_type * src_beg = src.data(); const typename Tsrcstring::value_type * src_end = src_beg + src.size(); return Tdststring(reinterpret_cast(src_beg), reinterpret_cast(src_end)); } #if defined(MPT_CHARSET_ICONV) if(to == CharsetCP437AMS || to == CharsetCP437AMS2 || from == CharsetCP437AMS || from == CharsetCP437AMS2) { return EncodeImpl(to, DecodeImpl(from, src)); } iconv_t conv = iconv_t(); conv = iconv_open(CharsetToStringTranslit(to), CharsetToString(from)); if(!conv) { conv = iconv_open(CharsetToString(to), CharsetToString(from)); if(!conv) { throw std::runtime_error("iconv conversion not working"); } } std::vector src_string(reinterpret_cast(src.c_str()), reinterpret_cast(src.c_str()) + src.length() + 1); std::vector dst_string(src_string.size() * 8); // large enough char * inbuf = src_string.data(); size_t inbytesleft = src_string.size(); char * outbuf = dst_string.data(); size_t outbytesleft = dst_string.size(); while(iconv(conv, &inbuf, &inbytesleft, &outbuf, &outbytesleft) == static_cast(-1)) { if(errno == EILSEQ || errno == EILSEQ) { inbuf++; inbytesleft--; outbuf[0] = '?'; outbuf++; outbytesleft--; iconv(conv, NULL, NULL, NULL, NULL); // reset state } else { iconv_close(conv); conv = iconv_t(); return Tdststring(); } } iconv_close(conv); conv = iconv_t(); return reinterpret_cast(dst_string.data()); #else return EncodeImpl(to, DecodeImpl(from, src)); #endif } } // namespace String bool IsUTF8(const std::string &str) { return (str == String::EncodeImpl(mpt::CharsetUTF8, String::DecodeImpl(mpt::CharsetUTF8, str))); } #if MPT_WSTRING_CONVERT std::wstring ToWide(Charset from, const std::string &str) { return String::DecodeImpl(from, str); } #endif #if MPT_WSTRING_CONVERT std::string ToCharset(Charset to, const std::wstring &str) { return String::EncodeImpl(to, str); } #endif std::string ToCharset(Charset to, Charset from, const std::string &str) { return String::ConvertImpl(to, from, str); } #if defined(_MFC_VER) CString ToCString(const std::wstring &str) { #ifdef UNICODE return str.c_str(); #else return ToCharset(CharsetLocale, str).c_str(); #endif } CString ToCString(Charset from, const std::string &str) { #ifdef UNICODE return ToWide(from, str).c_str(); #else return ToCharset(CharsetLocale, from, str).c_str(); #endif } std::wstring ToWide(const CString &str) { #ifdef UNICODE return str.GetString(); #else return ToWide(CharsetLocale, str.GetString()); #endif } std::string ToCharset(Charset to, const CString &str) { #ifdef UNICODE return ToCharset(to, str.GetString()); #else return ToCharset(to, CharsetLocale, str.GetString()); #endif } #ifdef UNICODE // inline #else // !UNICODE CStringW ToCStringW(const CString &str) { return ToWide(str).c_str(); } CStringW ToCStringW(const std::wstring &str) { return str.c_str(); } CStringW ToCStringW(Charset from, const std::string &str) { return ToWide(from, str).c_str(); } CStringW ToCStringW(const CStringW &str) { return str; } std::wstring ToWide(const CStringW &str) { return str.GetString(); } std::string ToCharset(Charset to, const CStringW &str) { return ToCharset(to, str.GetString()); } CString ToCString(const CStringW &str) { return ToCharset(CharsetLocale, str).c_str(); } #endif // UNICODE #endif // MFC #if MPT_USTRING_MODE_WIDE // inline #else // !MPT_USTRING_MODE_WIDE #if MPT_WSTRING_CONVERT mpt::ustring ToUnicode(const std::wstring &str) { return String::EncodeImpl(mpt::CharsetUTF8, str); } #endif mpt::ustring ToUnicode(Charset from, const std::string &str) { return String::ConvertImpl(mpt::CharsetUTF8, from, str); } #if defined(_MFC_VER) mpt::ustring ToUnicode(const CString &str) { #ifdef UNICODE return String::EncodeImpl(mpt::CharsetUTF8, str.GetString()); #else // !UNICODE return String::ConvertImpl(mpt::CharsetUTF8, mpt::CharsetLocale, str.GetString()); #endif // UNICODE } #ifndef UNICODE mpt::ustring ToUnicode(const CStringW &str) { return String::EncodeImpl(mpt::CharsetUTF8, str.GetString()); } #endif // !UNICODE #endif // MFC #endif // MPT_USTRING_MODE_WIDE #if MPT_USTRING_MODE_WIDE // nothing, std::wstring overloads will catch all stuff #else // !MPT_USTRING_MODE_WIDE #if MPT_WSTRING_CONVERT std::wstring ToWide(const mpt::ustring &str) { return String::DecodeImpl(mpt::CharsetUTF8, str); } #endif std::string ToCharset(Charset to, const mpt::ustring &str) { return String::ConvertImpl(to, mpt::CharsetUTF8, str); } #if defined(_MFC_VER) CString ToCString(const mpt::ustring &str) { #ifdef UNICODE return String::DecodeImpl(mpt::CharsetUTF8, str).c_str(); #else // !UNICODE return String::ConvertImpl(mpt::CharsetLocale, mpt::CharsetUTF8, str).c_str(); #endif // UNICODE } #endif // MFC #endif // MPT_USTRING_MODE_WIDE char ToLowerCaseAscii(char c) { if('A' <= c && c <= 'Z') { c += 'a' - 'A'; } return c; } char ToUpperCaseAscii(char c) { if('a' <= c && c <= 'z') { c -= 'a' - 'A'; } return c; } std::string ToLowerCaseAscii(std::string s) { std::transform(s.begin(), s.end(), s.begin(), static_cast(&mpt::ToLowerCaseAscii)); return s; } std::string ToUpperCaseAscii(std::string s) { std::transform(s.begin(), s.end(), s.begin(), static_cast(&mpt::ToUpperCaseAscii)); return s; } int CompareNoCaseAscii(const char *a, const char *b, std::size_t n) { while(n--) { unsigned char ac = static_cast(mpt::ToLowerCaseAscii(*a)); unsigned char bc = static_cast(mpt::ToLowerCaseAscii(*b)); if(ac != bc) { return ac < bc ? -1 : 1; } else if(!ac && !bc) { return 0; } ++a; ++b; } return 0; } int CompareNoCaseAscii(const std::string &a, const std::string &b) { for(std::size_t i = 0; i < std::min(a.length(), b.length()); ++i) { unsigned char ac = static_cast(mpt::ToLowerCaseAscii(a[i])); unsigned char bc = static_cast(mpt::ToLowerCaseAscii(b[i])); if(ac != bc) { return ac < bc ? -1 : 1; } else if(!ac && !bc) { return 0; } } if(a.length() == b.length()) { return 0; } return a.length() < b.length() ? -1 : 1; } #if defined(MODPLUG_TRACKER) mpt::ustring ToLowerCase(const mpt::ustring &s) { #if defined(_MFC_VER) #if defined(UNICODE) CString tmp = mpt::ToCString(s); tmp.MakeLower(); return mpt::ToUnicode(tmp); #else // !UNICODE CStringW tmp = mpt::ToCStringW(s); tmp.MakeLower(); return mpt::ToUnicode(tmp); #endif // UNICODE #else // !_MFC_VER std::wstring ws = mpt::ToWide(s); std::transform(ws.begin(), ws.end(), ws.begin(), &std::towlower); return mpt::ToUnicode(ws); #endif // _MFC_VER } mpt::ustring ToUpperCase(const mpt::ustring &s) { #if defined(_MFC_VER) #if defined(UNICODE) CString tmp = mpt::ToCString(s); tmp.MakeUpper(); return mpt::ToUnicode(tmp); #else // !UNICODE CStringW tmp = mpt::ToCStringW(s); tmp.MakeUpper(); return mpt::ToUnicode(tmp); #endif // UNICODE #else // !_MFC_VER std::wstring ws = mpt::ToWide(s); std::transform(ws.begin(), ws.end(), ws.begin(), &std::towlower); return mpt::ToUnicode(ws); #endif // _MFC_VER } #endif // MODPLUG_TRACKER } // namespace mpt OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/mptOS.h0000644000372100037210000000556613144630336017000 00000000000000/* * mptOS.h * ------- * Purpose: Operating system version information. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "mptLibrary.h" OPENMPT_NAMESPACE_BEGIN namespace mpt { namespace Windows { class Version { public: enum Number { WinNT4 = 0x0400, Win98 = 0x0410, WinME = 0x0490, Win2000 = 0x0500, WinXP = 0x0501, WinXP64 = 0x0502, WinVista = 0x0600, Win7 = 0x0601, Win8 = 0x0602, Win81 = 0x0603, Win10 = 0x0a00, WinNewer = Win10 + 1 }; static mpt::ustring VersionToString(uint16 version); static mpt::ustring VersionToString(Number version); private: bool SystemIsWindows; uint32 SystemVersion; private: Version(); public: static mpt::Windows::Version Current(); public: bool IsWindows() const; bool IsBefore(mpt::Windows::Version::Number version) const; bool IsAtLeast(mpt::Windows::Version::Number version) const; mpt::ustring GetName() const; #ifdef MODPLUG_TRACKER mpt::ustring GetNameShort() const; #endif // MODPLUG_TRACKER public: static mpt::Windows::Version::Number GetMinimumKernelLevel(); static mpt::Windows::Version::Number GetMinimumAPILevel(); }; // class Version #if defined(MODPLUG_TRACKER) void PreventWineDetection(); bool IsOriginal(); bool IsWine(); #endif // MODPLUG_TRACKER } // namespace Windows } // namespace mpt #if defined(MODPLUG_TRACKER) namespace mpt { namespace Wine { class Version { private: bool valid; uint8 vmajor; uint8 vminor; uint8 vupdate; public: Version(); Version(uint8 vmajor, uint8 vminor, uint8 vupdate); explicit Version(const mpt::ustring &version); public: bool IsValid() const; mpt::ustring AsString() const; private: static mpt::Wine::Version FromInteger(uint32 version); uint32 AsInteger() const; public: bool IsBefore(mpt::Wine::Version other) const; bool IsAtLeast(mpt::Wine::Version other) const; }; mpt::Wine::Version GetMinimumWineVersion(); class VersionContext { protected: bool m_IsWine; mpt::Library m_NTDLL; std::string m_RawVersion; std::string m_RawBuildID; std::string m_RawHostSysName; std::string m_RawHostRelease; mpt::Wine::Version m_Version; bool m_HostIsLinux; bool m_HostIsBSD; public: VersionContext(); public: bool IsWine() const { return m_IsWine; } mpt::Library NTDLL() const { return m_NTDLL; } std::string RawVersion() const { return m_RawVersion; } std::string RawBuildID() const { return m_RawBuildID; } std::string RawHostSysName() const { return m_RawHostSysName; } std::string RawHostRelease() const { return m_RawHostRelease; } mpt::Wine::Version Version() const { return m_Version; } bool HostIsLinux() const { return m_HostIsLinux; } bool HostIsBSD() const { return m_HostIsBSD; } }; } // namespace Wine } // namespace mpt #endif // MODPLUG_TRACKER OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/mptMutex.h0000644000372100037210000001300313076367670017556 00000000000000/* * mptMutex.h * ---------- * Purpose: Partially implement c++ mutexes as far as openmpt needs them. Can eventually go away when we only support c++11 compilers some time. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include // some C++ header in order to have the C++ standard library version information available #if !MPT_PLATFORM_MULTITHREADED #define MPT_MUTEX_STD 0 #define MPT_MUTEX_PTHREAD 0 #define MPT_MUTEX_WIN32 0 #elif MPT_OS_EMSCRIPTEN #define MPT_MUTEX_STD 0 #define MPT_MUTEX_PTHREAD 0 #define MPT_MUTEX_WIN32 0 #elif MPT_COMPILER_GENERIC && !defined(MPT_QUIRK_NO_CPP_THREAD) #define MPT_MUTEX_STD 1 #define MPT_MUTEX_PTHREAD 0 #define MPT_MUTEX_WIN32 0 #elif MPT_COMPILER_MSVC && !defined(MPT_QUIRK_NO_CPP_THREAD) #define MPT_MUTEX_STD 1 #define MPT_MUTEX_PTHREAD 0 #define MPT_MUTEX_WIN32 0 #elif MPT_COMPILER_GCC && !MPT_OS_WINDOWS && !defined(MPT_QUIRK_NO_CPP_THREAD) #define MPT_MUTEX_STD 1 #define MPT_MUTEX_PTHREAD 0 #define MPT_MUTEX_WIN32 0 #elif MPT_COMPILER_CLANG && defined(__GLIBCXX__) && !defined(MPT_QUIRK_NO_CPP_THREAD) #define MPT_MUTEX_STD 1 #define MPT_MUTEX_PTHREAD 0 #define MPT_MUTEX_WIN32 0 #elif (MPT_OS_MACOSX_OR_IOS || MPT_OS_FREEBSD) && MPT_COMPILER_CLANG && !defined(MPT_QUIRK_NO_CPP_THREAD) #define MPT_MUTEX_STD 1 #define MPT_MUTEX_PTHREAD 0 #define MPT_MUTEX_WIN32 0 #elif MPT_CLANG_AT_LEAST(3,6,0) && defined(_LIBCPP_VERSION) && !defined(MPT_QUIRK_NO_CPP_THREAD) #define MPT_MUTEX_STD 1 #define MPT_MUTEX_PTHREAD 0 #define MPT_MUTEX_WIN32 0 #elif MPT_OS_WINDOWS #define MPT_MUTEX_STD 0 #define MPT_MUTEX_PTHREAD 0 #define MPT_MUTEX_WIN32 1 #else #define MPT_MUTEX_STD 0 #define MPT_MUTEX_PTHREAD 0 #define MPT_MUTEX_WIN32 0 #endif #if !MPT_MUTEX_STD && !MPT_MUTEX_PTHREAD && !MPT_MUTEX_WIN32 #define MPT_MUTEX_NONE 1 #else #define MPT_MUTEX_NONE 0 #endif #if defined(MODPLUG_TRACKER) && MPT_MUTEX_NONE #error "OpenMPT requires mutexes." #endif #if MPT_MUTEX_STD #include #elif MPT_MUTEX_WIN32 #include #elif MPT_MUTEX_PTHREAD #include #endif // MPT_MUTEX OPENMPT_NAMESPACE_BEGIN namespace mpt { #if MPT_MUTEX_STD typedef std::mutex mutex; typedef std::recursive_mutex recursive_mutex; #elif MPT_MUTEX_WIN32 // compatible with c++11 std::mutex, can eventually be replaced without touching any usage site class mutex { private: CRITICAL_SECTION impl; public: mutex() { InitializeCriticalSection(&impl); } ~mutex() { DeleteCriticalSection(&impl); } void lock() { EnterCriticalSection(&impl); } bool try_lock() { return TryEnterCriticalSection(&impl) ? true : false; } void unlock() { LeaveCriticalSection(&impl); } }; // compatible with c++11 std::recursive_mutex, can eventually be replaced without touching any usage site class recursive_mutex { private: CRITICAL_SECTION impl; public: recursive_mutex() { InitializeCriticalSection(&impl); } ~recursive_mutex() { DeleteCriticalSection(&impl); } void lock() { EnterCriticalSection(&impl); } bool try_lock() { return TryEnterCriticalSection(&impl) ? true : false; } void unlock() { LeaveCriticalSection(&impl); } }; #elif MPT_MUTEX_PTHREAD class mutex { private: pthread_mutex_t hLock; public: mutex() { pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); pthread_mutex_init(&hLock, &attr); pthread_mutexattr_destroy(&attr); } ~mutex() { pthread_mutex_destroy(&hLock); } void lock() { pthread_mutex_lock(&hLock); } bool try_lock() { return (pthread_mutex_trylock(&hLock) == 0); } void unlock() { pthread_mutex_unlock(&hLock); } }; class recursive_mutex { private: pthread_mutex_t hLock; public: recursive_mutex() { pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&hLock, &attr); pthread_mutexattr_destroy(&attr); } ~recursive_mutex() { pthread_mutex_destroy(&hLock); } void lock() { pthread_mutex_lock(&hLock); } bool try_lock() { return (pthread_mutex_trylock(&hLock) == 0); } void unlock() { pthread_mutex_unlock(&hLock); } }; #else // MPT_MUTEX_NONE class mutex { public: mutex() { } ~mutex() { } void lock() { } bool try_lock() { return true; } void unlock() { } }; class recursive_mutex { public: recursive_mutex() { } ~recursive_mutex() { } void lock() { } bool try_lock() { return true; } void unlock() { } }; #endif // MPT_MUTEX #if MPT_MUTEX_STD #define MPT_LOCK_GUARD std::lock_guard #else // !MPT_MUTEX_STD // compatible with c++11 std::lock_guard, can eventually be replaced without touching any usage site template< typename mutex_type > class lock_guard { private: mutex_type & mutex; public: lock_guard( mutex_type & m ) : mutex(m) { mutex.lock(); } ~lock_guard() { mutex.unlock(); } }; #define MPT_LOCK_GUARD mpt::lock_guard #endif // MPT_MUTEX_STD #ifdef MODPLUG_TRACKER class recursive_mutex_with_lock_count { private: mpt::recursive_mutex mutex; long lockCount; public: recursive_mutex_with_lock_count() : lockCount(0) { return; } ~recursive_mutex_with_lock_count() { return; } void lock() { mutex.lock(); lockCount++; } void unlock() { lockCount--; mutex.unlock(); } public: bool IsLockedByCurrentThread() // DEBUGGING only { bool islocked = false; if(mutex.try_lock()) { islocked = (lockCount > 0); mutex.unlock(); } return islocked; } }; #endif // MODPLUG_TRACKER } // namespace mpt OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/mptOS.cpp0000644000372100037210000003137313161656666017343 00000000000000/* * mptOS.cpp * --------- * Purpose: Operating system version information. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "mptOS.h" #if MPT_OS_WINDOWS #include #endif OPENMPT_NAMESPACE_BEGIN namespace mpt { namespace Windows { #if MPT_OS_WINDOWS #if !MPT_OS_WINDOWS_WINRT static uint32 VersionDecimalTo_WIN32_WINNT(uint32 major, uint32 minor) { // GetVersionEx returns decimal. // _WIN32_WINNT macro uses BCD for the minor byte (see Windows 98 / ME). // We use what _WIN32_WINNT does. uint32 result = 0; minor = mpt::clamp(minor, 0, 99); result |= major; result <<= 8; result |= minor/10*0x10 + minor%10; return result; } #endif // !MPT_OS_WINDOWS_WINRT static void GatherWindowsVersion(uint32 & SystemVersion) { // Initialize to used SDK version SystemVersion = #if NTDDI_VERSION >= 0x0A000000 // NTDDI_WIN10 mpt::Windows::Version::Win10 #elif NTDDI_VERSION >= 0x06030000 // NTDDI_WINBLUE mpt::Windows::Version::Win81 #elif NTDDI_VERSION >= 0x06020000 // NTDDI_WIN8 mpt::Windows::Version::Win8 #elif NTDDI_VERSION >= 0x06010000 // NTDDI_WIN7 mpt::Windows::Version::Win7 #elif NTDDI_VERSION >= 0x06000000 // NTDDI_VISTA mpt::Windows::Version::WinVista #elif NTDDI_VERSION >= 0x05020000 // NTDDI_WS03 mpt::Windows::Version::WinXP64 #elif NTDDI_VERSION >= NTDDI_WINXP mpt::Windows::Version::WinXP #elif NTDDI_VERSION >= NTDDI_WIN2K mpt::Windows::Version::Win2000 #else mpt::Windows::Version::WinNT4 #endif ; #if !MPT_OS_WINDOWS_WINRT OSVERSIONINFOEXW versioninfoex; MemsetZero(versioninfoex); versioninfoex.dwOSVersionInfoSize = sizeof(versioninfoex); #if MPT_COMPILER_MSVC #pragma warning(push) #pragma warning(disable:4996) // 'GetVersionExW': was declared deprecated #endif // MPT_COMPILER_MSVC #if MPT_COMPILER_CLANG || MPT_COMPILER_MSVCCLANGC2 #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" #endif // MPT_COMPILER_CLANG GetVersionExW((LPOSVERSIONINFOW)&versioninfoex); #if MPT_COMPILER_MSVC #pragma warning(pop) #endif // MPT_COMPILER_MSVC #if MPT_COMPILER_CLANG || MPT_COMPILER_MSVCCLANGC2 #pragma clang diagnostic pop #endif // MPT_COMPILER_CLANG SystemVersion = VersionDecimalTo_WIN32_WINNT(versioninfoex.dwMajorVersion, versioninfoex.dwMinorVersion); #endif // !MPT_OS_WINDOWS_WINRT } #ifdef MODPLUG_TRACKER namespace { struct WindowsVersionCache { uint32 SystemVersion; WindowsVersionCache() : SystemVersion(mpt::Windows::Version::WinNT4) { GatherWindowsVersion(SystemVersion); } }; } static void GatherWindowsVersionFromCache(uint32 & SystemVersion) { static WindowsVersionCache gs_WindowsVersionCache; SystemVersion = gs_WindowsVersionCache.SystemVersion; } #endif // MODPLUG_TRACKER #endif // MPT_OS_WINDOWS Version::Version() : SystemIsWindows(false) , SystemVersion(mpt::Windows::Version::WinNT4) { return; } mpt::Windows::Version Version::Current() { mpt::Windows::Version result; #if MPT_OS_WINDOWS result.SystemIsWindows = true; #ifdef MODPLUG_TRACKER GatherWindowsVersionFromCache(result.SystemVersion); #else // !MODPLUG_TRACKER GatherWindowsVersion(result.SystemVersion); #endif // MODPLUG_TRACKER #endif // MPT_OS_WINDOWS return result; } bool Version::IsWindows() const { return SystemIsWindows; } bool Version::IsBefore(mpt::Windows::Version::Number version) const { if(!SystemIsWindows) { return false; } return (SystemVersion < static_cast(version)); } bool Version::IsAtLeast(mpt::Windows::Version::Number version) const { if(!SystemIsWindows) { return false; } return (SystemVersion >= static_cast(version)); } static MPT_CONSTEXPR11_VAR struct { Version::Number version; const MPT_UCHAR_TYPE * name; } versionMap[] = { { mpt::Windows::Version::WinNewer, MPT_ULITERAL("Windows 10 (or newer)") }, { mpt::Windows::Version::Win10, MPT_ULITERAL("Windows 10") }, { mpt::Windows::Version::Win81, MPT_ULITERAL("Windows 8.1") }, { mpt::Windows::Version::Win8, MPT_ULITERAL("Windows 8") }, { mpt::Windows::Version::Win7, MPT_ULITERAL("Windows 7") }, { mpt::Windows::Version::WinVista, MPT_ULITERAL("Windows Vista") }, { mpt::Windows::Version::WinXP64, MPT_ULITERAL("Windows XP x64 / Windows Server 2003") }, { mpt::Windows::Version::WinXP, MPT_ULITERAL("Windows XP") }, { mpt::Windows::Version::Win2000, MPT_ULITERAL("Windows 2000") }, { mpt::Windows::Version::WinME, MPT_ULITERAL("Windows ME") }, { mpt::Windows::Version::Win98, MPT_ULITERAL("Windows 98") }, { mpt::Windows::Version::WinNT4, MPT_ULITERAL("Windows NT4") } }; mpt::ustring Version::VersionToString(uint16 version) { mpt::ustring result; for(const auto &v : versionMap) { if(version > v.version) { result = MPT_USTRING("> ") + v.name; break; } else if(version == v.version) { result = v.name; break; } } if(result.empty()) { result = mpt::format(MPT_USTRING("0x%1"))(mpt::ufmt::dec0<4>(version)); } return result; } mpt::ustring Version::VersionToString(Number version) { return VersionToString(static_cast(version)); } mpt::ustring Version::GetName() const { mpt::ustring name = MPT_USTRING("Generic Windows NT"); for(const auto &v : versionMap) { if(mpt::Windows::Version::IsAtLeast(v.version)) { name = v.name; break; } } mpt::ustring result = name; #if defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS if(mpt::Windows::IsWine()) { mpt::Wine::VersionContext v; if(v.Version().IsValid()) { result = mpt::format(MPT_USTRING("Wine %1 (%2)"))( v.Version().AsString() , name ); } else { result = mpt::format(MPT_USTRING("Wine (unknown version: '%1') (%2)"))( mpt::ToUnicode(mpt::CharsetUTF8, v.RawVersion()) , name ); } } #endif // MODPLUG_TRACKER && MPT_OS_WINDOWS return result; } #ifdef MODPLUG_TRACKER mpt::ustring Version::GetNameShort() const { mpt::ustring name; if(mpt::Windows::IsWine()) { mpt::Wine::VersionContext v; if(v.Version().IsValid()) { name = mpt::format(MPT_USTRING("wine-%1"))(v.Version().AsString()); } else if(v.RawVersion().length() > 0) { name = MPT_USTRING("wine-") + Util::BinToHex(mpt::as_span(v.RawVersion())); } else { name = MPT_USTRING("wine-"); } name += MPT_USTRING("-") + Util::BinToHex(mpt::as_span(v.RawHostSysName())); } else { name = mpt::format(MPT_USTRING("%1.%2"))(mpt::ufmt::dec(SystemVersion >> 8), mpt::ufmt::HEX0<2>(SystemVersion & 0xFF)); } return name; } #endif // MODPLUG_TRACKER mpt::Windows::Version::Number Version::GetMinimumKernelLevel() { uint16 minimumKernelVersion = 0; #if MPT_OS_WINDOWS && MPT_COMPILER_MSVC #if !defined(MPT_BUILD_TARGET_XP) minimumKernelVersion = std::max(minimumKernelVersion, mpt::Windows::Version::WinVista); #else minimumKernelVersion = std::max(minimumKernelVersion, mpt::Windows::Version::WinXP); #endif #endif return static_cast(minimumKernelVersion); } mpt::Windows::Version::Number Version::GetMinimumAPILevel() { uint16 minimumApiVersion = 0; #if MPT_OS_WINDOWS && defined(_WIN32_WINNT) minimumApiVersion = std::max(minimumApiVersion, _WIN32_WINNT); #endif return static_cast(minimumApiVersion); } #if defined(MODPLUG_TRACKER) #if MPT_OS_WINDOWS static bool GatherSystemIsWine() { bool SystemIsWine = false; HMODULE hNTDLL = LoadLibraryW(L"ntdll.dll"); if(hNTDLL) { SystemIsWine = (GetProcAddress(hNTDLL, "wine_get_version") != NULL); FreeLibrary(hNTDLL); hNTDLL = NULL; } return SystemIsWine; } #endif // MPT_OS_WINDOWS #if defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS namespace { struct SystemIsWineCache { bool SystemIsWine; SystemIsWineCache() : SystemIsWine(GatherSystemIsWine()) { return; } SystemIsWineCache(bool isWine) : SystemIsWine(isWine) { return; } }; } #endif // MODPLUG_TRACKER && MPT_OS_WINDOWS static bool SystemIsWine(bool allowDetection = true) { #if defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS static SystemIsWineCache gs_SystemIsWineCache = allowDetection ? SystemIsWineCache() : SystemIsWineCache(false); if(!allowDetection) { // catch too late calls of PreventWineDetection MPT_ASSERT(!gs_SystemIsWineCache.SystemIsWine); } return gs_SystemIsWineCache.SystemIsWine; #elif MPT_OS_WINDOWS MPT_UNREFERENCED_PARAMETER(allowDetection); return GatherSystemIsWine(); #else MPT_UNREFERENCED_PARAMETER(allowDetection); return false; #endif } void PreventWineDetection() { SystemIsWine(false); } bool IsOriginal() { return mpt::Windows::Version::Current().IsWindows() && !SystemIsWine(); } bool IsWine() { return mpt::Windows::Version::Current().IsWindows() && SystemIsWine(); } #endif // MODPLUG_TRACKER } // namespace Windows } // namespace mpt #if defined(MODPLUG_TRACKER) namespace mpt { namespace Wine { Version::Version() : valid(false) , vmajor(0) , vminor(0) , vupdate(0) { return; } Version::Version(const mpt::ustring &rawVersion) : valid(false) , vmajor(0) , vminor(0) , vupdate(0) { if(rawVersion.empty()) { return; } std::vector version = mpt::String::Split(rawVersion, MPT_USTRING(".")); if(version.size() < 2) { return; } mpt::ustring parsedVersion = mpt::String::Combine(version, MPT_USTRING(".")); std::size_t len = std::min(parsedVersion.length(), rawVersion.length()); if(len == 0) { return; } if(parsedVersion.substr(0, len) != rawVersion.substr(0, len)) { return; } valid = true; vmajor = version[0]; vminor = version[1]; vupdate = (version.size() >= 3) ? version[2] : 0; } Version::Version(uint8 vmajor, uint8 vminor, uint8 vupdate) : valid((vmajor > 0) || (vminor > 0) || (vupdate > 0)) , vmajor(vmajor) , vminor(vminor) , vupdate(vupdate) { return; } mpt::Wine::Version Version::FromInteger(uint32 version) { mpt::Wine::Version result; result.valid = (version <= 0xffffff); result.vmajor = static_cast(version >> 16); result.vminor = static_cast(version >> 8); result.vupdate = static_cast(version >> 0); return result; } bool Version::IsValid() const { return valid; } mpt::ustring Version::AsString() const { return mpt::ufmt::dec(vmajor) + MPT_USTRING(".") + mpt::ufmt::dec(vminor) + MPT_USTRING(".") + mpt::ufmt::dec(vupdate); } uint32 Version::AsInteger() const { uint32 version = 0; version |= static_cast(vmajor) << 16; version |= static_cast(vminor) << 8; version |= static_cast(vupdate) << 0; return version; } bool Version::IsBefore(mpt::Wine::Version other) const { if(!IsValid()) { return false; } return (AsInteger() < other.AsInteger()); } bool Version::IsAtLeast(mpt::Wine::Version other) const { if(!IsValid()) { return false; } return (AsInteger() >= other.AsInteger()); } mpt::Wine::Version GetMinimumWineVersion() { mpt::Wine::Version minimumWineVersion = mpt::Wine::Version(0,0,0); #if MPT_OS_WINDOWS && MPT_COMPILER_MSVC #if !defined(MPT_BUILD_TARGET_XP) minimumWineVersion = mpt::Wine::Version(1,8,0); #else minimumWineVersion = mpt::Wine::Version(1,6,0); #endif #endif return minimumWineVersion; } VersionContext::VersionContext() : m_IsWine(false) , m_HostIsLinux(false) , m_HostIsBSD(false) { #if MPT_OS_WINDOWS m_IsWine = mpt::Windows::IsWine(); if(!m_IsWine) { return; } m_NTDLL = mpt::Library(mpt::LibraryPath::FullPath(MPT_PATHSTRING("ntdll.dll"))); if(m_NTDLL.IsValid()) { const char * (__cdecl * wine_get_version)(void) = nullptr; const char * (__cdecl * wine_get_build_id)(void) = nullptr; void (__cdecl * wine_get_host_version)(const char * *, const char * *) = nullptr; m_NTDLL.Bind(wine_get_version, "wine_get_version"); m_NTDLL.Bind(wine_get_build_id, "wine_get_build_id"); m_NTDLL.Bind(wine_get_host_version, "wine_get_host_version"); const char * wine_version = nullptr; const char * wine_build_id = nullptr; const char * wine_host_sysname = nullptr; const char * wine_host_release = nullptr; wine_version = wine_get_version ? wine_get_version() : ""; wine_build_id = wine_get_build_id ? wine_get_build_id() : ""; if(wine_get_host_version) { wine_get_host_version(&wine_host_sysname, &wine_host_release); } m_RawVersion = wine_version ? wine_version : ""; m_RawBuildID = wine_build_id ? wine_build_id : ""; m_RawHostSysName = wine_host_sysname ? wine_host_sysname : ""; m_RawHostRelease = wine_host_release ? wine_host_release : ""; } m_Version = mpt::Wine::Version(mpt::ToUnicode(mpt::CharsetUTF8, m_RawVersion)); m_HostIsLinux = (m_RawHostSysName == "Linux"); m_HostIsBSD = (m_RawHostSysName == "FreeBSD" || m_RawHostSysName == "DragonFly" || m_RawHostSysName == "NetBSD" || m_RawHostSysName == "OpenBSD"); #endif // MPT_OS_WINDOWS } } // namespace Wine } // namespace mpt #endif // MODPLUG_TRACKER OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/StringFixer.h0000644000372100037210000002660713176066711020206 00000000000000/* * StringFixer.h * ------------- * Purpose: Various functions for "fixing" char array strings for writing to or * reading from module files, or for securing char arrays in general. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include #include #include OPENMPT_NAMESPACE_BEGIN namespace mpt { namespace String { #if MPT_COMPILER_MSVC #pragma warning(push) #pragma warning(disable:4127) // conditional expression is constant #endif // MPT_COMPILER_MSVC // Sets last character to null in given char array. // Size of the array must be known at compile time. template void SetNullTerminator(char (&buffer)[size]) { STATIC_ASSERT(size > 0); buffer[size - 1] = 0; } inline void SetNullTerminator(char *buffer, size_t size) { MPT_ASSERT(size > 0); buffer[size - 1] = 0; } template void SetNullTerminator(wchar_t (&buffer)[size]) { STATIC_ASSERT(size > 0); buffer[size - 1] = 0; } inline void SetNullTerminator(wchar_t *buffer, size_t size) { MPT_ASSERT(size > 0); buffer[size - 1] = 0; } // Remove any chars after the first null char template void FixNullString(char (&buffer)[size]) { STATIC_ASSERT(size > 0); SetNullTerminator(buffer); size_t pos = 0; // Find the first null char. while(pos < size && buffer[pos] != '\0') { pos++; } // Remove everything after the null char. while(pos < size) { buffer[pos++] = '\0'; } } inline void FixNullString(std::string & str) { for(std::size_t i = 0; i < str.length(); ++i) { if(str[i] == '\0') { // if we copied \0 in the middle of the buffer, terminate std::string here str.resize(i); break; } } } enum ReadWriteMode { // Reading / Writing: Standard null-terminated string handling. nullTerminated, // Reading: Source string is not guaranteed to be null-terminated (if it fills the whole char array). // Writing: Destination string is not guaranteed to be null-terminated (if it fills the whole char array). maybeNullTerminated, // Reading: String may contain null characters anywhere. They should be treated as spaces. // Writing: A space-padded string is written. spacePadded, // Reading: String may contain null characters anywhere. The last character is ignored (it is supposed to be 0). // Writing: A space-padded string with a trailing null is written. spacePaddedNull }; namespace detail { static inline char NullToSpace(const char &c) { return (c != '\0') ? c : ' '; } } // Copy a string from srcBuffer to destBuffer using a given read mode. // Used for reading strings from files. // Only use this version of the function if the size of the source buffer is variable. template void Read(std::string &dest, const Tbyte *srcBuffer, size_t srcSize) { const char *src = mpt::byte_cast(srcBuffer); dest.clear(); if(mode == nullTerminated || mode == spacePaddedNull) { // We assume that the last character of the source buffer is null. if(srcSize > 0) { srcSize -= 1; } } if(mode == nullTerminated || mode == maybeNullTerminated) { // Copy null-terminated string, stopping at null. try { dest.assign(src, std::find(src, src + srcSize, '\0')); } MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e) { MPT_EXCEPTION_DELETE_OUT_OF_MEMORY(e); } } else if(mode == spacePadded || mode == spacePaddedNull) { try { // Copy string over. dest.assign(src, src + srcSize); // Convert null characters to spaces. std::transform(dest.begin(), dest.end(), dest.begin(), detail::NullToSpace); // Trim trailing spaces. dest = mpt::String::RTrim(dest, std::string(" ")); } MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e) { MPT_EXCEPTION_DELETE_OUT_OF_MEMORY(e); } } } // Copy a charset encoded string from srcBuffer to destBuffer using a given read mode. // Used for reading strings from files. // Only use this version of the function if the size of the source buffer is variable. template void Read(mpt::ustring &dest, mpt::Charset charset, const Tbyte *srcBuffer, size_t srcSize) { std::string tmp; Read(tmp, srcBuffer, srcSize); dest = mpt::ToUnicode(charset, tmp); } // Used for reading strings from files. // Preferrably use this version of the function, it is safer. template void Read(std::string &dest, const Tbyte (&srcBuffer)[srcSize]) { STATIC_ASSERT(srcSize > 0); Read(dest, srcBuffer, srcSize); } // Used for reading charset encoded strings from files. // Preferrably use this version of the function, it is safer. template void Read(mpt::ustring &dest, mpt::Charset charset, const Tbyte(&srcBuffer)[srcSize]) { std::string tmp; Read(tmp, srcBuffer); dest = mpt::ToUnicode(charset, tmp); } // Copy a string from srcBuffer to destBuffer using a given read mode. // Used for reading strings from files. // Only use this version of the function if the size of the source buffer is variable. template void Read(char (&destBuffer)[destSize], const Tbyte *srcBuffer, size_t srcSize) { STATIC_ASSERT(destSize > 0); char *dst = destBuffer; const char *src = mpt::byte_cast(srcBuffer); if(mode == nullTerminated || mode == spacePaddedNull) { // We assume that the last character of the source buffer is null. if(srcSize > 0) { srcSize -= 1; } } if(mode == nullTerminated || mode == maybeNullTerminated) { // Copy string and leave one character space in the destination buffer for null. dst = std::copy(src, std::find(src, src + std::min(srcSize, destSize - 1), '\0'), dst); } else if(mode == spacePadded || mode == spacePaddedNull) { // Copy string and leave one character space in the destination buffer for null. // Convert nulls to spaces while copying. dst = std::replace_copy(src, src + std::min(srcSize, destSize - 1), dst, '\0', ' '); // Rewind dst to the first of any trailing spaces. while(dst - destBuffer > 0) { dst--; char c = *dst; if(c != ' ') { dst++; break; } } } // Fill rest of string with nulls. std::fill(dst, destBuffer + destSize, '\0'); } // Used for reading strings from files. // Preferrably use this version of the function, it is safer. template void Read(char (&destBuffer)[destSize], const Tbyte (&srcBuffer)[srcSize]) { STATIC_ASSERT(destSize > 0); STATIC_ASSERT(srcSize > 0); Read(destBuffer, srcBuffer, srcSize); } // Copy a string from srcBuffer to destBuffer using a given write mode. // You should only use this function if src and dest are dynamically sized, // otherwise use one of the safer overloads below. template void Write(char *destBuffer, const size_t destSize, const char *srcBuffer, const size_t srcSize) { MPT_ASSERT(destSize > 0); const size_t maxSize = std::min(destSize, srcSize); char *dst = destBuffer; const char *src = srcBuffer; // First, copy over null-terminated string. size_t pos = maxSize; while(pos > 0) { if((*dst = *src) == '\0') { break; } pos--; dst++; src++; } if(mode == nullTerminated || mode == maybeNullTerminated) { // Fill rest of string with nulls. std::fill(dst, dst + destSize - maxSize + pos, '\0'); } else if(mode == spacePadded || mode == spacePaddedNull) { // Fill the rest of the destination string with spaces. std::fill(dst, dst + destSize - maxSize + pos, ' '); } if(mode == nullTerminated || mode == spacePaddedNull) { // Make sure that destination is really null-terminated. SetNullTerminator(destBuffer, destSize); } } // Copy a string from srcBuffer to a dynamically sized std::vector destBuffer using a given write mode. // Used for writing strings to files. // Only use this version of the function if the size of the source buffer is variable and the destination buffer also has variable size. template void Write(std::vector &destBuffer, const char *srcBuffer, const size_t srcSize) { MPT_ASSERT(destBuffer.size() > 0); Write(destBuffer.data(), destBuffer.size(), srcBuffer, srcSize); } // Copy a string from srcBuffer to destBuffer using a given write mode. // Used for writing strings to files. // Only use this version of the function if the size of the source buffer is variable. template void Write(char (&destBuffer)[destSize], const char *srcBuffer, const size_t srcSize) { STATIC_ASSERT(destSize > 0); Write(destBuffer, destSize, srcBuffer, srcSize); } // Copy a string from srcBuffer to destBuffer using a given write mode. // Used for writing strings to files. // Preferrably use this version of the function, it is safer. template void Write(char (&destBuffer)[destSize], const char (&srcBuffer)[srcSize]) { STATIC_ASSERT(destSize > 0); STATIC_ASSERT(srcSize > 0); Write(destBuffer, srcBuffer, srcSize); } template void Write(char *destBuffer, const size_t destSize, const std::string &src) { MPT_ASSERT(destSize > 0); Write(destBuffer, destSize, src.c_str(), src.length()); } template void Write(std::vector &destBuffer, const std::string &src) { MPT_ASSERT(destBuffer.size() > 0); Write(destBuffer, src.c_str(), src.length()); } template void Write(char (&destBuffer)[destSize], const std::string &src) { STATIC_ASSERT(destSize > 0); Write(destBuffer, src.c_str(), src.length()); } // Copy from a char array to a fixed size char array. template void CopyN(char (&destBuffer)[destSize], const char *srcBuffer, const size_t srcSize = std::numeric_limits::max()) { const size_t copySize = std::min(destSize - 1u, srcSize); std::strncpy(destBuffer, srcBuffer, copySize); destBuffer[copySize] = '\0'; } // Copy at most srcSize characters from srcBuffer to a std::string. static inline void CopyN(std::string &dest, const char *srcBuffer, const size_t srcSize = std::numeric_limits::max()) { dest.assign(srcBuffer, srcBuffer + mpt::strnlen(srcBuffer, srcSize)); } // Copy from one fixed size char array to another one. template void Copy(char (&destBuffer)[destSize], const char (&srcBuffer)[srcSize]) { CopyN(destBuffer, srcBuffer, srcSize); } // Copy from a std::string to a fixed size char array. template void Copy(char (&destBuffer)[destSize], const std::string &src) { CopyN(destBuffer, src.c_str(), src.length()); } // Copy from a fixed size char array to a std::string. template void Copy(std::string &dest, const char (&srcBuffer)[srcSize]) { CopyN(dest, srcBuffer, srcSize); } // Copy from a std::string to a std::string. static inline void Copy(std::string &dest, const std::string &src) { dest.assign(src); } #if MPT_COMPILER_MSVC #pragma warning(pop) #endif // MPT_COMPILER_MSVC } } // namespace mpt::String OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/mptStringParse.h0000644000372100037210000002014113127664066020712 00000000000000/* * mptStringParse.h * ---------------- * Purpose: Convert strings to other types. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once OPENMPT_NAMESPACE_BEGIN bool ConvertStrToBool(const std::string &str); signed char ConvertStrToSignedChar(const std::string &str); unsigned char ConvertStrToUnsignedChar(const std::string &str); signed short ConvertStrToSignedShort(const std::string &str); unsigned short ConvertStrToUnsignedShort(const std::string &str); signed int ConvertStrToSignedInt(const std::string &str); unsigned int ConvertStrToUnsignedInt(const std::string &str); signed long ConvertStrToSignedLong(const std::string &str); unsigned long ConvertStrToUnsignedLong(const std::string &str); signed long long ConvertStrToSignedLongLong(const std::string &str); unsigned long long ConvertStrToUnsignedLongLong(const std::string &str); float ConvertStrToFloat(const std::string &str); double ConvertStrToDouble(const std::string &str); long double ConvertStrToLongDouble(const std::string &str); template inline T ConvertStrTo(const std::string &str); // not defined, generates compiler error for non-specialized types template<> inline std::string ConvertStrTo(const std::string &str) { return str; } template<> inline bool ConvertStrTo(const std::string &str) { return ConvertStrToBool(str); } template<> inline signed char ConvertStrTo(const std::string &str) { return ConvertStrToSignedChar(str); } template<> inline unsigned char ConvertStrTo(const std::string &str) { return ConvertStrToUnsignedChar(str); } template<> inline signed short ConvertStrTo(const std::string &str) { return ConvertStrToSignedShort(str); } template<> inline unsigned short ConvertStrTo(const std::string &str) { return ConvertStrToUnsignedShort(str); } template<> inline signed int ConvertStrTo(const std::string &str) { return ConvertStrToSignedInt(str); } template<> inline unsigned int ConvertStrTo(const std::string &str) { return ConvertStrToUnsignedInt(str); } template<> inline signed long ConvertStrTo(const std::string &str) { return ConvertStrToSignedLong(str); } template<> inline unsigned long ConvertStrTo(const std::string &str) { return ConvertStrToUnsignedLong(str); } template<> inline signed long long ConvertStrTo(const std::string &str) { return ConvertStrToSignedLongLong(str); } template<> inline unsigned long long ConvertStrTo(const std::string &str) { return ConvertStrToUnsignedLongLong(str); } template<> inline float ConvertStrTo(const std::string &str) { return ConvertStrToFloat(str); } template<> inline double ConvertStrTo(const std::string &str) { return ConvertStrToDouble(str); } template<> inline long double ConvertStrTo(const std::string &str) { return ConvertStrToLongDouble(str); } #if MPT_WSTRING_FORMAT bool ConvertStrToBool(const std::wstring &str); signed char ConvertStrToSignedChar(const std::wstring &str); unsigned char ConvertStrToUnsignedChar(const std::wstring &str); signed short ConvertStrToSignedShort(const std::wstring &str); unsigned short ConvertStrToUnsignedShort(const std::wstring &str); signed int ConvertStrToSignedInt(const std::wstring &str); unsigned int ConvertStrToUnsignedInt(const std::wstring &str); signed long ConvertStrToSignedLong(const std::wstring &str); unsigned long ConvertStrToUnsignedLong(const std::wstring &str); signed long long ConvertStrToSignedLongLong(const std::wstring &str); unsigned long long ConvertStrToUnsignedLongLong(const std::wstring &str); float ConvertStrToFloat(const std::wstring &str); double ConvertStrToDouble(const std::wstring &str); long double ConvertStrToLongDouble(const std::wstring &str); template inline T ConvertStrTo(const std::wstring &str); // not defined, generates compiler error for non-specialized types template<> inline std::wstring ConvertStrTo(const std::wstring &str) { return str; } template<> inline bool ConvertStrTo(const std::wstring &str) { return ConvertStrToBool(str); } template<> inline signed char ConvertStrTo(const std::wstring &str) { return ConvertStrToSignedChar(str); } template<> inline unsigned char ConvertStrTo(const std::wstring &str) { return ConvertStrToUnsignedChar(str); } template<> inline signed short ConvertStrTo(const std::wstring &str) { return ConvertStrToSignedShort(str); } template<> inline unsigned short ConvertStrTo(const std::wstring &str) { return ConvertStrToUnsignedShort(str); } template<> inline signed int ConvertStrTo(const std::wstring &str) { return ConvertStrToSignedInt(str); } template<> inline unsigned int ConvertStrTo(const std::wstring &str) { return ConvertStrToUnsignedInt(str); } template<> inline signed long ConvertStrTo(const std::wstring &str) { return ConvertStrToSignedLong(str); } template<> inline unsigned long ConvertStrTo(const std::wstring &str) { return ConvertStrToUnsignedLong(str); } template<> inline signed long long ConvertStrTo(const std::wstring &str) { return ConvertStrToSignedLongLong(str); } template<> inline unsigned long long ConvertStrTo(const std::wstring &str) { return ConvertStrToUnsignedLongLong(str); } template<> inline float ConvertStrTo(const std::wstring &str) { return ConvertStrToFloat(str); } template<> inline double ConvertStrTo(const std::wstring &str) { return ConvertStrToDouble(str); } template<> inline long double ConvertStrTo(const std::wstring &str) { return ConvertStrToLongDouble(str); } #endif #if defined(_MFC_VER) template inline T ConvertStrTo(const CString &str) { #if defined(UNICODE) && MPT_WSTRING_FORMAT return ConvertStrTo(mpt::ToWide(str)); #elif defined(UNICODE) return ConvertStrTo(mpt::ToCharset(mpt::CharsetUTF8, str)); #else // !UNICODE return ConvertStrTo(mpt::ToCharset(mpt::CharsetLocale, str)); #endif // UNICODE } #endif // _MFC_VER template inline T ConvertStrTo(const char *str) { if(!str) { return T(); } return ConvertStrTo(std::string(str)); } #if MPT_WSTRING_FORMAT #if MPT_USTRING_MODE_UTF8 template<> inline mpt::ustring ConvertStrTo(const std::wstring &str) { return mpt::ToUnicode(str); } #endif template inline T ConvertStrTo(const wchar_t *str) { if(!str) { return T(); } return ConvertStrTo(std::wstring(str)); } #endif #if MPT_USTRING_MODE_UTF8 template inline T ConvertStrTo(const mpt::ustring &str) { return ConvertStrTo(mpt::ToCharset(mpt::CharsetUTF8, str)); } template<> inline mpt::ustring ConvertStrTo(const mpt::ustring &str) { return str; } #if MPT_WSTRING_CONVERT template<> inline std::wstring ConvertStrTo(const mpt::ustring &str) { return mpt::ToWide(str); } #endif #endif namespace mpt { namespace String { namespace Parse { unsigned char HexToUnsignedChar(const std::string &str); unsigned short HexToUnsignedShort(const std::string &str); unsigned int HexToUnsignedInt(const std::string &str); unsigned long HexToUnsignedLong(const std::string &str); unsigned long long HexToUnsignedLongLong(const std::string &str); template inline T Hex(const std::string &str); // not defined, generates compiler error for non-specialized types template<> inline unsigned char Hex(const std::string &str) { return HexToUnsignedChar(str); } template<> inline unsigned short Hex(const std::string &str) { return HexToUnsignedShort(str); } template<> inline unsigned int Hex(const std::string &str) { return HexToUnsignedInt(str); } template<> inline unsigned long Hex(const std::string &str) { return HexToUnsignedLong(str); } template<> inline unsigned long long Hex(const std::string &str) { return HexToUnsignedLongLong(str); } template inline T Hex(const char *str) { if(!str) { return T(); } return Hex(std::string(str)); } #if MPT_WSTRING_FORMAT template inline T Hex(const std::wstring &str) { return Hex(mpt::ToCharset(mpt::CharsetUTF8, str)); } template inline T Hex(const wchar_t *str) { if(!str) { return T(); } return Hex(std::wstring(str)); } #endif #if MPT_USTRING_MODE_UTF8 template inline T Hex(const mpt::ustring &str) { return Hex(mpt::ToCharset(mpt::CharsetUTF8, str)); } #endif } // namespace Parse } // namespace String } // namespace mpt OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/mptTime.h0000644000372100037210000000475313127113532017345 00000000000000/* * mptTime.h * --------- * Purpose: Various time utility functions. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include #include OPENMPT_NAMESPACE_BEGIN namespace mpt { namespace Date { #if defined(MODPLUG_TRACKER) #if MPT_OS_WINDOWS namespace ANSI { // uint64 counts 100ns since 1601-01-01T00:00Z uint64 Now(); mpt::ustring ToString(uint64 time100ns); // i.e. 2015-01-15 18:32:01.718 } // namespacee ANSI #endif // MPT_OS_WINDOWS #endif // MODPLUG_TRACKER class Unix { // int64 counts 1s since 1970-01-01T00:00Z private: int64 Value; public: Unix(); explicit Unix(int64 unixtime); operator int64 () const; public: static mpt::Date::Unix FromUTC(tm timeUtc); tm AsUTC() const; }; mpt::ustring ToShortenedISO8601(tm date); // i.e. 2015-01-15T18:32:01Z } // namespace Date } // namespace mpt #ifdef MODPLUG_TRACKER namespace Util { #if MPT_OS_WINDOWS // RAII wrapper around timeBeginPeriod/timeEndPeriod/timeGetTime (on Windows). // This clock is monotonic, even across changing its resolution. // This is needed to synchronize time in Steinberg APIs (ASIO and VST). class MultimediaClock { private: uint32 m_CurrentPeriod; private: void Init(); void SetPeriod(uint32 ms); void Cleanup(); public: MultimediaClock(); MultimediaClock(uint32 ms); ~MultimediaClock(); public: // Sets the desired resolution in milliseconds, returns the obtained resolution in milliseconds. // A parameter of 0 causes the resolution to be reset to system defaults. // A return value of 0 means the resolution is unknown, but timestamps will still be valid. uint32 SetResolution(uint32 ms); // Returns obtained resolution in milliseconds. // A return value of 0 means the resolution is unknown, but timestamps will still be valid. uint32 GetResolution() const; // Returns current instantaneous timestamp in milliseconds. // The epoch (offset) of the timestamps is undefined but constant until the next system reboot. // The resolution is the value returned from GetResolution(). uint32 Now() const; // Returns current instantaneous timestamp in nanoseconds. // The epoch (offset) of the timestamps is undefined but constant until the next system reboot. // The resolution is the value returned from GetResolution() in milliseconds. uint64 NowNanoseconds() const; }; #endif // MPT_OS_WINDOWS } // namespace Util #endif // MODPLUG_TRACKER OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/mptCPU.h0000644000372100037210000000552113070741301017066 00000000000000/* * mptCPU.h * -------- * Purpose: CPU feature detection. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once OPENMPT_NAMESPACE_BEGIN #ifdef ENABLE_ASM #define PROCSUPPORT_CPUID 0x00001 // Processor supports CPUID instruction (i586) #define PROCSUPPORT_TSC 0x00002 // Processor supports RDTSC instruction (i586) #define PROCSUPPORT_CMOV 0x00004 // Processor supports conditional move instructions (i686) #define PROCSUPPORT_FPU 0x00008 // Processor supports x87 instructions #define PROCSUPPORT_MMX 0x00010 // Processor supports MMX instructions #define PROCSUPPORT_AMD_MMXEXT 0x00020 // Processor supports AMD MMX extensions #define PROCSUPPORT_AMD_3DNOW 0x00040 // Processor supports AMD 3DNow! instructions #define PROCSUPPORT_AMD_3DNOWEXT 0x00080 // Processor supports AMD 3DNow!2 instructions #define PROCSUPPORT_SSE 0x00100 // Processor supports SSE instructions #define PROCSUPPORT_SSE2 0x00200 // Processor supports SSE2 instructions #define PROCSUPPORT_SSE3 0x00400 // Processor supports SSE3 instructions #define PROCSUPPORT_SSSE3 0x00800 // Processor supports SSSE3 instructions #define PROCSUPPORT_SSE4_1 0x01000 // Processor supports SSE4.1 instructions #define PROCSUPPORT_SSE4_2 0x02000 // Processor supports SSE4.2 instructions static const uint32 PROCSUPPORT_i486 = 0u | PROCSUPPORT_FPU ; static const uint32 PROCSUPPORT_i586 = 0u | PROCSUPPORT_CPUID | PROCSUPPORT_FPU ; static const uint32 PROCSUPPORT_i686 = 0u | PROCSUPPORT_CPUID | PROCSUPPORT_CMOV | PROCSUPPORT_FPU ; static const uint32 PROCSUPPORT_x86_SSE = 0u | PROCSUPPORT_CPUID | PROCSUPPORT_CMOV | PROCSUPPORT_FPU | PROCSUPPORT_SSE ; static const uint32 PROCSUPPORT_x86_SSE2 = 0u | PROCSUPPORT_CPUID | PROCSUPPORT_CMOV | PROCSUPPORT_FPU | PROCSUPPORT_SSE | PROCSUPPORT_SSE2; static const uint32 PROCSUPPORT_AMD64 = 0u | PROCSUPPORT_CPUID | PROCSUPPORT_CMOV | PROCSUPPORT_SSE | PROCSUPPORT_SSE2; extern uint32 RealProcSupport; extern uint32 ProcSupport; extern char ProcVendorID[16+1]; extern uint16 ProcFamily; extern uint8 ProcModel; extern uint8 ProcStepping; void InitProcSupport(); // enabled processor features for inline asm and intrinsics static inline uint32 GetProcSupport() { return ProcSupport; } // available processor features static inline uint32 GetRealProcSupport() { return RealProcSupport; } #endif // ENABLE_ASM #ifdef MODPLUG_TRACKER uint32 GetMinimumProcSupportFlags(); int GetMinimumSSEVersion(); int GetMinimumAVXVersion(); #endif OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/stdafx.cpp0000644000372100037210000000074112530057313017544 00000000000000/* * StdAfx.cpp * ---------- * Purpose: Source file that includes just the standard includes * Notes : mptrack.pch will be the pre-compiled header * stdafx.obj will contain the pre-compiled type information * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" OPENMPT_NAMESPACE_BEGIN MPT_MSVC_WORKAROUND_LNK4221(stdafx) OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/Profiler.h0000644000372100037210000000421212727767750017524 00000000000000/* * Profiler.h * ---------- * Purpose: Performance measuring * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "../common/mptMutex.h" #include #include OPENMPT_NAMESPACE_BEGIN #if defined(MODPLUG_TRACKER) //#define USE_PROFILER #endif #ifdef USE_PROFILER class Profiler { public: enum Category { GUI, Audio, Notify, CategoriesCount }; static std::vector GetCategoryNames() { std::vector ret; ret.push_back("GUI"); ret.push_back("Audio"); ret.push_back("Notify"); return ret; } public: static void Update(); static std::string DumpProfiles(); static std::vector DumpCategories(); }; class Profile { private: mutable mpt::mutex datamutex; public: struct Data { uint64 Calls; uint64 Sum; int64 Overhead; uint64 Start; }; public: Data data; uint64 EnterTime; Profiler::Category Category; const char * const Name; uint64 GetTime() const; uint64 GetFrequency() const; public: Profile(Profiler::Category category, const char *name); ~Profile(); void Reset(); void Enter(); void Leave(); class Scope { private: Profile &profile; public: Scope(Profile &p) : profile(p) { profile.Enter(); } ~Scope() { profile.Leave(); } }; public: Data GetAndResetData(); }; #define OPENMPT_PROFILE_SCOPE(cat, name) \ static Profile OPENMPT_PROFILE_VAR(cat, name);\ Profile::Scope OPENMPT_PROFILE_SCOPE_VAR(OPENMPT_PROFILE_VAR); \ /**/ #define OPENMPT_PROFILE_FUNCTION(cat) OPENMPT_PROFILE_SCOPE(cat, __FUNCTION__) #else // !USE_PROFILER class Profiler { public: enum Category { CategoriesCount }; static std::vector GetCategoryNames() { return std::vector(); } public: static void Update() { } static std::string DumpProfiles() { return std::string(); } static std::vector DumpCategories() { return std::vector(); } }; #define OPENMPT_PROFILE_SCOPE(cat, name) MPT_DO { } MPT_WHILE_0 #define OPENMPT_PROFILE_FUNCTION(cat) MPT_DO { } MPT_WHILE_0 #endif // USE_PROFILER OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/Logging.h0000644000372100037210000001613212762747035017325 00000000000000/* * Logging.h * --------- * Purpose: General logging * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once OPENMPT_NAMESPACE_BEGIN /* Build time logging configuration (in BuildSettings.h): * #define NO_LOGGING Disables all logging completely. MPT_LOG calls are not even compiled but instead completely removed via the preprocessor. * #define MPT_LOG_GLOBAL_LEVEL_STATIC #define MPT_LOG_GLOBAL_LEVEL # Define the former (to anything) and the latter (to one of the log levels below) in order to statically select the verbosity of logging at build time. MPT_LOG calls that exceed the specified logging level will get dead-code eliminated at compile time. This especially means that, when setting MPT_LOG_GLOBAL_LEVEL to 0, no MPT_LOG call (with a constant level parameter) remains in the resulting binary, however, they still do get parsed and properly type checked by the compiler. Logging: If the context is related to a particular CSoundfile instance, use CSoundfile::AddToLog. Logging a simple message: MPT_LOG(LogWarning, "sounddev", "some message"); MPT_LOG(LogWarning, "sounddev", MPT_USTRING("some message")); Facility is some course grained code section identifier (more coarse grained than the current file name probably), useful to do some selective logging. Logging a more complex message: MPT_LOG(LogWarning, "sounddev", mpt::format(MPT_USTRING("Some message: foo=%1, bar=0x%2"))(foo, mpt::ufmt::hex0<8>(bar))); Note that even with full enabled logging and a runtime configurable logging level, the runtime overhead of a MPT_LOG(level, facility, text) call is just a single conditional in case the verbosity does not require logging the respective message. Even the expression "text" is not evaluated. */ enum LogLevel { LogDebug = 5, LogInformation = 4, LogNotification = 3, LogWarning = 2, LogError = 1 }; inline mpt::ustring LogLevelToString(LogLevel level) { switch(level) { case LogError: return MPT_USTRING("error"); break; case LogWarning: return MPT_USTRING("warning"); break; case LogNotification: return MPT_USTRING("notify"); break; case LogInformation: return MPT_USTRING("info"); break; case LogDebug: return MPT_USTRING("debug"); break; } return MPT_USTRING("unknown"); } class ILog { protected: virtual ~ILog() { } public: virtual void AddToLog(LogLevel level, const mpt::ustring &text) const = 0; }; namespace mpt { namespace log { #ifndef NO_LOGGING #if defined(MPT_LOG_GLOBAL_LEVEL_STATIC) #if (MPT_LOG_GLOBAL_LEVEL <= 0) // Logging framework is enabled (!NO_LOGGING) but all logging has beeen statically disabled. // All logging code gets compiled and immediately dead-code eliminated. #define MPT_LOG_IS_DISABLED #endif static const int GlobalLogLevel = MPT_LOG_GLOBAL_LEVEL ; #else extern int GlobalLogLevel; #endif #if defined(MODPLUG_TRACKER) && !defined(MPT_LOG_IS_DISABLED) extern bool FileEnabled; extern bool DebuggerEnabled; extern bool ConsoleEnabled; void SetFacilities(const std::string &solo, const std::string &blocked); bool IsFacilityActive(const char *facility); #else static MPT_FORCEINLINE bool IsFacilityActive(const char * /*facility*/ ) { return true; } #endif #endif // !NO_LOGGING struct Context { const char * const file; const int line; const char * const function; MPT_FORCEINLINE Context(const char *file, int line, const char *function) : file(file) , line(line) , function(function) { return; } MPT_FORCEINLINE Context(const Context &c) : file(c.file) , line(c.line) , function(c.function) { return; } }; // class Context #define MPT_LOG_CURRENTCONTEXT() mpt::log::Context( __FILE__ , __LINE__ , __FUNCTION__ ) #ifndef NO_LOGGING class Logger { public: // facility:ASCII void SendLogMessage(const Context &context, LogLevel level, const char *facility, const mpt::ustring &text); public: // facility:ASCII, text:ASCII (only string literals) template MPT_FORCEINLINE void SendLogMessage(const Context &context, LogLevel level, const char *facility, const char (&text)[size]) { SendLogMessage(context, level, facility, mpt::ToUnicode(mpt::CharsetASCII, text)); } }; #define MPT_LOG(level, facility, text) \ MPT_DO \ { \ MPT_MAYBE_CONSTANT_IF(mpt::log::GlobalLogLevel >= ( level )) \ { \ MPT_MAYBE_CONSTANT_IF(mpt::log::IsFacilityActive(( facility ))) \ { \ mpt::log::Logger().SendLogMessage( MPT_LOG_CURRENTCONTEXT() , ( level ), ( facility ), ( text )); \ } \ } \ } MPT_WHILE_0 \ /**/ #define MPT_LEGACY_LOGLEVEL LogDebug class LegacyLogger : public Logger { private: const Context context; public: LegacyLogger(const Context &context) : context(context) {} /* MPT_DEPRECATED */ void MPT_PRINTF_FUNC(2,3) operator () (const char *format, ...); // migrate to type-safe MPT_LOG /* MPT_DEPRECATED */ void operator () (const AnyStringLocale &text); // migrate to properly namespaced MPT_LOG /* MPT_DEPRECATED */ void operator () (LogLevel level, const mpt::ustring &text); // migrate to properly namespaced MPT_LOG }; #define Log MPT_MAYBE_CONSTANT_IF(mpt::log::GlobalLogLevel < MPT_LEGACY_LOGLEVEL) { } else MPT_MAYBE_CONSTANT_IF(!mpt::log::IsFacilityActive("")) { } else mpt::log::LegacyLogger(MPT_LOG_CURRENTCONTEXT()) #else // !NO_LOGGING #define MPT_LOG(level, facility, text) MPT_DO { } MPT_WHILE_0 struct LegacyLogger { inline void MPT_PRINTF_FUNC(2,3) operator () (const char * /*format*/ , ...) {} inline void operator () (const AnyStringLocale & /*text*/ ) {} inline void operator () (LogLevel /*level*/ , const mpt::ustring & /*text*/ ) {} }; #define Log MPT_CONSTANT_IF(true) {} else mpt::log::LegacyLogger() // completely compile out arguments to Log() so that they do not even get evaluated #endif // NO_LOGGING #if defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS namespace Trace { // This is not strictly thread safe in all corner cases because of missing barriers. // We do not care in order to not harm the fast path with additional barriers. // Enabled tracing incurs a runtime overhead with multiple threads as a global atomic variable // gets modified. // This cacheline bouncing does not matter at all // if there are not multiple thread adding trace points at high frequency (way greater than 1000Hz), // which, in OpenMPT, is only ever the case for just a single thread (the audio thread), if at all. extern bool volatile g_Enabled; static inline bool IsEnabled() { return g_Enabled; } MPT_NOINLINE void Trace(const mpt::log::Context & contexxt); enum ThreadKind { ThreadKindGUI, ThreadKindAudio, ThreadKindNotify, }; void Enable(std::size_t numEntries); void Disable(); void SetThreadId(mpt::log::Trace::ThreadKind kind, uint32 id); void Seal(); bool Dump(const mpt::PathString &filename); #define MPT_TRACE() MPT_DO { if(mpt::log::Trace::g_Enabled) { mpt::log::Trace::Trace(MPT_LOG_CURRENTCONTEXT()); } } MPT_WHILE_0 } // namespace Trace #else // !MODPLUG_TRACKER #define MPT_TRACE() MPT_DO { } MPT_WHILE_0 #endif // MODPLUG_TRACKER } // namespace log } // namespace mpt OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/stdafx.h0000644000372100037210000000562713115351121017213 00000000000000/* * StdAfx.h * -------- * Purpose: Include file for standard system include files, or project specific include files that are used frequently, but are changed infrequently. Also includes the global build settings from BuildSettings.h. * Notes : (currently none) * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once // has to be first #include "BuildSettings.h" #if defined(MODPLUG_TRACKER) #if MPT_OS_WINDOWS #if !defined(MPT_BUILD_WINESUPPORT) #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS // Do not include support for MFC controls in dialogs (reduces binary bloat; remove this #define if you want to use MFC controls) #include // MFC core and standard components #include // MFC extensions #include // MFC support for Windows Common Controls #include #include #include #endif // !MPT_BUILD_WINESUPPORT #include #include #include #include #endif // MPT_OS_WINDOWS #endif // MODPLUG_TRACKER #if MPT_COMPILER_MSVC #include #endif #if MPT_OS_WINDOWS #if MPT_COMPILER_MSVCCLANGC2 // windows.h references IUnknown in a template function without having it even forward-declared. // Clang does not like that. Forward-declaration fixes it. struct IUnknown; #endif #endif // this will be available everywhere #include "../common/typedefs.h" // // // // // // #include "../common/mptTypeTraits.h" // #include "../common/mptString.h" // // // // // #include "../common/mptStringFormat.h" #include "../common/mptPathString.h" #include "../common/Logging.h" #include "../common/misc_util.h" // // // // // // // // // // for std::abs #include #include #include #include #if defined(MPT_ENABLE_FILEIO_STDIO) // for FILE* definition (which cannot be forward-declared in a portable way) #include #include #endif #ifndef NO_VST // VST SDK includes these headers after messing with default compiler structure // packing. No problem in practice as VST SDK sets packing matching the default // packing and we are compiling with default packing and standard headers should // be careful about structure packing anyway, but it is very much unclean // nonetheless. Pre-include the affected headers here as a future-proof // safe-guard and let their own include guards handle the further including by // VST SDK. #include #include #include #include #endif //{{AFX_INSERT_LOCATION}} // Microsoft Developer Studio will insert additional declarations immediately before the previous line. libopenmpt-0.3.6+release.autotools/common/mptFileIO.h0000644000372100037210000003556213161656666017602 00000000000000/* * mptFileIO.h * ----------- * Purpose: A wrapper around std::fstream, fixing VS2008 charset conversion braindamage, and enforcing usage of mpt::PathString. * Notes : You should only ever use these wrappers instead of plain std::fstream classes. * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #if defined(MPT_ENABLE_FILEIO) #include "../common/mptString.h" #include "../common/mptPathString.h" #include "../common/mptIO.h" #include #include #include #include #include #endif // MPT_ENABLE_FILEIO OPENMPT_NAMESPACE_BEGIN #if defined(MPT_ENABLE_FILEIO) #if defined(MPT_ENABLE_FILEIO_STDIO) static inline FILE * mpt_fopen(const mpt::PathString &filename, const char *mode) { #if MPT_OS_WINDOWS return _wfopen(filename.AsNativePrefixed().c_str(), mode ? mpt::ToWide(mpt::CharsetASCII, mode).c_str() : L""); #else // !MPT_OS_WINDOWS return fopen(filename.AsNative().c_str(), mode); #endif // MPT_OS_WINDOWS } #endif // MPT_ENABLE_FILEIO_STDIO // Sets the NTFS compression attribute on the file or directory. // Requires read and write permissions for already opened files. // Returns true if the attribute has been set. // In almost all cases, the return value should be ignored because most filesystems other than NTFS do not support compression. #ifdef MODPLUG_TRACKER #if MPT_OS_WINDOWS bool SetFilesystemCompression(HANDLE hFile); bool SetFilesystemCompression(int fd); #if defined(MPT_ENABLE_FILEIO_STDIO) bool SetFilesystemCompression(FILE *file); #endif // MPT_ENABLE_FILEIO_STDIO bool SetFilesystemCompression(const mpt::PathString &filename); #endif // MPT_OS_WINDOWS #endif // MODPLUG_TRACKER namespace mpt { #if MPT_COMPILER_GCC #if MPT_OS_WINDOWS // GCC C++ library has no wchar_t overloads #define MPT_FSTREAM_DO_CONVERSIONS #define MPT_FSTREAM_DO_CONVERSIONS_ANSI #endif #endif #ifdef MPT_FSTREAM_DO_CONVERSIONS #define MPT_FSTREAM_OPEN(filename, mode) detail::fstream_open(*this, (filename), (mode)) #else #define MPT_FSTREAM_OPEN(filename, mode) Tbase::open((filename), (mode)) #endif namespace detail { template inline void fstream_open(Tbase & base, const mpt::PathString & filename, std::ios_base::openmode mode) { #if defined(MPT_FSTREAM_DO_CONVERSIONS_ANSI) base.open(mpt::ToCharset(mpt::CharsetLocale, filename.AsNative()).c_str(), mode); #else base.open(filename.AsNativePrefixed().c_str(), mode); #endif } #ifdef MPT_FSTREAM_DO_CONVERSIONS template inline void fstream_open(Tbase & base, const std::wstring & filename, std::ios_base::openmode mode) { detail::fstream_open(base, mpt::PathString::FromWide(filename), mode); } template inline void fstream_open(Tbase & base, const wchar_t * filename, std::ios_base::openmode mode) { detail::fstream_open(base, mpt::PathString::FromWide(filename ? std::wstring(filename) : std::wstring()), mode); } template inline void fstream_open(Tbase & base, const std::string & filename, std::ios_base::openmode mode) { detail::fstream_open(base, mpt::PathString::FromWide(mpt::ToWide(mpt::CharsetLocale, filename)), mode); } template inline void fstream_open(Tbase & base, const char * filename, std::ios_base::openmode mode) { detail::fstream_open(base, mpt::PathString::FromWide(mpt::ToWide(mpt::CharsetLocale, filename ? std::string(filename) : std::string())), mode); } #endif } // namespace detail class fstream : public std::fstream { private: typedef std::fstream Tbase; public: fstream() {} fstream(const mpt::PathString & filename, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) { detail::fstream_open(*this, filename, mode); } void open(const mpt::PathString & filename, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) { detail::fstream_open(*this, filename, mode); } MPT_DEPRECATED_PATH void open(const char * filename, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) { MPT_FSTREAM_OPEN(filename, mode); } MPT_DEPRECATED_PATH void open(const std::string & filename, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) { MPT_FSTREAM_OPEN(filename.c_str(), mode); } #if MPT_OS_WINDOWS MPT_DEPRECATED_PATH void open(const wchar_t * filename, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) { MPT_FSTREAM_OPEN(filename, mode); } MPT_DEPRECATED_PATH void open(const std::wstring & filename, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) { MPT_FSTREAM_OPEN(filename.c_str(), mode); } #endif }; class ifstream : public std::ifstream { private: typedef std::ifstream Tbase; public: ifstream() {} ifstream(const mpt::PathString & filename, std::ios_base::openmode mode = std::ios_base::in) { detail::fstream_open(*this, filename, mode); } void open(const mpt::PathString & filename, std::ios_base::openmode mode = std::ios_base::in) { detail::fstream_open(*this, filename, mode); } MPT_DEPRECATED_PATH void open(const char * filename, std::ios_base::openmode mode = std::ios_base::in) { MPT_FSTREAM_OPEN(filename, mode); } MPT_DEPRECATED_PATH void open(const std::string & filename, std::ios_base::openmode mode = std::ios_base::in) { MPT_FSTREAM_OPEN(filename.c_str(), mode); } #if MPT_OS_WINDOWS MPT_DEPRECATED_PATH void open(const wchar_t * filename, std::ios_base::openmode mode = std::ios_base::in) { MPT_FSTREAM_OPEN(filename, mode); } MPT_DEPRECATED_PATH void open(const std::wstring & filename, std::ios_base::openmode mode = std::ios_base::in) { MPT_FSTREAM_OPEN(filename.c_str(), mode); } #endif }; class ofstream : public std::ofstream { private: typedef std::ofstream Tbase; public: ofstream() {} ofstream(const mpt::PathString & filename, std::ios_base::openmode mode = std::ios_base::out) { detail::fstream_open(*this, filename, mode); } void open(const mpt::PathString & filename, std::ios_base::openmode mode = std::ios_base::out) { detail::fstream_open(*this, filename, mode); } MPT_DEPRECATED_PATH void open(const char * filename, std::ios_base::openmode mode = std::ios_base::out) { MPT_FSTREAM_OPEN(filename, mode); } MPT_DEPRECATED_PATH void open(const std::string & filename, std::ios_base::openmode mode = std::ios_base::out) { MPT_FSTREAM_OPEN(filename.c_str(), mode); } #if MPT_OS_WINDOWS MPT_DEPRECATED_PATH void open(const wchar_t * filename, std::ios_base::openmode mode = std::ios_base::out) { MPT_FSTREAM_OPEN(filename, mode); } MPT_DEPRECATED_PATH void open(const std::wstring & filename, std::ios_base::openmode mode = std::ios_base::out) { MPT_FSTREAM_OPEN(filename.c_str(), mode); } #endif }; #undef MPT_FSTREAM_OPEN // LazyFileRef is a simple reference to an on-disk file by the means of a // filename which allows easy assignment of the whole file contents to and from // byte buffers. class LazyFileRef { private: const mpt::PathString m_Filename; public: LazyFileRef(const mpt::PathString &filename) : m_Filename(filename) { return; } public: LazyFileRef & operator = (const std::vector &data); LazyFileRef & operator = (const std::vector &data); LazyFileRef & operator = (const std::string &data); operator std::vector () const; operator std::vector () const; operator std::string () const; }; #if defined(MPT_ENABLE_FILEIO_STDIO) // class FILE_ostream, FILE_output_streambuf and FILE_output_buffered_streambuf // provide a portable way of wrapping a std::ostream around an FILE* opened for output. // They offer similar functionality to the badly documented // MSVC std::fstream(FILE*) constructor or GCC libstdc++ __gnu_cxx::stdio_sync_filebuf class, // and, for other compilers, provide a race-free alternative to // closing the FILE* and opening it again as a std::ofstream. // // Only output functionality is implemented because we have no need for an input wrapper. // // During the whole lifetime of the iostream wrappers, the FILE* object is assumend to be // either // - NULL // or // - valid // - opened for writing in non-append mode // - opened in binary mode // - seekable // Some of these preconditions cannot be verified, // and even the others do not get verified. // Behaviour in case of any unmet preconditions is undefined. // // The buffered streambuf and the ostream use a buffer of 64KiB by default. // // For FILE_output_streambuf, coherency with the underlying FILE* is always guaranteed. // For FILE_ostream and FILE_output_buffered_streambuf, coherence is only // guaranteed when flush() or pubsync() get called. // The constructors and destructors take care to not violate coherency. // When mixing FILE* and iostream I/O during the lifetime of the iostream objects, // the user is responsible for providing coherency via the appropriate // flush and sync functions. // Behaviour in case of incoherent access is undefined. class FILE_output_streambuf : public std::streambuf { public: typedef std::streambuf::char_type char_type; typedef std::streambuf::traits_type traits_type; typedef traits_type::int_type int_type; typedef traits_type::pos_type pos_type; typedef traits_type::off_type off_type; protected: FILE *f; public: FILE_output_streambuf(FILE *f) : f(f) { return; } ~FILE_output_streambuf() { return; } protected: virtual int_type overflow(int_type ch) { if(!mpt::IO::IsValid(f)) { return traits_type::eof(); } if(traits_type::eq_int_type(ch, traits_type::eof())) { return traits_type::eof(); } char_type c = traits_type::to_char_type(ch); if(!mpt::IO::WriteRaw(f, &c, 1)) { return traits_type::eof(); } return ch; } virtual int sync() { if(!mpt::IO::IsValid(f)) { return -1; } if(!mpt::IO::Flush(f)) { return -1; } return 0; } virtual pos_type seekpos(pos_type pos, std::ios_base::openmode which) { if(!mpt::IO::IsValid(f)) { return pos_type(off_type(-1)); } return seekoff(pos, std::ios_base::beg, which); } virtual pos_type seekoff(off_type off, std::ios_base::seekdir dir, std::ios_base::openmode which) { if(!mpt::IO::IsValid(f)) { return pos_type(off_type(-1)); } if(which & std::ios_base::in) { return pos_type(off_type(-1)); } if(!(which & std::ios_base::out)) { return pos_type(off_type(-1)); } mpt::IO::Offset oldpos = mpt::IO::TellWrite(f); if(dir == std::ios_base::beg) { if(!mpt::IO::SeekAbsolute(f, off)) { mpt::IO::SeekAbsolute(f, oldpos); return pos_type(off_type(-1)); } } else if(dir == std::ios_base::cur) { if(!mpt::IO::SeekRelative(f, off)) { mpt::IO::SeekAbsolute(f, oldpos); return pos_type(off_type(-1)); } } else if(dir == std::ios_base::end) { if(!(mpt::IO::SeekEnd(f) && mpt::IO::SeekRelative(f, off))) { mpt::IO::SeekAbsolute(f, oldpos); return pos_type(off_type(-1)); } } else { return pos_type(off_type(-1)); } mpt::IO::Offset newpos = mpt::IO::TellWrite(f); if(!mpt::IO::OffsetFits(newpos)) { mpt::IO::SeekAbsolute(f, oldpos); return pos_type(off_type(-1)); } return pos_type(static_cast(newpos)); } }; // class FILE_output_streambuf class FILE_output_buffered_streambuf : public FILE_output_streambuf { public: typedef std::streambuf::char_type char_type; typedef std::streambuf::traits_type traits_type; typedef traits_type::int_type int_type; typedef traits_type::pos_type pos_type; typedef traits_type::off_type off_type; private: typedef FILE_output_streambuf Tparent; std::vector buf; public: FILE_output_buffered_streambuf(FILE *f, std::size_t bufSize = 64*1024) : FILE_output_streambuf(f) , buf((bufSize > 0) ? bufSize : 1) { setp(buf.data(), buf.data() + buf.size()); } ~FILE_output_buffered_streambuf() { if(!mpt::IO::IsValid(f)) { return; } WriteOut(); } private: bool IsDirty() const { return ((pptr() - pbase()) > 0); } bool WriteOut() { std::ptrdiff_t n = pptr() - pbase(); std::ptrdiff_t left = n; while(left > 0) { int backchunk = mpt::saturate_cast(-left); pbump(backchunk); left += backchunk; } return mpt::IO::WriteRaw(f, pbase(), n); } protected: virtual int_type overflow(int_type ch) { if(!mpt::IO::IsValid(f)) { return traits_type::eof(); } if(traits_type::eq_int_type(ch, traits_type::eof())) { return traits_type::eof(); } if(!WriteOut()) { return traits_type::eof(); } char_type c = traits_type::to_char_type(ch); *pptr() = c; pbump(1); return ch; } virtual int sync() { if(!mpt::IO::IsValid(f)) { return -1; } if(!WriteOut()) { return -1; } return Tparent::sync(); } virtual pos_type seekpos(pos_type pos, std::ios_base::openmode which) { if(!mpt::IO::IsValid(f)) { return pos_type(off_type(-1)); } if(!WriteOut()) { return pos_type(off_type(-1)); } return Tparent::seekpos(pos, which); } virtual pos_type seekoff(off_type off, std::ios_base::seekdir dir, std::ios_base::openmode which) { if(!mpt::IO::IsValid(f)) { return pos_type(off_type(-1)); } if(!WriteOut()) { return pos_type(off_type(-1)); } return Tparent::seekoff(off, dir, which); } }; // class FILE_output_buffered_streambuf class FILE_ostream : public std::ostream { private: FILE *f; FILE_output_buffered_streambuf buf; public: FILE_ostream(FILE *f, std::size_t bufSize = 64*1024) : std::ostream(&buf) , f(f) , buf(f, bufSize) { if(mpt::IO::IsValid(f)) mpt::IO::Flush(f); } ~FILE_ostream() { flush(); buf.pubsync(); if(mpt::IO::IsValid(f)) mpt::IO::Flush(f); } }; // class FILE_ostream #endif // MPT_ENABLE_FILEIO_STDIO } // namespace mpt #ifdef MODPLUG_TRACKER #if MPT_OS_WINDOWS class CMappedFile { protected: HANDLE m_hFile; HANDLE m_hFMap; void *m_pData; mpt::PathString m_FileName; public: CMappedFile() : m_hFile(nullptr), m_hFMap(nullptr), m_pData(nullptr) { } ~CMappedFile(); public: bool Open(const mpt::PathString &filename); bool IsOpen() const { return m_hFile != NULL && m_hFile != INVALID_HANDLE_VALUE; } const mpt::PathString * GetpFilename() const { return &m_FileName; } void Close(); size_t GetLength(); const mpt::byte *Lock(); }; #endif // MPT_OS_WINDOWS #endif // MODPLUG_TRACKER class InputFile { private: mpt::PathString m_Filename; #ifdef MPT_FILEREADER_STD_ISTREAM mpt::ifstream m_File; #else CMappedFile m_File; #endif public: InputFile(); InputFile(const mpt::PathString &filename); ~InputFile(); bool Open(const mpt::PathString &filename); bool IsValid() const; #if defined(MPT_FILEREADER_STD_ISTREAM) typedef std::pair ContentsRef; #else struct Data { const mpt::byte *data; std::size_t size; }; typedef std::pair ContentsRef; #endif InputFile::ContentsRef Get(); }; #endif // MPT_ENABLE_FILEIO OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/typedefs.h0000644000372100037210000003700213164740634017554 00000000000000/* * typedefs.h * ---------- * Purpose: Basic data type definitions and assorted compiler-related helpers. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once OPENMPT_NAMESPACE_BEGIN // Advanced inline attributes #if MPT_COMPILER_MSVC #define MPT_FORCEINLINE __forceinline #define MPT_NOINLINE __declspec(noinline) #elif MPT_COMPILER_GCC || MPT_COMPILER_CLANG || MPT_COMPILER_MSVCCLANGC2 #define MPT_FORCEINLINE __attribute__((always_inline)) inline #define MPT_NOINLINE __attribute__((noinline)) #else #define MPT_FORCEINLINE inline #define MPT_NOINLINE #endif // constexpr #define MPT_CONSTEXPR11_FUN constexpr MPT_FORCEINLINE #define MPT_CONSTEXPR11_VAR constexpr #if MPT_CXX_AT_LEAST(14) #define MPT_CONSTEXPR14_FUN constexpr MPT_FORCEINLINE #define MPT_CONSTEXPR14_VAR constexpr #else #define MPT_CONSTEXPR14_FUN MPT_FORCEINLINE #define MPT_CONSTEXPR14_VAR const #endif // C++17 std::size OPENMPT_NAMESPACE_END #include OPENMPT_NAMESPACE_BEGIN namespace mpt { template MPT_CONSTEXPR11_FUN auto size(const T & v) -> decltype(v.size()) { return v.size(); } template MPT_CONSTEXPR11_FUN std::size_t size(const T(&)[N]) noexcept { return N; } } // namespace mpt // MPT_ARRAY_COUNT macro computes the number of elements in a statically-allocated array. #if MPT_COMPILER_MSVC OPENMPT_NAMESPACE_END #include OPENMPT_NAMESPACE_BEGIN #define MPT_ARRAY_COUNT(x) _countof(x) #else #define MPT_ARRAY_COUNT(x) (sizeof((x))/sizeof((x)[0])) #endif // Use MPT_RESTRICT to indicate that a pointer is guaranteed to not be aliased. #if MPT_COMPILER_MSVC || MPT_COMPILER_GCC || MPT_COMPILER_CLANG || MPT_COMPILER_MSVCCLANGC2 #define MPT_RESTRICT __restrict #else #define MPT_RESTRICT #endif // Some functions might be deprecated although they are still in use. // Tag them with "MPT_DEPRECATED". #if MPT_COMPILER_MSVC #define MPT_DEPRECATED __declspec(deprecated) #elif MPT_COMPILER_GCC || MPT_COMPILER_CLANG || MPT_COMPILER_MSVCCLANGC2 #define MPT_DEPRECATED __attribute__((deprecated)) #else #define MPT_DEPRECATED #endif #if defined(MODPLUG_TRACKER) #define MPT_DEPRECATED_TRACKER MPT_DEPRECATED #define MPT_DEPRECATED_LIBOPENMPT #elif defined(LIBOPENMPT_BUILD) #define MPT_DEPRECATED_TRACKER #define MPT_DEPRECATED_LIBOPENMPT MPT_DEPRECATED #else #define MPT_DEPRECATED_TRACKER MPT_DEPRECATED #define MPT_DEPRECATED_LIBOPENMPT MPT_DEPRECATED #endif OPENMPT_NAMESPACE_END #include #include OPENMPT_NAMESPACE_BEGIN #if MPT_CXX_AT_LEAST(14) namespace mpt { using std::make_unique; } // namespace mpt #else namespace mpt { template std::unique_ptr make_unique(Args&&... args) { return std::unique_ptr(new T(std::forward(args)...)); } } // namespace mpt #endif #if MPT_COMPILER_MSVC #define MPT_CONSTANT_IF(x) \ __pragma(warning(push)) \ __pragma(warning(disable:4127)) \ if(x) \ __pragma(warning(pop)) \ /**/ #define MPT_MAYBE_CONSTANT_IF(x) \ __pragma(warning(push)) \ __pragma(warning(disable:4127)) \ if(x) \ __pragma(warning(pop)) \ /**/ #endif #if MPT_COMPILER_GCC #define MPT_MAYBE_CONSTANT_IF(x) \ _Pragma("GCC diagnostic push") \ _Pragma("GCC diagnostic ignored \"-Wtype-limits\"") \ if(x) \ _Pragma("GCC diagnostic pop") \ /**/ #endif #if MPT_COMPILER_CLANG || MPT_COMPILER_MSVCCLANGC2 #define MPT_MAYBE_CONSTANT_IF(x) \ _Pragma("clang diagnostic push") \ _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"") \ _Pragma("clang diagnostic ignored \"-Wtype-limits\"") \ _Pragma("clang diagnostic ignored \"-Wtautological-constant-out-of-range-compare\"") \ if(x) \ _Pragma("clang diagnostic pop") \ /**/ #endif #if !defined(MPT_CONSTANT_IF) // MPT_CONSTANT_IF disables compiler warnings for conditions that are either always true or always false for some reason (dependent on template arguments for example) #define MPT_CONSTANT_IF(x) if(x) #endif #if !defined(MPT_MAYBE_CONSTANT_IF) // MPT_MAYBE_CONSTANT_IF disables compiler warnings for conditions that may in some case be either always false or always true (this may turn out to be useful in ASSERTions in some cases). #define MPT_MAYBE_CONSTANT_IF(x) if(x) #endif #if MPT_COMPILER_MSVC // MSVC warns for the well-known and widespread "do { } while(0)" idiom with warning level 4 ("conditional expression is constant"). // It does not warn with "while(0,0)". However this again causes warnings with other compilers. // Solve it with a macro. #define MPT_DO do #define MPT_WHILE_0 while(0,0) #endif #ifndef MPT_DO #define MPT_DO do #endif #ifndef MPT_WHILE_0 #define MPT_WHILE_0 while(0) #endif #if MPT_COMPILER_MSVC && defined(UNREFERENCED_PARAMETER) #define MPT_UNREFERENCED_PARAMETER(x) UNREFERENCED_PARAMETER(x) #else #define MPT_UNREFERENCED_PARAMETER(x) (void)(x) #endif #define MPT_UNUSED_VARIABLE(x) MPT_UNREFERENCED_PARAMETER(x) // Exception handling helpers, because MFC requires explicit deletion of the exception object, // Thus, always call exactly one of MPT_EXCEPTION_RETHROW_OUT_OF_MEMORY() or MPT_EXCEPTION_DELETE_OUT_OF_MEMORY(e). #if defined(_MFC_VER) #define MPT_EXCEPTION_THROW_OUT_OF_MEMORY() MPT_DO { AfxThrowMemoryException(); } MPT_WHILE_0 #define MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e) catch ( CMemoryException * e ) #define MPT_EXCEPTION_RETHROW_OUT_OF_MEMORY() MPT_DO { throw; } MPT_WHILE_0 #define MPT_EXCEPTION_DELETE_OUT_OF_MEMORY(e) MPT_DO { if(e) { e->Delete(); e = nullptr; } } MPT_WHILE_0 #else // !_MFC_VER OPENMPT_NAMESPACE_END #include OPENMPT_NAMESPACE_BEGIN #define MPT_EXCEPTION_THROW_OUT_OF_MEMORY() MPT_DO { throw std::bad_alloc(); } MPT_WHILE_0 #define MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e) catch ( const std::bad_alloc & e ) #define MPT_EXCEPTION_RETHROW_OUT_OF_MEMORY() MPT_DO { throw; } MPT_WHILE_0 #define MPT_EXCEPTION_DELETE_OUT_OF_MEMORY(e) MPT_DO { MPT_UNUSED_VARIABLE(e); } MPT_WHILE_0 #endif // _MFC_VER // Static code checkers might need to get the knowledge of our assertions transferred to them. #define MPT_CHECKER_ASSUME_ASSERTIONS 1 //#define MPT_CHECKER_ASSUME_ASSERTIONS 0 #ifdef MPT_BUILD_ANALYZED #if MPT_COMPILER_MSVC #if MPT_CHECKER_ASSUME_ASSERTIONS #define MPT_CHECKER_ASSUME(x) __analysis_assume(!!(x)) #endif #elif MPT_COMPILER_CLANG || MPT_COMPILER_MSVCCLANGC2 #if MPT_CHECKER_ASSUME_ASSERTIONS #ifdef NDEBUG #error "Builds for static analyzers depend on std::assert being enabled, but the current build has #define NDEBUG. This makes no sense." #endif OPENMPT_NAMESPACE_END #include OPENMPT_NAMESPACE_BEGIN #define MPT_CHECKER_ASSUME(x) assert(!!(x)) #endif #endif // MPT_COMPILER #endif // MPT_BUILD_ANALYZED #ifndef MPT_CHECKER_ASSUME #define MPT_CHECKER_ASSUME(x) MPT_DO { } MPT_WHILE_0 #endif #if defined(_MFC_VER) #if !defined(ASSERT) #error "MFC is expected to #define ASSERT" #endif // !defined(ASERRT) #define MPT_FRAMEWORK_ASSERT_IS_DEFINED #if defined(_DEBUG) #define MPT_FRAMEWORK_ASSERT_IS_ACTIVE 1 #else // !_DEBUG #define MPT_FRAMEWORK_ASSERT_IS_ACTIVE 0 #endif // _DEBUG // let MFC handle our asserts #define MPT_ASSERT_USE_FRAMEWORK 1 #else // !_MFC_VER #if defined(ASSERT) #define MPT_FRAMEWORK_ASSERT_IS_DEFINED #if defined(_DEBUG) #define MPT_FRAMEWORK_ASSERT_IS_ACTIVE 1 #else // !_DEBUG #define MPT_FRAMEWORK_ASSERT_IS_ACTIVE 0 #endif // _DEBUG #endif // !defined(ASERRT) // handle assert in our own way without relying on some platform-/framework-specific assert implementation #define MPT_ASSERT_USE_FRAMEWORK 0 #endif // _MFC_VER #if defined(MPT_FRAMEWORK_ASSERT_IS_DEFINED) && (MPT_ASSERT_USE_FRAMEWORK == 1) #define MPT_ASSERT_NOTREACHED() ASSERT(0) #define MPT_ASSERT(expr) ASSERT((expr)) #define MPT_ASSERT_MSG(expr, msg) ASSERT((expr) && (msg)) #if (MPT_FRAMEWORK_ASSERT_IS_ACTIVE == 1) #define MPT_ASSERT_ALWAYS(expr) ASSERT((expr)) #define MPT_ASSERT_ALWAYS_MSG(expr, msg) ASSERT((expr) && (msg)) #else #define MPT_ASSERT_ALWAYS(expr) MPT_DO { if(!(expr)) { AssertHandler(__FILE__, __LINE__, __FUNCTION__, #expr); } MPT_CHECKER_ASSUME(expr); } MPT_WHILE_0 #define MPT_ASSERT_ALWAYS_MSG(expr, msg) MPT_DO { if(!(expr)) { AssertHandler(__FILE__, __LINE__, __FUNCTION__, #expr, msg); } MPT_CHECKER_ASSUME(expr); } MPT_WHILE_0 #ifndef MPT_ASSERT_HANDLER_NEEDED #define MPT_ASSERT_HANDLER_NEEDED #endif #endif #elif defined(NO_ASSERTS) #define MPT_ASSERT_NOTREACHED() MPT_CHECKER_ASSUME(0) #define MPT_ASSERT(expr) MPT_CHECKER_ASSUME(expr) #define MPT_ASSERT_MSG(expr, msg) MPT_CHECKER_ASSUME(expr) #define MPT_ASSERT_ALWAYS(expr) MPT_DO { if(!(expr)) { AssertHandler(__FILE__, __LINE__, __FUNCTION__, #expr); } MPT_CHECKER_ASSUME(expr); } MPT_WHILE_0 #define MPT_ASSERT_ALWAYS_MSG(expr, msg) MPT_DO { if(!(expr)) { AssertHandler(__FILE__, __LINE__, __FUNCTION__, #expr, msg); } MPT_CHECKER_ASSUME(expr); } MPT_WHILE_0 #ifndef MPT_ASSERT_HANDLER_NEEDED #define MPT_ASSERT_HANDLER_NEEDED #endif #else // !NO_ASSERTS #define MPT_ASSERT_NOTREACHED() MPT_DO { MPT_CONSTANT_IF(!(0)) { AssertHandler(__FILE__, __LINE__, __FUNCTION__, "0"); } MPT_CHECKER_ASSUME(0); } MPT_WHILE_0 #define MPT_ASSERT(expr) MPT_DO { if(!(expr)) { AssertHandler(__FILE__, __LINE__, __FUNCTION__, #expr); } MPT_CHECKER_ASSUME(expr); } MPT_WHILE_0 #define MPT_ASSERT_MSG(expr, msg) MPT_DO { if(!(expr)) { AssertHandler(__FILE__, __LINE__, __FUNCTION__, #expr, msg); } MPT_CHECKER_ASSUME(expr); } MPT_WHILE_0 #define MPT_ASSERT_ALWAYS(expr) MPT_DO { if(!(expr)) { AssertHandler(__FILE__, __LINE__, __FUNCTION__, #expr); } MPT_CHECKER_ASSUME(expr); } MPT_WHILE_0 #define MPT_ASSERT_ALWAYS_MSG(expr, msg) MPT_DO { if(!(expr)) { AssertHandler(__FILE__, __LINE__, __FUNCTION__, #expr, msg); } MPT_CHECKER_ASSUME(expr); } MPT_WHILE_0 #ifndef MPT_ASSERT_HANDLER_NEEDED #define MPT_ASSERT_HANDLER_NEEDED #endif #endif // NO_ASSERTS #if defined(MPT_ASSERT_HANDLER_NEEDED) // custom assert handler needed MPT_NOINLINE void AssertHandler(const char *file, int line, const char *function, const char *expr, const char *msg=nullptr); #endif // MPT_ASSERT_HANDLER_NEEDED // Compile time assert. #define MPT_STATIC_ASSERT(expr) static_assert((expr), "compile time assertion failed: " #expr) // Macro for marking intentional fall-throughs in switch statements - can be used for static analysis if supported. #if (MPT_CXX >= 17) #define MPT_FALLTHROUGH [[fallthrough]] #elif MPT_COMPILER_MSVC #define MPT_FALLTHROUGH __fallthrough #elif MPT_COMPILER_CLANG || MPT_COMPILER_MSVCCLANGC2 #define MPT_FALLTHROUGH [[clang::fallthrough]] #elif MPT_COMPILER_GCC && MPT_GCC_AT_LEAST(7,1,0) #define MPT_FALLTHROUGH __attribute__((fallthrough)) #elif defined(__has_cpp_attribute) #if __has_cpp_attribute(fallthrough) #define MPT_FALLTHROUGH [[fallthrough]] #else #define MPT_FALLTHROUGH MPT_DO { } MPT_WHILE_0 #endif #else #define MPT_FALLTHROUGH MPT_DO { } MPT_WHILE_0 #endif OPENMPT_NAMESPACE_END #include #include #include OPENMPT_NAMESPACE_BEGIN typedef std::int8_t int8; typedef std::int16_t int16; typedef std::int32_t int32; typedef std::int64_t int64; typedef std::uint8_t uint8; typedef std::uint16_t uint16; typedef std::uint32_t uint32; typedef std::uint64_t uint64; const int8 int8_min = INT8_MIN; const int16 int16_min = INT16_MIN; const int32 int32_min = INT32_MIN; const int64 int64_min = INT64_MIN; const int8 int8_max = INT8_MAX; const int16 int16_max = INT16_MAX; const int32 int32_max = INT32_MAX; const int64 int64_max = INT64_MAX; const uint8 uint8_max = UINT8_MAX; const uint16 uint16_max = UINT16_MAX; const uint32 uint32_max = UINT32_MAX; const uint64 uint64_max = UINT64_MAX; // 24-bit integer wrapper (for 24-bit PCM) struct int24 { uint8 bytes[3]; int24() { bytes[0] = bytes[1] = bytes[2] = 0; } #if MPT_PLATFORM_ENDIAN_KNOWN explicit int24(int other) { #ifdef MPT_PLATFORM_BIG_ENDIAN bytes[0] = (static_cast(other)>>16)&0xff; bytes[1] = (static_cast(other)>> 8)&0xff; bytes[2] = (static_cast(other)>> 0)&0xff; #else bytes[0] = (static_cast(other)>> 0)&0xff; bytes[1] = (static_cast(other)>> 8)&0xff; bytes[2] = (static_cast(other)>>16)&0xff; #endif } operator int() const { #ifdef MPT_PLATFORM_BIG_ENDIAN return (static_cast(bytes[0]) * 65536) + (bytes[1] * 256) + bytes[2]; #else return (static_cast(bytes[2]) * 65536) + (bytes[1] * 256) + bytes[0]; #endif } #else explicit int24(int other); operator int() const; #endif }; MPT_STATIC_ASSERT(sizeof(int24) == 3); #define int24_min (0-0x00800000) #define int24_max (0+0x007fffff) typedef float float32; MPT_STATIC_ASSERT(sizeof(float32) == 4); typedef double float64; MPT_STATIC_ASSERT(sizeof(float64) == 8); MPT_STATIC_ASSERT(sizeof(std::uintptr_t) == sizeof(void*)); namespace mpt { MPT_STATIC_ASSERT(CHAR_BIT == 8); MPT_STATIC_ASSERT(sizeof(char) == 1); typedef unsigned char byte; MPT_STATIC_ASSERT(sizeof(mpt::byte) == 1); } // namespace mpt #if MPT_COMPILER_MSVC #if defined(_M_X64) #define MPT_ARCH_BITS 64 #define MPT_ARCH_BITS_32 0 #define MPT_ARCH_BITS_64 1 #elif defined(_M_IX86) #define MPT_ARCH_BITS 32 #define MPT_ARCH_BITS_32 1 #define MPT_ARCH_BITS_64 0 #endif #elif MPT_COMPILER_GCC || MPT_COMPILER_CLANG || MPT_COMPILER_MSVCCLANGC2 #if defined(__SIZEOF_POINTER__) #if (__SIZEOF_POINTER__ == 8) #define MPT_ARCH_BITS 64 #define MPT_ARCH_BITS_32 0 #define MPT_ARCH_BITS_64 1 #elif (__SIZEOF_POINTER__ == 4) #define MPT_ARCH_BITS 32 #define MPT_ARCH_BITS_32 1 #define MPT_ARCH_BITS_64 0 #endif #endif #endif // MPT_COMPILER // fallback #if !defined(MPT_ARCH_BITS) #include #include MPT_STATIC_ASSERT(sizeof(std::uintptr_t) == sizeof(void*)); #if defined(UINTPTR_MAX) #if (UINTPTR_MAX == 0xffffffffffffffffull) #define MPT_ARCH_BITS 64 #define MPT_ARCH_BITS_32 0 #define MPT_ARCH_BITS_64 1 #elif (UINTPTR_MAX == 0xffffffffu) #define MPT_ARCH_BITS 32 #define MPT_ARCH_BITS_32 1 #define MPT_ARCH_BITS_64 0 #endif #endif // UINTPTR_MAX #endif // MPT_ARCH_BITS #if MPT_COMPILER_GCC || MPT_COMPILER_CLANG || MPT_COMPILER_MSVCCLANGC2 #define MPT_PRINTF_FUNC(formatstringindex,varargsindex) __attribute__((format(printf, formatstringindex, varargsindex))) #else #define MPT_PRINTF_FUNC(formatstringindex,varargsindex) #endif #if MPT_COMPILER_MSVC // warning LNK4221: no public symbols found; archive member will be inaccessible // There is no way to selectively disable linker warnings. // #pragma warning does not apply and a command line option does not exist. // Some options: // 1. Macro which generates a variable with a unique name for each file (which means we have to pass the filename to the macro) // 2. unnamed namespace containing any symbol (does not work for c++11 compilers because they actually have internal linkage now) // 3. An unused trivial inline function. // Option 3 does not actually solve the problem though, which leaves us with option 1. // In any case, for optimized builds, the linker will just remove the useless symbol. #define MPT_MSVC_WORKAROUND_LNK4221_CONCAT_DETAIL(x,y) x##y #define MPT_MSVC_WORKAROUND_LNK4221_CONCAT(x,y) MPT_MSVC_WORKAROUND_LNK4221_CONCAT_DETAIL(x,y) #define MPT_MSVC_WORKAROUND_LNK4221(x) int MPT_MSVC_WORKAROUND_LNK4221_CONCAT(mpt_msvc_workaround_lnk4221_,x) = 0; #endif #ifndef MPT_MSVC_WORKAROUND_LNK4221 #define MPT_MSVC_WORKAROUND_LNK4221(x) #endif // legacy #define CountOf(x) MPT_ARRAY_COUNT(x) #define STATIC_ASSERT(x) MPT_STATIC_ASSERT(x) OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/misc_util.cpp0000644000372100037210000000526513161656666020272 00000000000000/* * misc_util.cpp * ------------- * Purpose: Various useful utility functions. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "misc_util.h" OPENMPT_NAMESPACE_BEGIN #ifdef MODPLUG_TRACKER namespace Util { #if MPT_OS_WINDOWS #endif // MPT_OS_WINDOWS } // namespace Util #endif // MODPLUG_TRACKER namespace Util { static const MPT_UCHAR_TYPE EncodeNibble[16] = { MPT_UCHAR('0'), MPT_UCHAR('1'), MPT_UCHAR('2'), MPT_UCHAR('3'), MPT_UCHAR('4'), MPT_UCHAR('5'), MPT_UCHAR('6'), MPT_UCHAR('7'), MPT_UCHAR('8'), MPT_UCHAR('9'), MPT_UCHAR('A'), MPT_UCHAR('B'), MPT_UCHAR('C'), MPT_UCHAR('D'), MPT_UCHAR('E'), MPT_UCHAR('F') }; static inline bool DecodeByte(uint8 &byte, MPT_UCHAR_TYPE c1, MPT_UCHAR_TYPE c2) { byte = 0; if(MPT_UCHAR('0') <= c1 && c1 <= MPT_UCHAR('9')) { byte += static_cast((c1 - MPT_UCHAR('0')) << 4); } else if(MPT_UCHAR('A') <= c1 && c1 <= MPT_UCHAR('F')) { byte += static_cast((c1 - MPT_UCHAR('A') + 10) << 4); } else if(MPT_UCHAR('a') <= c1 && c1 <= MPT_UCHAR('f')) { byte += static_cast((c1 - MPT_UCHAR('a') + 10) << 4); } else { return false; } if(MPT_UCHAR('0') <= c2 && c2 <= MPT_UCHAR('9')) { byte += static_cast(c2 - MPT_UCHAR('0')); } else if(MPT_UCHAR('A') <= c2 && c2 <= MPT_UCHAR('F')) { byte += static_cast(c2 - MPT_UCHAR('A') + 10); } else if(MPT_UCHAR('a') <= c2 && c2 <= MPT_UCHAR('f')) { byte += static_cast(c2 - MPT_UCHAR('a') + 10); } else { return false; } return true; } mpt::ustring BinToHex(mpt::const_byte_span src) { mpt::ustring result; result.reserve(src.size() * 2); for(uint8 byte : src) { result.push_back(EncodeNibble[(byte & 0xf0) >> 4]); result.push_back(EncodeNibble[byte & 0x0f]); } return result; } std::vector HexToBin(const mpt::ustring &src) { std::vector result; result.reserve(src.size() / 2); for(std::size_t i = 0; (i + 1) < src.size(); i += 2) { uint8 byte = 0; if(!DecodeByte(byte, src[i], src[i + 1])) { return result; } result.push_back(byte); } return result; } } // namespace Util #if defined(MODPLUG_TRACKER) || (defined(LIBOPENMPT_BUILD) && defined(LIBOPENMPT_BUILD_TEST)) namespace mpt { std::string getenv(const std::string &env_var, const std::string &def) { #if MPT_OS_WINDOWS && MPT_OS_WINDOWS_WINRT MPT_UNREFERENCED_PARAMETER(env_var); return def; #else const char *val = std::getenv(env_var.c_str()); if(!val) { return def; } return val; #endif } } // namespace mpt #endif // MODPLUG_TRACKER || (LIBOPENMPT_BUILD && LIBOPENMPT_BUILD_TEST) OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/BuildSettings.h0000644000372100037210000004331113214777522020513 00000000000000/* * BuildSettings.h * --------------- * Purpose: Global, user settable compile time flags (and some global system header configuration) * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "CompilerDetect.h" // set windows version early so that we can deduce dependencies from SDK version #if MPT_OS_WINDOWS #if defined(MPT_BUILD_MSVC) #if defined(MPT_BUILD_TARGET_XP) #if defined(_M_X64) #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0502 // _WIN32_WINNT_WS03 #endif #else // !_M_X64 #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0501 // _WIN32_WINNT_WINXP #endif #endif // _M_X64 #else // MPT_BUILD_TARGET #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0601 // _WIN32_WINNT_WIN7 #endif #endif // MPT_BUILD_TARGET #else // !MPT_BUILD_MSVC #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0501 // _WIN32_WINNT_WINXP #endif #endif // MPT_BUILD_MSVC #ifndef WINVER #define WINVER _WIN32_WINNT #endif #endif // MPT_OS_WINDOWS #if defined(MODPLUG_TRACKER) && defined(LIBOPENMPT_BUILD) #error "either MODPLUG_TRACKER or LIBOPENMPT_BUILD has to be defined" #elif defined(MODPLUG_TRACKER) // nothing #elif defined(LIBOPENMPT_BUILD) // nothing #else #error "either MODPLUG_TRACKER or LIBOPENMPT_BUILD has to be defined" #endif // MODPLUG_TRACKER || LIBOPENMPT_BUILD // wrapper for autoconf macros #if defined(HAVE_CONFIG_H) #include "config.h" // Fixup dependencies which are currently not used in libopenmpt itself #ifdef MPT_WITH_FLAC #undef MPT_WITH_FLAC #endif #endif // HAVE_CONFIG_H // Dependencies from the MSVC build system #if defined(MPT_BUILD_MSVC) // This section defines which dependencies are available when building with // MSVC. Other build systems provide MPT_WITH_* macros via command-line or other // means. // OpenMPT and libopenmpt should compile and run successfully (albeit with // reduced functionality) with any or all dependencies missing/disabled. // The defaults match the bundled third-party libraries with the addition of // ASIO and VST SDKs. #if defined(MODPLUG_TRACKER) // OpenMPT-only dependencies #define MPT_WITH_ASIO #define MPT_WITH_DSOUND #define MPT_WITH_LHASA #define MPT_WITH_MINIZIP #define MPT_WITH_OPUS #define MPT_WITH_OPUSENC #define MPT_WITH_OPUSFILE #define MPT_WITH_PICOJSON #define MPT_WITH_PORTAUDIO //#define MPT_WITH_PULSEAUDIO //#define MPT_WITH_PULSEAUDIOSIMPLE #define MPT_WITH_SMBPITCHSHIFT #define MPT_WITH_UNRAR #define MPT_WITH_VORBISENC // OpenMPT and libopenmpt dependencies (not for openmp123, player plugins or examples) //#define MPT_WITH_DL #define MPT_WITH_FLAC //#define MPT_WITH_ICONV //#define MPT_WITH_LTDL #if MPT_OS_WINDOWS #if (_WIN32_WINNT >= 0x0601) #define MPT_WITH_MEDIAFOUNDATION #endif #endif //#define MPT_WITH_MINIMP3 //#define MPT_WITH_MINIZ #define MPT_WITH_MPG123 #define MPT_WITH_OGG //#define MPT_WITH_STBVORBIS #define MPT_WITH_VORBIS #define MPT_WITH_VORBISFILE #define MPT_WITH_ZLIB #endif // MODPLUG_TRACKER #if defined(LIBOPENMPT_BUILD) // OpenMPT and libopenmpt dependencies (not for openmp123, player plugins or examples) #if defined(LIBOPENMPT_BUILD_FULL) && defined(LIBOPENMPT_BUILD_SMALL) #error "only one of LIBOPENMPT_BUILD_FULL or LIBOPENMPT_BUILD_SMALL can be defined" #endif // LIBOPENMPT_BUILD_FULL && LIBOPENMPT_BUILD_SMALL #if defined(LIBOPENMPT_BUILD_FULL) //#define MPT_WITH_DL //#define MPT_WITH_FLAC //#define MPT_WITH_ICONV //#define MPT_WITH_LTDL #if MPT_OS_WINDOWS && !MPT_OS_WINDOWS_WINRT #if (_WIN32_WINNT >= 0x0601) #define MPT_WITH_MEDIAFOUNDATION #endif #endif //#define MPT_WITH_MINIMP3 //#define MPT_WITH_MINIZ #define MPT_WITH_MPG123 #define MPT_WITH_OGG //#define MPT_WITH_STBVORBIS #define MPT_WITH_VORBIS #define MPT_WITH_VORBISFILE #define MPT_WITH_ZLIB #elif defined(LIBOPENMPT_BUILD_SMALL) //#define MPT_WITH_DL //#define MPT_WITH_FLAC //#define MPT_WITH_ICONV //#define MPT_WITH_LTDL //#define MPT_WITH_MEDIAFOUNDATION #define MPT_WITH_MINIMP3 #define MPT_WITH_MINIZ //#define MPT_WITH_MPG123 //#define MPT_WITH_OGG #define MPT_WITH_STBVORBIS //#define MPT_WITH_VORBIS //#define MPT_WITH_VORBISFILE //#define MPT_WITH_ZLIB #else // !LIBOPENMPT_BUILD_SMALL //#define MPT_WITH_DL //#define MPT_WITH_FLAC //#define MPT_WITH_ICONV //#define MPT_WITH_LTDL //#define MPT_WITH_MEDIAFOUNDATION //#define MPT_WITH_MINIMP3 //#define MPT_WITH_MINIZ #define MPT_WITH_MPG123 #define MPT_WITH_OGG //#define MPT_WITH_STBVORBIS #define MPT_WITH_VORBIS #define MPT_WITH_VORBISFILE #define MPT_WITH_ZLIB #endif // LIBOPENMPT_BUILD_SMALL #endif // LIBOPENMPT_BUILD #endif // MPT_BUILD_MSVC #if defined(MODPLUG_TRACKER) // Enable built-in test suite. #ifdef _DEBUG #define ENABLE_TESTS #endif // Disable any file saving functionality (not really useful except for the player library) //#define MODPLUG_NO_FILESAVE // Disable any debug logging //#define NO_LOGGING #if !defined(_DEBUG) && !defined(MPT_BUILD_WINESUPPORT) #define MPT_LOG_GLOBAL_LEVEL_STATIC #define MPT_LOG_GLOBAL_LEVEL 0 #endif // Disable all runtime asserts #if !defined(_DEBUG) && !defined(MPT_BUILD_WINESUPPORT) #define NO_ASSERTS #endif // Enable std::istream support in class FileReader (this is generally not needed for the tracker, local files can easily be mmapped as they have been before introducing std::istream support) //#define MPT_FILEREADER_STD_ISTREAM // Enable callback stream wrapper for FileReader (required by libopenmpt C API). //#define MPT_FILEREADER_CALLBACK_STREAM // Support for externally linked samples e.g. in MPTM files #define MPT_EXTERNAL_SAMPLES // Support mpt::ChartsetLocale #define MPT_ENABLE_CHARSET_LOCALE // Use inline assembly #define ENABLE_ASM // Disable unarchiving support //#define NO_ARCHIVE_SUPPORT // Disable the built-in reverb effect //#define NO_REVERB // Disable built-in miscellaneous DSP effects (surround, mega bass, noise reduction) //#define NO_DSP // Disable the built-in equalizer. //#define NO_EQ // Disable the built-in automatic gain control //#define NO_AGC // Define to build without VST plugin support; makes build possible without VST SDK. //#define NO_VST // Define to build without DMO plugin support //#define NO_DMO // (HACK) Define to build without any plugin support //#define NO_PLUGINS // Do not build libopenmpt C api #define NO_LIBOPENMPT_C // Do not build libopenmpt C++ api #define NO_LIBOPENMPT_CXX #endif // MODPLUG_TRACKER #if defined(LIBOPENMPT_BUILD) #if (defined(_DEBUG) || defined(DEBUG)) && !defined(MPT_BUILD_DEBUG) #define MPT_BUILD_DEBUG #endif #if defined(LIBOPENMPT_BUILD_TEST) #define ENABLE_TESTS #else #define MODPLUG_NO_FILESAVE #endif #if defined(MPT_BUILD_ANALZYED) || defined(MPT_BUILD_CHECKED) || defined(ENABLE_TESTS) // enable asserts #else #define NO_ASSERTS #endif //#define NO_LOGGING #define MPT_FILEREADER_STD_ISTREAM #define MPT_FILEREADER_CALLBACK_STREAM //#define MPT_EXTERNAL_SAMPLES #if defined(ENABLE_TESTS) || defined(MPT_BUILD_HACK_ARCHIVE_SUPPORT) #define MPT_ENABLE_CHARSET_LOCALE #else //#define MPT_ENABLE_CHARSET_LOCALE #endif // Do not use inline asm in library builds. There is just about no codepath which would use it anyway. //#define ENABLE_ASM #if defined(MPT_BUILD_HACK_ARCHIVE_SUPPORT) //#define NO_ARCHIVE_SUPPORT #else #define NO_ARCHIVE_SUPPORT #endif //#define NO_REVERB #define NO_DSP #define NO_EQ #define NO_AGC #define NO_VST //#if !MPT_OS_WINDOWS || MPT_OS_WINDOWS_WINRT || !MPT_COMPILER_MSVC || !defined(LIBOPENMPT_BUILD_FULL) #define NO_DMO //#endif //#define NO_PLUGINS //#define NO_LIBOPENMPT_C //#define NO_LIBOPENMPT_CXX #endif // LIBOPENMPT_BUILD #if MPT_OS_WINDOWS #define MPT_CHARSET_WIN32 #elif MPT_OS_LINUX #define MPT_CHARSET_ICONV #elif MPT_OS_ANDROID #define MPT_CHARSET_INTERNAL #elif MPT_OS_EMSCRIPTEN #define MPT_CHARSET_INTERNAL #ifndef MPT_LOCALE_ASSUME_CHARSET #define MPT_LOCALE_ASSUME_CHARSET CharsetUTF8 #endif #elif MPT_OS_MACOSX_OR_IOS #if defined(MPT_WITH_ICONV) #define MPT_CHARSET_ICONV #ifndef MPT_ICONV_NO_WCHAR #define MPT_ICONV_NO_WCHAR #endif #else #define MPT_CHARSET_INTERNAL #endif //#ifndef MPT_LOCALE_ASSUME_CHARSET //#define MPT_LOCALE_ASSUME_CHARSET CharsetUTF8 //#endif #elif defined(MPT_WITH_ICONV) #define MPT_CHARSET_ICONV #endif #if MPT_COMPILER_MSVC // Use wide strings for MSVC because this is the native encoding on // microsoft platforms. #define MPT_USTRING_MODE_WIDE 1 #define MPT_USTRING_MODE_UTF8 0 #else // !MPT_COMPILER_MSVC #define MPT_USTRING_MODE_WIDE 0 #define MPT_USTRING_MODE_UTF8 1 #endif // MPT_COMPILER_MSVC #if MPT_USTRING_MODE_UTF8 // MPT_USTRING_MODE_UTF8 mpt::ustring is implemented via mpt::u8string #define MPT_ENABLE_U8STRING 1 #else #define MPT_ENABLE_U8STRING 0 #endif #if defined(MODPLUG_TRACKER) || MPT_USTRING_MODE_WIDE // mpt::ToWString, mpt::wfmt, ConvertStrTo // Required by the tracker to ease interfacing with WinAPI. // Required by MPT_USTRING_MODE_WIDE to ease type tunneling in mpt::format. #define MPT_WSTRING_FORMAT 1 #else #define MPT_WSTRING_FORMAT 0 #endif #if MPT_OS_WINDOWS || MPT_USTRING_MODE_WIDE || MPT_WSTRING_FORMAT // mpt::ToWide // Required on Windows by mpt::PathString. // Required by MPT_USTRING_MODE_WIDE as they share the conversion functions. // Required by MPT_WSTRING_FORMAT because of std::string<->std::wstring conversion in mpt::ToString and mpt::ToWString. #define MPT_WSTRING_CONVERT 1 #else #define MPT_WSTRING_CONVERT 0 #endif // fixing stuff up #if defined(MPT_BUILD_TARGET_XP) // Also support Wine 1.6 in addition to Windows XP #ifndef MPT_QUIRK_NO_CPP_THREAD #define MPT_QUIRK_NO_CPP_THREAD #endif #endif #if defined(MPT_BUILD_ANALYZED) || defined(MPT_BUILD_CHECKED) #ifdef NO_ASSERTS #undef NO_ASSERTS // static or dynamic analyzers want assertions on #endif #endif #if defined(MPT_BUILD_FUZZER) #ifndef MPT_FUZZ_TRACKER #define MPT_FUZZ_TRACKER #endif #endif #if !MPT_COMPILER_MSVC && defined(ENABLE_ASM) #undef ENABLE_ASM // inline assembly requires MSVC compiler #endif #if defined(ENABLE_ASM) #if MPT_COMPILER_MSVC && defined(_M_IX86) // Generate general x86 inline assembly / intrinsics. #define ENABLE_X86 // Generate inline assembly using MMX instructions (only used when the CPU supports it). #define ENABLE_MMX // Generate inline assembly using SSE instructions (only used when the CPU supports it). #define ENABLE_SSE // Generate inline assembly using SSE2 instructions (only used when the CPU supports it). #define ENABLE_SSE2 // Generate inline assembly using SSE3 instructions (only used when the CPU supports it). #define ENABLE_SSE3 // Generate inline assembly using SSE4 instructions (only used when the CPU supports it). #define ENABLE_SSE4 // Generate inline assembly using AMD specific instruction set extensions (only used when the CPU supports it). #define ENABLE_X86_AMD #elif MPT_COMPILER_MSVC && defined(_M_X64) // Generate general x64 inline assembly / intrinsics. #define ENABLE_X64 // Generate inline assembly using SSE2 instructions (only used when the CPU supports it). #define ENABLE_SSE2 // Generate inline assembly using SSE3 instructions (only used when the CPU supports it). #define ENABLE_SSE3 // Generate inline assembly using SSE4 instructions (only used when the CPU supports it). #define ENABLE_SSE4 #endif // arch #endif // ENABLE_ASM #if defined(MPT_WITH_MPG123) && defined(MPT_BUILD_MSVC) && defined(MPT_BUILD_MSVC_STATIC) && !MPT_OS_WINDOWS_WINRT #define MPT_ENABLE_MPG123_DELAYLOAD #endif #if defined(ENABLE_TESTS) && defined(MODPLUG_NO_FILESAVE) #undef MODPLUG_NO_FILESAVE // tests recommend file saving #endif #if defined(MPT_WITH_ZLIB) && defined(MPT_WITH_MINIZ) // Only one deflate implementation should be used. Prefer zlib. #undef MPT_WITH_MINIZ #endif #if !MPT_OS_WINDOWS && defined(MPT_WITH_MEDIAFOUNDATION) #undef MPT_WITH_MEDIAFOUNDATION // MediaFoundation requires Windows #endif #if defined(MPT_WITH_MEDIAFOUNDATION) && !defined(MPT_ENABLE_TEMPFILE) #define MPT_ENABLE_TEMPFILE #endif #if defined(MODPLUG_TRACKER) && !defined(MPT_ENABLE_TEMPFILE) #define MPT_ENABLE_TEMPFILE #endif #if !defined(MPT_CHARSET_WIN32) && !defined(MPT_CHARSET_ICONV) && !defined(MPT_CHARSET_CODECVTUTF8) && !defined(MPT_CHARSET_INTERNAL) #define MPT_CHARSET_INTERNAL #endif #if defined(MODPLUG_TRACKER) && !defined(MPT_ENABLE_DYNBIND) #define MPT_ENABLE_DYNBIND // Tracker requires dynamic library loading for export codecs #endif #if defined(MPT_ENABLE_MPG123_DELAYLOAD) && !defined(MPT_ENABLE_DYNBIND) #define MPT_ENABLE_DYNBIND // static MSVC builds require dynbind to load delay-loaded DLLs #endif #if defined(MPT_WITH_MEDIAFOUNDATION) && !defined(MPT_ENABLE_DYNBIND) #define MPT_ENABLE_DYNBIND // MediaFoundation needs dynamic loading in order to test availability of delay loaded libs #endif #if (defined(MPT_WITH_MPG123) || defined(MPT_WITH_MINIMP3)) && !defined(MPT_ENABLE_MP3_SAMPLES) #define MPT_ENABLE_MP3_SAMPLES #endif #if defined(ENABLE_TESTS) #define MPT_ENABLE_FILEIO // Test suite requires PathString for file loading. #endif #if !MPT_OS_WINDOWS && !defined(MPT_FILEREADER_STD_ISTREAM) #define MPT_FILEREADER_STD_ISTREAM // MMAP is only supported on Windows #endif #if defined(MODPLUG_TRACKER) && !defined(MPT_ENABLE_FILEIO) #define MPT_ENABLE_FILEIO // Tracker requires disk file io #endif #if defined(MODPLUG_TRACKER) && !defined(MPT_ENABLE_THREAD) #define MPT_ENABLE_THREAD // Tracker requires threads #endif #if defined(MPT_EXTERNAL_SAMPLES) && !defined(MPT_ENABLE_FILEIO) #define MPT_ENABLE_FILEIO // External samples require disk file io #endif #if !defined(MODPLUG_NO_FILESAVE) && !defined(MPT_ENABLE_FILEIO_STDIO) #define MPT_ENABLE_FILEIO_STDIO // file saving requires FILE* #endif #if defined(NO_PLUGINS) // Any plugin type requires NO_PLUGINS to not be defined. #define NO_VST #define NO_DMO #endif #if defined(MODPLUG_TRACKER) && !defined(MPT_BUILD_WINESUPPORT) && !defined(MPT_BUILD_WINESUPPORT_WRAPPER) #ifndef MPT_NO_NAMESPACE #define MPT_NO_NAMESPACE #endif #endif #if defined(MPT_NO_NAMESPACE) #ifdef OPENMPT_NAMESPACE #undef OPENMPT_NAMESPACE #endif #define OPENMPT_NAMESPACE #ifdef OPENMPT_NAMESPACE_BEGIN #undef OPENMPT_NAMESPACE_BEGIN #endif #define OPENMPT_NAMESPACE_BEGIN #ifdef OPENMPT_NAMESPACE_END #undef OPENMPT_NAMESPACE_END #endif #define OPENMPT_NAMESPACE_END #else #ifndef OPENMPT_NAMESPACE #define OPENMPT_NAMESPACE OpenMPT #endif #ifndef OPENMPT_NAMESPACE_BEGIN #define OPENMPT_NAMESPACE_BEGIN namespace OPENMPT_NAMESPACE { #endif #ifndef OPENMPT_NAMESPACE_END #define OPENMPT_NAMESPACE_END } #endif #endif // platform configuration #if MPT_OS_WINDOWS #define WIN32_LEAN_AND_MEAN // windows.h excludes #define NOMEMMGR // GMEM_*, LMEM_*, GHND, LHND, associated routines #define NOMINMAX // Macros min(a,b) and max(a,b) #define NOSERVICE // All Service Controller routines, SERVICE_ equates, etc. #define NOCOMM // COMM driver routines #define NOKANJI // Kanji support stuff. #define NOPROFILER // Profiler interface. #define NOMCX // Modem Configuration Extensions // mmsystem.h excludes #define MMNODRV //#define MMNOSOUND //#define MMNOWAVE //#define MMNOMIDI #define MMNOAUX #define MMNOMIXER //#define MMNOTIMER #define MMNOJOY #define MMNOMCI //#define MMNOMMIO //#define MMNOMMSYSTEM // mmreg.h excludes #define NOMMIDS //#define NONEWWAVE #define NONEWRIFF #define NOJPEGDIB #define NONEWIC #define NOBITMAP #endif // MPT_OS_WINDOWS // stdlib configuration #define __STDC_CONSTANT_MACROS #define __STDC_LIMIT_MACROS #define _USE_MATH_DEFINES #if !MPT_OS_ANDROID #ifndef _FILE_OFFSET_BITS #define _FILE_OFFSET_BITS 64 #endif #endif // !MPT_OS_ANDROID // compiler configuration #if MPT_COMPILER_MSVC #define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers #ifndef _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS // Define to disable the "This function or variable may be unsafe" warnings. #endif #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT 1 #ifndef _SCL_SECURE_NO_WARNINGS #define _SCL_SECURE_NO_WARNINGS #endif #ifndef NO_WARN_MBCS_MFC_DEPRECATION #define NO_WARN_MBCS_MFC_DEPRECATION #endif #pragma warning(disable:4355) // 'this' : used in base member initializer list // happens for immutable classes (i.e. classes containing const members) #pragma warning(disable:4512) // assignment operator could not be generated #pragma warning(error:4309) // Treat "truncation of constant value"-warning as error. #ifdef MPT_BUILD_ANALYZED // Disable Visual Studio static analyzer warnings that generate too many false positives in VS2010. //#pragma warning(disable:6246) //#pragma warning(disable:6262) #pragma warning(disable:6326) // Potential comparison of a constant with another constant //#pragma warning(disable:6385) //#pragma warning(disable:6386) #endif // MPT_BUILD_ANALYZED #endif // MPT_COMPILER_MSVC #if MPT_COMPILER_MSVCCLANGC2 #if MPT_OS_WINDOWS // As Clang defines __STDC__ 1, Windows headers will use named union fields. The MediaFoundation headers do not support this, though. // Clang supports nameless union fields just fine, and luckily there is a way to override the Windows headers behaviour. #define _FORCENAMELESSUNION #endif // MPT_OS_WINDOWS #endif // MPT_COMPILER_MSVCCLANGC2 // third-party library configuration #ifdef MPT_WITH_FLAC #ifdef MPT_BUILD_MSVC_STATIC #define FLAC__NO_DLL #endif #endif #ifdef MPT_WITH_PICOJSON #define PICOJSON_USE_INT64 #endif #ifdef MPT_WITH_SMBPITCHSHIFT #ifdef MPT_BUILD_MSVC_SHARED #define SMBPITCHSHIFT_USE_DLL #endif #endif #ifdef MPT_WITH_STBVORBIS #define STB_VORBIS_HEADER_ONLY #ifndef STB_VORBIS_NO_PULLDATA_API #define STB_VORBIS_NO_PULLDATA_API #endif #ifndef STB_VORBIS_NO_STDIO #define STB_VORBIS_NO_STDIO #endif #endif #ifdef MPT_WITH_VORBISFILE #ifndef OV_EXCLUDE_STATIC_CALLBACKS #define OV_EXCLUDE_STATIC_CALLBACKS #endif #endif #ifdef MPT_WITH_ZLIB #ifdef MPT_BUILD_MSVC_SHARED #define ZLIB_DLL #endif #endif libopenmpt-0.3.6+release.autotools/common/mptPathString.h0000644000372100037210000004015513166633425020541 00000000000000/* * mptPathString.h * --------------- * Purpose: Wrapper class around the platform-native representation of path names. Should be the only type that is used to store path names. * Notes : Currently none. * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include #include "FlagSet.h" OPENMPT_NAMESPACE_BEGIN #define MPT_DEPRECATED_PATH //#define MPT_DEPRECATED_PATH MPT_DEPRECATED namespace mpt { #if MPT_OS_WINDOWS typedef std::wstring RawPathString; #else // !MPT_OS_WINDOWS typedef std::string RawPathString; #endif // if MPT_OS_WINDOWS class PathString { private: RawPathString path; private: PathString(const RawPathString & path) : path(path) { return; } public: PathString() { return; } PathString(const PathString & other) : path(other.path) { return; } PathString & assign(const PathString & other) { path = other.path; return *this; } PathString & operator = (const PathString & other) { return assign(other); } PathString & append(const PathString & other) { path.append(other.path); return *this; } PathString & operator += (const PathString & other) { return append(other); } friend PathString operator + (const PathString & a, const PathString & b) { return PathString(a).append(b); } friend bool operator < (const PathString & a, const PathString & b) { return a.AsNative() < b.AsNative(); } friend bool operator == (const PathString & a, const PathString & b) { return a.AsNative() == b.AsNative(); } friend bool operator != (const PathString & a, const PathString & b) { return a.AsNative() != b.AsNative(); } bool empty() const { return path.empty(); } std::size_t Length() const { return path.size(); } public: #if MPT_OS_WINDOWS #if !MPT_OS_WINDOWS_WINRT static int CompareNoCase(const PathString & a, const PathString & b); #endif // !MPT_OS_WINDOWS_WINRT #endif #if MPT_OS_WINDOWS && (defined(MPT_ENABLE_DYNBIND) || defined(MPT_ENABLE_TEMPFILE)) void SplitPath(PathString *drive, PathString *dir, PathString *fname, PathString *ext) const; // \\?\ prefixes will be removed and \\?\\UNC prefixes converted to canonical \\ form. PathString GetDrive() const; // Drive letter + colon, e.g. "C:" or \\server\\share PathString GetDir() const; // Directory, e.g. "\OpenMPT\" PathString GetPath() const; // Drive + Dir, e.g. "C:\OpenMPT\" PathString GetFileName() const; // File name without extension, e.g. "mptrack" PathString GetFileExt() const; // Extension including dot, e.g. ".exe" PathString GetFullFileName() const; // File name + extension, e.g. "mptrack.exe" // Verify if this path represents a valid directory on the file system. bool IsDirectory() const; // Verify if this path exists and is a file on the file system. bool IsFile() const; #endif // MPT_OS_WINDOWS && (MPT_ENABLE_DYNBIND || MPT_ENABLE_TEMPFILE) #if defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS bool FileOrDirectoryExists() const; #endif // MODPLUG_TRACKER && MPT_OS_WINDOWS #if defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS // Return the same path string with a different (or appended) extension (including "."), e.g. "foo.bar",".txt" -> "foo.txt" or "C:\OpenMPT\foo",".txt" -> "C:\OpenMPT\foo.txt" PathString ReplaceExt(const mpt::PathString &newExt) const; // Removes special characters from a filename component and replaces them with a safe replacement character ("_" on windows). // Returns the result. // Note that this also removes path component separators, so this should only be used on single-component PathString objects. PathString SanitizeComponent() const; bool HasTrailingSlash() const { if(empty()) return false; RawPathString::value_type c = path[path.length() - 1]; #if MPT_OS_WINDOWS return (c == L'\\' || c == L'/'); #else return (c == '/'); #endif } mpt::PathString &EnsureTrailingSlash() { if(!path.empty() && !HasTrailingSlash()) { #if MPT_OS_WINDOWS path += L'\\'; #else path += '/'; #endif } return *this; } mpt::PathString WithoutTrailingSlash() const { mpt::PathString result = *this; while(result.HasTrailingSlash()) { if(result.Length() == 1) { return result; } result = result.AsNative().substr(0, result.AsNative().length() - 1); } return result; } mpt::PathString WithTrailingSlash() const { mpt::PathString result = *this; result.EnsureTrailingSlash(); return result; } // Relative / absolute paths conversion mpt::PathString AbsolutePathToRelative(const mpt::PathString &relativeTo) const; mpt::PathString RelativePathToAbsolute(const mpt::PathString &relativeTo) const; #endif // MODPLUG_TRACKER && MPT_OS_WINDOWS public: #if MPT_OS_WINDOWS #if !(MPT_WSTRING_CONVERT) #error "mpt::PathString on Windows depends on MPT_WSTRING_CONVERT)" #endif // conversions #if defined(MPT_ENABLE_CHARSET_LOCALE) MPT_DEPRECATED_PATH std::string ToLocale() const { return mpt::ToCharset(mpt::CharsetLocale, path); } #endif std::string ToUTF8() const { return mpt::ToCharset(mpt::CharsetUTF8, path); } std::wstring ToWide() const { return path; } mpt::ustring ToUnicode() const { return mpt::ToUnicode(path); } #if defined(MPT_ENABLE_CHARSET_LOCALE) MPT_DEPRECATED_PATH static PathString FromLocale(const std::string &path) { return PathString(mpt::ToWide(mpt::CharsetLocale, path)); } static PathString FromLocaleSilent(const std::string &path) { return PathString(mpt::ToWide(mpt::CharsetLocale, path)); } #endif static PathString FromUTF8(const std::string &path) { return PathString(mpt::ToWide(mpt::CharsetUTF8, path)); } static PathString FromWide(const std::wstring &path) { return PathString(path); } static PathString FromUnicode(const mpt::ustring &path) { return PathString(mpt::ToWide(path)); } RawPathString AsNative() const { return path; } // Return native string, with possible \\?\ prefix if it exceeds MAX_PATH characters. RawPathString AsNativePrefixed() const; static PathString FromNative(const RawPathString &path) { return PathString(path); } #if defined(_MFC_VER) // CString TCHAR, so this is CHAR or WCHAR, depending on UNICODE MPT_DEPRECATED_PATH CString ToCString() const { return mpt::ToCString(path); } MPT_DEPRECATED_PATH static PathString FromCString(const CString &path) { return PathString(mpt::ToWide(path)); } // Non-warning-generating versions of the above. Use with extra care. CString ToCStringSilent() const { return mpt::ToCString(path); } static PathString FromCStringSilent(const CString &path) { return PathString(mpt::ToWide(path)); } // really special purpose, if !UNICODE, encode unicode in CString as UTF8: static mpt::PathString TunnelOutofCString(const CString &path); static CString TunnelIntoCString(const mpt::PathString &path); // CStringW #ifdef UNICODE MPT_DEPRECATED_PATH CString ToCStringW() const { return mpt::ToCString(path); } MPT_DEPRECATED_PATH static PathString FromCStringW(const CString &path) { return PathString(mpt::ToWide(path)); } #else CStringW ToCStringW() const { return mpt::ToCStringW(path); } static PathString FromCStringW(const CStringW &path) { return PathString(mpt::ToWide(path)); } #endif #endif // Convert a path to its simplified form, i.e. remove ".\" and "..\" entries mpt::PathString Simplify() const; #else // !MPT_OS_WINDOWS // conversions #if defined(MPT_ENABLE_CHARSET_LOCALE) std::string ToLocale() const { return path; } std::string ToUTF8() const { return mpt::ToCharset(mpt::CharsetUTF8, mpt::CharsetLocale, path); } #if MPT_WSTRING_CONVERT std::wstring ToWide() const { return mpt::ToWide(mpt::CharsetLocale, path); } #endif mpt::ustring ToUnicode() const { return mpt::ToUnicode(mpt::CharsetLocale, path); } static PathString FromLocale(const std::string &path) { return PathString(path); } static PathString FromLocaleSilent(const std::string &path) { return PathString(path); } static PathString FromUTF8(const std::string &path) { return PathString(mpt::ToCharset(mpt::CharsetLocale, mpt::CharsetUTF8, path)); } #if MPT_WSTRING_CONVERT static PathString FromWide(const std::wstring &path) { return PathString(mpt::ToCharset(mpt::CharsetLocale, path)); } #endif static PathString FromUnicode(const mpt::ustring &path) { return PathString(mpt::ToCharset(mpt::CharsetLocale, path)); } RawPathString AsNative() const { return path; } RawPathString AsNativePrefixed() const { return path; } static PathString FromNative(const RawPathString &path) { return PathString(path); } #else // !MPT_ENABLE_CHARSET_LOCALE std::string ToUTF8() const { return path; } #if MPT_WSTRING_CONVERT std::wstring ToWide() const { return mpt::ToWide(mpt::CharsetUTF8, path); } #endif mpt::ustring ToUnicode() const { return mpt::ToUnicode(mpt::CharsetUTF8, path); } static PathString FromUTF8(const std::string &path) { return path; } #if MPT_WSTRING_CONVERT static PathString FromWide(const std::wstring &path) { return PathString(mpt::ToCharset(mpt::CharsetUTF8, path)); } #endif static PathString FromUnicode(const mpt::ustring &path) { return PathString(mpt::ToCharset(mpt::CharsetUTF8, path)); } RawPathString AsNative() const { return path; } RawPathString AsNativePrefixed() const { return path; } static PathString FromNative(const RawPathString &path) { return PathString(path); } #endif // MPT_ENABLE_CHARSET_LOCALE // Convert a path to its simplified form (currently only implemented on Windows) MPT_DEPRECATED mpt::PathString Simplify() const { return path; } #endif // MPT_OS_WINDOWS }; #if defined(MPT_ENABLE_CHARSET_LOCALE) MPT_DEPRECATED_PATH static inline std::string ToString(const mpt::PathString & x) { return mpt::ToCharset(mpt::CharsetLocale, x.ToUnicode()); } #endif static inline mpt::ustring ToUString(const mpt::PathString & x) { return x.ToUnicode(); } #if MPT_WSTRING_FORMAT static inline std::wstring ToWString(const mpt::PathString & x) { return x.ToWide(); } #endif } // namespace mpt #if MPT_OS_WINDOWS #define MPT_PATHSTRING(x) mpt::PathString::FromNative( L ## x ) #else // !MPT_OS_WINDOWS #define MPT_PATHSTRING(x) mpt::PathString::FromNative( x ) #endif // MPT_OS_WINDOWS namespace mpt { bool IsPathSeparator(mpt::RawPathString::value_type c); bool PathIsAbsolute(const mpt::PathString &path); #if MPT_OS_WINDOWS // Returns the absolute path for a potentially relative path and removes ".." or "." components. (same as GetFullPathNameW) mpt::PathString GetAbsolutePath(const mpt::PathString &path); #ifdef MODPLUG_TRACKER // Deletes a complete directory tree. Handle with EXTREME care. // Returns false if any file could not be removed and aborts as soon as it // encounters any error. path must be absolute. bool DeleteWholeDirectoryTree(mpt::PathString path); #endif // MODPLUG_TRACKER #endif // MPT_OS_WINDOWS #if MPT_OS_WINDOWS #if defined(MPT_ENABLE_DYNBIND) || defined(MPT_ENABLE_TEMPFILE) // Returns the application path or an empty string (if unknown), e.g. "C:\mptrack\" mpt::PathString GetAppPath(); #endif // MPT_ENABLE_DYNBIND || MPT_ENABLE_TEMPFILE #if defined(MPT_ENABLE_DYNBIND) #if !MPT_OS_WINDOWS_WINRT // Returns the system directory path, e.g. "C:\Windows\System32\" mpt::PathString GetSystemPath(); #endif // !MPT_OS_WINDOWS_WINRT #endif // MPT_ENABLE_DYNBIND #endif // MPT_OS_WINDOWS #if defined(MPT_ENABLE_TEMPFILE) #if MPT_OS_WINDOWS // Returns temporary directory (with trailing backslash added) (e.g. "C:\TEMP\") mpt::PathString GetTempDirectory(); // Returns a new unique absolute path. mpt::PathString CreateTempFileName(const mpt::PathString &fileNamePrefix = mpt::PathString(), const mpt::PathString &fileNameExtension = MPT_PATHSTRING("tmp")); // Scoped temporary file guard. Deletes the file when going out of scope. // The file itself is not created automatically. class TempFileGuard { private: const mpt::PathString filename; public: TempFileGuard(const mpt::PathString &filename = CreateTempFileName()); mpt::PathString GetFilename() const; ~TempFileGuard(); }; #ifdef MODPLUG_TRACKER // Scoped temporary directory guard. Deletes the directory when going out of scope. // The directory itself is created automatically. class TempDirGuard { private: mpt::PathString dirname; public: TempDirGuard(const mpt::PathString &dirname_ = CreateTempFileName()); mpt::PathString GetDirname() const; ~TempDirGuard(); }; #endif // MODPLUG_TRACKER #endif // MPT_OS_WINDOWS #endif // MPT_ENABLE_TEMPFILE } // namespace mpt #if defined(MODPLUG_TRACKER) // Sanitize a filename (remove special chars) void SanitizeFilename(mpt::PathString &filename); void SanitizeFilename(char *beg, char *end); void SanitizeFilename(wchar_t *beg, wchar_t *end); void SanitizeFilename(std::string &str); void SanitizeFilename(std::wstring &str); #if MPT_USTRING_MODE_UTF8 void SanitizeFilename(mpt::u8string &str); #endif // MPT_USTRING_MODE_UTF8 template void SanitizeFilename(char (&buffer)[size]) { STATIC_ASSERT(size > 0); SanitizeFilename(buffer, buffer + size); } template void SanitizeFilename(wchar_t (&buffer)[size]) { STATIC_ASSERT(size > 0); SanitizeFilename(buffer, buffer + size); } #if defined(_MFC_VER) void SanitizeFilename(CString &str); #endif #endif // MODPLUG_TRACKER #if defined(MODPLUG_TRACKER) enum FileTypeFormat { FileTypeFormatNone = 0 , // do not show extensions after description, i.e. "Foo Files" FileTypeFormatShowExtensions = 1<<0, // show extensions after descripten, i.e. "Foo Files (*.foo,*.bar)" }; MPT_DECLARE_ENUM(FileTypeFormat) class FileType { private: mpt::ustring m_ShortName; // "flac", "mod" (lowercase) mpt::ustring m_Description; // "FastTracker 2 Module" std::vector m_MimeTypes; // "audio/ogg" (in ASCII) std::vector m_Extensions; // "mod", "xm" (lowercase) std::vector m_Prefixes; // "mod" for "mod.*" public: FileType() { } FileType(const std::vector &group) { for(const auto &type : group) { m_MimeTypes.insert(m_MimeTypes.end(), type.m_MimeTypes.begin(), type.m_MimeTypes.end()); m_Extensions.insert(m_Extensions.end(), type.m_Extensions.begin(), type.m_Extensions.end()); m_Prefixes.insert(m_Prefixes.end(), type.m_Prefixes.begin(), type.m_Prefixes.end()); } } static FileType Any() { return FileType().ShortName(MPT_USTRING("*")).Description(MPT_USTRING("All Files")).AddExtension(MPT_PATHSTRING("*")); } public: FileType& ShortName(const mpt::ustring &shortName) { m_ShortName = shortName; return *this; } FileType& Description(const mpt::ustring &description) { m_Description = description; return *this; } FileType& MimeTypes(const std::vector &mimeTypes) { m_MimeTypes = mimeTypes; return *this; } FileType& Extensions(const std::vector &extensions) { m_Extensions = extensions; return *this; } FileType& Prefixes(const std::vector &prefixes) { m_Prefixes = prefixes; return *this; } FileType& AddMimeType(const std::string &mimeType) { m_MimeTypes.push_back(mimeType); return *this; } FileType& AddExtension(const mpt::PathString &extension) { m_Extensions.push_back(extension); return *this; } FileType& AddPrefix(const mpt::PathString &prefix) { m_Prefixes.push_back(prefix); return *this; } public: mpt::ustring GetShortName() const { return m_ShortName; } mpt::ustring GetDescription() const { return m_Description; } std::vector GetMimeTypes() const { return m_MimeTypes; } std::vector GetExtensions() const { return m_Extensions; } std::vector GetPrefixes() const { return m_Prefixes; } public: mpt::PathString AsFilterString(FlagSet format = FileTypeFormatNone) const; mpt::PathString AsFilterOnlyString() const; }; // class FileType // "Ogg Vorbis|*.ogg;*.oga|" // FileTypeFormatNone // "Ogg Vorbis (*.ogg,*.oga)|*.ogg;*.oga|" // FileTypeFormatShowExtensions mpt::PathString ToFilterString(const FileType &fileType, FlagSet format = FileTypeFormatNone); mpt::PathString ToFilterString(const std::vector &fileTypes, FlagSet format = FileTypeFormatNone); // "*.ogg;*.oga" / ";*.ogg;*.oga" mpt::PathString ToFilterOnlyString(const FileType &fileType, bool prependSemicolonWhenNotEmpty = false); mpt::PathString ToFilterOnlyString(const std::vector &fileTypes, bool prependSemicolonWhenNotEmpty = false); #endif // MODPLUG_TRACKER OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/FileReader.h0000644000372100037210000010006613161656666017744 00000000000000/* * FileReader.h * ------------ * Purpose: A basic class for transparent reading of memory-based files. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "typedefs.h" #include "mptTypeTraits.h" #include "StringFixer.h" #include "misc_util.h" #include "Endianness.h" #include "mptIO.h" #include #include #include #include #include "FileReaderFwd.h" OPENMPT_NAMESPACE_BEGIN // change to show warnings for functions which trigger pre-caching the whole file for unseekable streams //#define FILEREADER_DEPRECATED MPT_DEPRECATED #define FILEREADER_DEPRECATED class FileReaderTraitsMemory { public: typedef FileDataContainerMemory::off_t off_t; typedef FileDataContainerMemory data_type; typedef const FileDataContainerMemory & ref_data_type; typedef const FileDataContainerMemory & shared_data_type; typedef FileDataContainerMemory value_data_type; static shared_data_type get_shared(const data_type & data) { return data; } static ref_data_type get_ref(const data_type & data) { return data; } static value_data_type make_data() { return mpt::const_byte_span(); } static value_data_type make_data(mpt::const_byte_span data) { return data; } static value_data_type make_chunk(shared_data_type data, off_t position, off_t size) { return mpt::as_span(data.GetRawData() + position, size); } }; #if defined(MPT_FILEREADER_STD_ISTREAM) class FileReaderTraitsStdStream { public: typedef IFileDataContainer::off_t off_t; typedef std::shared_ptr data_type; typedef const IFileDataContainer & ref_data_type; typedef std::shared_ptr shared_data_type; typedef std::shared_ptr value_data_type; static shared_data_type get_shared(const data_type & data) { return data; } static ref_data_type get_ref(const data_type & data) { return *data; } static value_data_type make_data() { return std::make_shared(); } static value_data_type make_data(mpt::const_byte_span data) { return std::make_shared(data); } static value_data_type make_chunk(shared_data_type data, off_t position, off_t size) { return std::static_pointer_cast(std::make_shared(data, position, size)); } }; typedef FileReaderTraitsStdStream FileReaderTraitsDefault; #else // !MPT_FILEREADER_STD_ISTREAM typedef FileReaderTraitsMemory FileReaderTraitsDefault; #endif // MPT_FILEREADER_STD_ISTREAM namespace detail { template class FileReader { private: typedef Ttraits traits_type; public: typedef typename traits_type::off_t off_t; typedef typename traits_type::data_type data_type; typedef typename traits_type::ref_data_type ref_data_type; typedef typename traits_type::shared_data_type shared_data_type; typedef typename traits_type::value_data_type value_data_type; protected: shared_data_type SharedDataContainer() const { return traits_type::get_shared(m_data); } ref_data_type DataContainer() const { return traits_type::get_ref(m_data); } static value_data_type DataInitializer() { return traits_type::make_data(); } static value_data_type DataInitializer(mpt::const_byte_span data) { return traits_type::make_data(data); } static value_data_type CreateChunkImpl(shared_data_type data, off_t position, off_t size) { return traits_type::make_chunk(data, position, size); } private: data_type m_data; off_t streamPos; // Cursor location in the file const mpt::PathString *fileName; // Filename that corresponds to this FileReader. It is only set if this FileReader represents the whole contents of fileName. May be nullptr. Lifetime is managed outside of FileReader. public: // Initialize invalid file reader object. FileReader() : m_data(DataInitializer()), streamPos(0), fileName(nullptr) { } // Initialize file reader object with pointer to data and data length. template FileReader(mpt::span bytedata, const mpt::PathString *filename = nullptr) : m_data(DataInitializer(mpt::byte_cast(bytedata))), streamPos(0), fileName(filename) { } // Initialize file reader object based on an existing file reader object window. explicit FileReader(value_data_type other, const mpt::PathString *filename = nullptr) : m_data(other), streamPos(0), fileName(filename) { } // Initialize file reader object based on an existing file reader object. The other object's stream position is copied. FileReader(const FileReader &) = default; FileReader& operator=(const FileReader &) = default; // Move an existing file reader object FileReader(FileReader &&) noexcept = default; FileReader& operator=(FileReader &&) noexcept = default; public: mpt::PathString GetFileName() const { if(!fileName) { return mpt::PathString(); } return *fileName; } // Returns true if the object points to a valid (non-empty) stream. operator bool() const { return IsValid(); } // Returns true if the object points to a valid (non-empty) stream. bool IsValid() const { return DataContainer().IsValid(); } // Reset cursor to first byte in file. void Rewind() { streamPos = 0; } // Seek to a position in the mapped file. // Returns false if position is invalid. bool Seek(off_t position) { if(position <= streamPos) { streamPos = position; return true; } if(position <= DataContainer().GetLength()) { streamPos = position; return true; } else { return false; } } // Increases position by skipBytes. // Returns true if skipBytes could be skipped or false if the file end was reached earlier. bool Skip(off_t skipBytes) { if(CanRead(skipBytes)) { streamPos += skipBytes; return true; } else { streamPos = DataContainer().GetLength(); return false; } } // Decreases position by skipBytes. // Returns true if skipBytes could be skipped or false if the file start was reached earlier. bool SkipBack(off_t skipBytes) { if(streamPos >= skipBytes) { streamPos -= skipBytes; return true; } else { streamPos = 0; return false; } } // Returns cursor position in the mapped file. off_t GetPosition() const { return streamPos; } // Return true IFF seeking and GetLength() is fast. // In particular, it returns false for unseekable stream where GetLength() // requires pre-caching. bool HasFastGetLength() const { return DataContainer().HasFastGetLength(); } // Returns size of the mapped file in bytes. FILEREADER_DEPRECATED off_t GetLength() const { // deprecated because in case of an unseekable std::istream, this triggers caching of the whole file return DataContainer().GetLength(); } // Return byte count between cursor position and end of file, i.e. how many bytes can still be read. FILEREADER_DEPRECATED off_t BytesLeft() const { // deprecated because in case of an unseekable std::istream, this triggers caching of the whole file return DataContainer().GetLength() - streamPos; } bool EndOfFile() const { return !CanRead(1); } bool NoBytesLeft() const { return !CanRead(1); } // Check if "amount" bytes can be read from the current position in the stream. bool CanRead(off_t amount) const { return DataContainer().CanRead(streamPos, amount); } // Check if file size is at least size, without potentially caching the whole file to query the exact file length. bool LengthIsAtLeast(off_t size) const { return DataContainer().CanRead(0, size); } // Check if file size is exactly size, without potentially caching the whole file if it is larger. bool LengthIs(off_t size) const { return DataContainer().CanRead(0, size) && !DataContainer().CanRead(size, 1); } protected: FileReader CreateChunk(off_t position, off_t length) const { off_t readableLength = DataContainer().GetReadableLength(position, length); if(readableLength == 0) { return FileReader(); } return FileReader(CreateChunkImpl(SharedDataContainer(), position, std::min(length, DataContainer().GetLength() - position))); } public: // Create a new FileReader object for parsing a sub chunk at a given position with a given length. // The file cursor is not modified. FileReader GetChunkAt(off_t position, off_t length) const { return CreateChunk(position, length); } // Create a new FileReader object for parsing a sub chunk at the current position with a given length. // The file cursor is not advanced. FileReader GetChunk(off_t length) { return CreateChunk(streamPos, length); } // Create a new FileReader object for parsing a sub chunk at the current position with a given length. // The file cursor is advanced by "length" bytes. FileReader ReadChunk(off_t length) { off_t position = streamPos; Skip(length); return CreateChunk(position, length); } class PinnedRawDataView { private: std::size_t size_; const mpt::byte *pinnedData; std::vector cache; private: void Init(const FileReader &file, std::size_t size) { size_ = 0; pinnedData = nullptr; if(!file.CanRead(size)) { size = file.BytesLeft(); } size_ = size; if(file.DataContainer().HasPinnedView()) { pinnedData = file.DataContainer().GetRawData() + file.GetPosition(); } else { cache.resize(size_); if(!cache.empty()) { file.GetRaw(&(cache[0]), size); } } } public: PinnedRawDataView() { return; } PinnedRawDataView(const FileReader &file) { Init(file, file.BytesLeft()); } PinnedRawDataView(const FileReader &file, std::size_t size) { Init(file, size); } PinnedRawDataView(FileReader &file, bool advance) { Init(file, file.BytesLeft()); if(advance) { file.Skip(size_); } } PinnedRawDataView(FileReader &file, std::size_t size, bool advance) { Init(file, size); if(advance) { file.Skip(size_); } } public: mpt::const_byte_span GetSpan() const { if(pinnedData) { return mpt::as_span(pinnedData, size_); } else if(!cache.empty()) { return mpt::as_span(cache); } else { return mpt::const_byte_span(); } } mpt::const_byte_span span() const { return GetSpan(); } void invalidate() { size_ = 0; pinnedData = nullptr; cache = std::vector(); } const mpt::byte *data() const { return span().data(); } std::size_t size() const { return size_; } mpt::const_byte_span::iterator begin() const { return span().begin(); } mpt::const_byte_span::iterator end() const { return span().end(); } mpt::const_byte_span::const_iterator cbegin() const { return span().cbegin(); } mpt::const_byte_span::const_iterator cend() const { return span().cend(); } }; // Returns a pinned view into the remaining raw data from cursor position. PinnedRawDataView GetPinnedRawDataView() const { return PinnedRawDataView(*this); } // Returns a pinned view into the remeining raw data from cursor position, clamped at size. PinnedRawDataView GetPinnedRawDataView(std::size_t size) const { return PinnedRawDataView(*this, size); } // Returns a pinned view into the remeining raw data from cursor position. // File cursor is advaned by the size of the returned pinned view. PinnedRawDataView ReadPinnedRawDataView() { return PinnedRawDataView(*this, true); } // Returns a pinned view into the remeining raw data from cursor position, clamped at size. // File cursor is advaned by the size of the returned pinned view. PinnedRawDataView ReadPinnedRawDataView(std::size_t size) { return PinnedRawDataView(*this, size, true); } // Returns raw stream data at cursor position. // Should only be used if absolutely necessary, for example for sample reading, or when used with a small chunk of the file retrieved by ReadChunk(). // Use GetPinnedRawDataView(size) whenever possible. FILEREADER_DEPRECATED const mpt::byte *GetRawData() const { // deprecated because in case of an unseekable std::istream, this triggers caching of the whole file return DataContainer().GetRawData() + streamPos; } template FILEREADER_DEPRECATED const T *GetRawData() const { // deprecated because in case of an unseekable std::istream, this triggers caching of the whole file return mpt::byte_cast(DataContainer().GetRawData() + streamPos); } template std::size_t GetRaw(T *dst, std::size_t count) const { return static_cast(DataContainer().Read(mpt::byte_cast(dst), streamPos, count)); } template std::size_t ReadRaw(T *dst, std::size_t count) { std::size_t result = static_cast(DataContainer().Read(mpt::byte_cast(dst), streamPos, count)); streamPos += result; return result; } std::vector GetRawDataAsByteVector() const { PinnedRawDataView view = GetPinnedRawDataView(); return std::vector(view.span().begin(), view.span().end()); } std::vector ReadRawDataAsByteVector() { PinnedRawDataView view = ReadPinnedRawDataView(); return std::vector(view.span().begin(), view.span().end()); } std::vector GetRawDataAsByteVector(std::size_t size) const { PinnedRawDataView view = GetPinnedRawDataView(size); return std::vector(view.span().begin(), view.span().end()); } std::vector ReadRawDataAsByteVector(std::size_t size) { PinnedRawDataView view = ReadPinnedRawDataView(size); return std::vector(view.span().begin(), view.span().end()); } std::string GetRawDataAsString() const { PinnedRawDataView view = GetPinnedRawDataView(); return std::string(view.span().begin(), view.span().end()); } std::string ReadRawDataAsString() { PinnedRawDataView view = ReadPinnedRawDataView(); return std::string(view.span().begin(), view.span().end()); } std::string GetRawDataAsString(std::size_t size) const { PinnedRawDataView view = GetPinnedRawDataView(size); return std::string(view.span().begin(), view.span().end()); } std::string ReadRawDataAsString(std::size_t size) { PinnedRawDataView view = ReadPinnedRawDataView(size); return std::string(view.span().begin(), view.span().end()); } protected: // Read a "T" object from the stream. // If not enough bytes can be read, false is returned. // If successful, the file cursor is advanced by the size of "T". template bool Read(T &target) { if(sizeof(T) != DataContainer().Read(reinterpret_cast(&target), streamPos, sizeof(T))) { return false; } streamPos += sizeof(T); return true; } public: // Read some kind of integer in little-endian format. // If successful, the file cursor is advanced by the size of the integer. template T ReadIntLE() { static_assert(std::numeric_limits::is_integer == true, "Target type is a not an integer"); T target; if(Read(target)) { return SwapBytesLE(target); } else { return 0; } } // Read some kind of integer in big-endian format. // If successful, the file cursor is advanced by the size of the integer. template T ReadIntBE() { static_assert(std::numeric_limits::is_integer == true, "Target type is a not an integer"); T target; if(Read(target)) { return SwapBytesBE(target); } else { return 0; } } // Read a integer in little-endian format which has some of its higher bytes not stored in file. // If successful, the file cursor is advanced by the given size. template T ReadTruncatedIntLE(off_t size) { static_assert(std::numeric_limits::is_integer == true, "Target type is a not an integer"); MPT_ASSERT(sizeof(T) >= size); if(size == 0) { return 0; } if(!CanRead(size)) { return 0; } uint8 buf[sizeof(T)]; bool negative = false; for(std::size_t i = 0; i < sizeof(T); ++i) { uint8 byte = 0; if(i < size) { Read(byte); negative = std::numeric_limits::is_signed && ((byte & 0x80) != 0x00); } else { // sign or zero extend byte = negative ? 0xff : 0x00; } buf[i] = byte; } T target; std::memcpy(&target, buf, sizeof(T)); return SwapBytesLE(target); } // Read a supplied-size little endian integer to a fixed size variable. // The data is properly sign-extended when fewer bytes are stored. // If more bytes are stored, higher order bytes are silently ignored. // If successful, the file cursor is advanced by the given size. template T ReadSizedIntLE(off_t size) { static_assert(std::numeric_limits::is_integer == true, "Target type is a not an integer"); if(size == 0) { return 0; } if(!CanRead(size)) { return 0; } if(size < sizeof(T)) { return ReadTruncatedIntLE(size); } T retval = ReadIntLE(); Skip(size - sizeof(T)); return retval; } // Read unsigned 32-Bit integer in little-endian format. // If successful, the file cursor is advanced by the size of the integer. uint32 ReadUint32LE() { return ReadIntLE(); } // Read unsigned 32-Bit integer in big-endian format. // If successful, the file cursor is advanced by the size of the integer. uint32 ReadUint32BE() { return ReadIntBE(); } // Read signed 32-Bit integer in little-endian format. // If successful, the file cursor is advanced by the size of the integer. int32 ReadInt32LE() { return ReadIntLE(); } // Read signed 32-Bit integer in big-endian format. // If successful, the file cursor is advanced by the size of the integer. int32 ReadInt32BE() { return ReadIntBE(); } // Read unsigned 16-Bit integer in little-endian format. // If successful, the file cursor is advanced by the size of the integer. uint16 ReadUint16LE() { return ReadIntLE(); } // Read unsigned 16-Bit integer in big-endian format. // If successful, the file cursor is advanced by the size of the integer. uint16 ReadUint16BE() { return ReadIntBE(); } // Read signed 16-Bit integer in little-endian format. // If successful, the file cursor is advanced by the size of the integer. int16 ReadInt16LE() { return ReadIntLE(); } // Read signed 16-Bit integer in big-endian format. // If successful, the file cursor is advanced by the size of the integer. int16 ReadInt16BE() { return ReadIntBE(); } // Read unsigned 8-Bit integer. // If successful, the file cursor is advanced by the size of the integer. uint8 ReadUint8() { uint8 target; if(Read(target)) { return target; } else { return 0; } } // Read signed 8-Bit integer. If successful, the file cursor is advanced by the size of the integer. int8 ReadInt8() { int8 target; if(Read(target)) { return target; } else { return 0; } } // Read 32-Bit float in little-endian format. // If successful, the file cursor is advanced by the size of the float. float ReadFloatLE() { IEEE754binary32LE target; if(Read(target)) { return target; } else { return 0.0f; } } // Read 32-Bit float in big-endian format. // If successful, the file cursor is advanced by the size of the float. float ReadFloatBE() { IEEE754binary32BE target; if(Read(target)) { return target; } else { return 0.0f; } } // Read 64-Bit float in little-endian format. // If successful, the file cursor is advanced by the size of the float. double ReadDoubleLE() { IEEE754binary64LE target; if(Read(target)) { return target; } else { return 0.0f; } } // Read 64-Bit float in big-endian format. // If successful, the file cursor is advanced by the size of the float. double ReadDoubleBE() { IEEE754binary64BE target; if(Read(target)) { return target; } else { return 0.0f; } } // Read a struct. // If successful, the file cursor is advanced by the size of the struct. Otherwise, the target is zeroed. template bool ReadStruct(T &target) { STATIC_ASSERT(mpt::is_binary_safe::value); if(Read(target)) { return true; } else { MemsetZero(target); return false; } } // Allow to read a struct partially (if there's less memory available than the struct's size, fill it up with zeros). // The file cursor is advanced by "partialSize" bytes. template bool ReadStructPartial(T &target, off_t partialSize = sizeof(T)) { STATIC_ASSERT(mpt::is_binary_safe::value); off_t copyBytes = std::min(partialSize, sizeof(T)); if(!CanRead(copyBytes)) { copyBytes = BytesLeft(); } DataContainer().Read(reinterpret_cast(&target), streamPos, copyBytes); std::memset(reinterpret_cast(&target) + copyBytes, 0, sizeof(target) - copyBytes); Skip(partialSize); return true; } // Read a string of length srcSize into fixed-length char array destBuffer using a given read mode. // The file cursor is advanced by "srcSize" bytes. // Returns true if at least one byte could be read or 0 bytes were requested. template bool ReadString(char (&destBuffer)[destSize], const off_t srcSize) { FileReader::PinnedRawDataView source = ReadPinnedRawDataView(srcSize); // Make sure the string is cached properly. off_t realSrcSize = source.size(); // In case fewer bytes are available mpt::String::Read(destBuffer, mpt::byte_cast(source.data()), realSrcSize); return (realSrcSize > 0 || srcSize == 0); } // Read a string of length srcSize into a std::string dest using a given read mode. // The file cursor is advanced by "srcSize" bytes. // Returns true if at least one character could be read or 0 characters were requested. template bool ReadString(std::string &dest, const off_t srcSize) { FileReader::PinnedRawDataView source = ReadPinnedRawDataView(srcSize); // Make sure the string is cached properly. off_t realSrcSize = source.size(); // In case fewer bytes are available mpt::String::Read(dest, mpt::byte_cast(source.data()), realSrcSize); return (realSrcSize > 0 || srcSize == 0); } // Read a charset encoded string of length srcSize into a mpt::ustring dest using a given read mode. // The file cursor is advanced by "srcSize" bytes. // Returns true if at least one character could be read or 0 characters were requested. template bool ReadString(mpt::ustring &dest, mpt::Charset charset, const off_t srcSize) { FileReader::PinnedRawDataView source = ReadPinnedRawDataView(srcSize); // Make sure the string is cached properly. off_t realSrcSize = source.size(); // In case fewer bytes are available mpt::String::Read(dest, charset, mpt::byte_cast(source.data()), realSrcSize); return (realSrcSize > 0 || srcSize == 0); } // Read a string with a preprended length field of type Tsize (must be a packed<*,*> type) into a std::string dest using a given read mode. // The file cursor is advanced by the string length. // Returns true if the size field could be read and at least one character could be read or 0 characters were requested. template bool ReadSizedString(char (&destBuffer)[destSize], const off_t maxLength = std::numeric_limits::max()) { packed srcSize; // Enforce usage of a packed type by ensuring that the passed type has the required typedefs if(!Read(srcSize)) return false; return ReadString(destBuffer, std::min(srcSize, maxLength)); } // Read a string with a preprended length field of type Tsize (must be a packed<*,*> type) into a std::string dest using a given read mode. // The file cursor is advanced by the string length. // Returns true if the size field could be read and at least one character could be read or 0 characters were requested. template bool ReadSizedString(std::string &dest, const off_t maxLength = std::numeric_limits::max()) { packed srcSize; // Enforce usage of a packed type by ensuring that the passed type has the required typedefs if(!Read(srcSize)) return false; return ReadString(dest, std::min(srcSize, maxLength)); } // Read a null-terminated string into a std::string bool ReadNullString(std::string &dest, const off_t maxLength = std::numeric_limits::max()) { dest.clear(); if(!CanRead(1)) return false; try { char buffer[64]; off_t avail = 0; while((avail = std::min(DataContainer().Read(reinterpret_cast(buffer), streamPos, sizeof(buffer)), maxLength - dest.length())) != 0) { auto end = std::find(buffer, buffer + avail, '\0'); dest.insert(dest.end(), buffer, end); streamPos += (end - buffer); if(end < buffer + avail) { // Found null char streamPos++; break; } } } MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e) { MPT_EXCEPTION_DELETE_OUT_OF_MEMORY(e); } return dest.length() != 0; } private: static MPT_FORCEINLINE bool IsLineEnding(char c) { return c == '\r' || c == '\n'; } public: // Read a string up to the next line terminator into a std::string bool ReadLine(std::string &dest, const off_t maxLength = std::numeric_limits::max()) { dest.clear(); if(!CanRead(1)) return false; try { char buffer[64], c = '\0'; off_t avail = 0; while((avail = std::min(DataContainer().Read(reinterpret_cast(buffer), streamPos, sizeof(buffer)), maxLength - dest.length())) != 0) { auto end = std::find_if(buffer, buffer + avail, IsLineEnding); dest.insert(dest.end(), buffer, end); streamPos += (end - buffer); if(end < buffer + avail) { // Found line ending streamPos++; // Handle CRLF line ending if(*end == '\r') { if(Read(c) && c != '\n') SkipBack(1); } break; } } } MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e) { MPT_EXCEPTION_DELETE_OUT_OF_MEMORY(e); } return true; } // Read an array of binary-safe T values. // If successful, the file cursor is advanced by the size of the array. // Otherwise, the target is zeroed. template bool ReadArray(T (&destArray)[destSize]) { STATIC_ASSERT(mpt::is_binary_safe::value); if(CanRead(sizeof(destArray))) { for(auto &element : destArray) { Read(element); } return true; } else { MemsetZero(destArray); return false; } } // Read destSize elements of binary-safe type T into a vector. // If successful, the file cursor is advanced by the size of the vector. // Otherwise, the vector is resized to destSize, but possibly existing contents are not cleared. template bool ReadVector(std::vector &destVector, size_t destSize) { STATIC_ASSERT(mpt::is_binary_safe::value); destVector.resize(destSize); if(CanRead(sizeof(T) * destSize)) { for(auto &element : destVector) { Read(element); } return true; } else { return false; } } // Compare a magic string with the current stream position. // Returns true if they are identical and advances the file cursor by the the length of the "magic" string. // Returns false if the string could not be found. The file cursor is not advanced in this case. template bool ReadMagic(const char (&magic)[N]) { MPT_ASSERT(magic[N - 1] == '\0'); for(std::size_t i = 0; i < N - 1; ++i) { MPT_ASSERT(magic[i] != '\0'); } if(CanRead(N - 1)) { mpt::byte bytes[N - 1]; STATIC_ASSERT(sizeof(bytes) == sizeof(magic) - 1); DataContainer().Read(bytes, streamPos, N - 1); if(!std::memcmp(bytes, magic, N - 1)) { streamPos += (N - 1); return true; } } return false; } bool ReadMagic(const char *const magic, off_t magicLength) { if(CanRead(magicLength)) { bool identical = true; for(std::size_t i = 0; i < magicLength; ++i) { mpt::byte c = 0; DataContainer().Read(&c, streamPos + i, 1); if(c != mpt::byte_cast(magic[i])) { identical = false; break; } } if(identical) { streamPos += magicLength; return true; } else { return false; } } else { return false; } } // Read variable-length unsigned integer (as found in MIDI files). // If successful, the file cursor is advanced by the size of the integer and true is returned. // False is returned if not enough bytes were left to finish reading of the integer or if an overflow happened (source doesn't fit into target integer). // In case of an overflow, the target is also set to the maximum value supported by its data type. template bool ReadVarInt(T &target) { static_assert(std::numeric_limits::is_integer == true && std::numeric_limits::is_signed == false, "Target type is not an unsigned integer"); if(NoBytesLeft()) { target = 0; return false; } mpt::byte bytes[16]; // More than enough for any valid VarInt off_t avail = DataContainer().Read(bytes, streamPos, sizeof(bytes)), readPos = 1; size_t writtenBits = 0; uint8 b = bytes[0]; target = (b & 0x7F); // Count actual bits used in most significant byte (i.e. this one) for(size_t bit = 0; bit < 7; bit++) { if((b & (1u << bit)) != 0) { writtenBits = bit + 1; } } while(readPos < avail && (b & 0x80) != 0) { b = bytes[readPos++]; target <<= 7; target |= (b & 0x7F); writtenBits += 7; if(readPos == avail) { streamPos += readPos; avail = DataContainer().Read(bytes, streamPos, sizeof(bytes)); readPos = 0; } } streamPos += readPos; if(writtenBits > sizeof(target) * 8u) { // Overflow target = Util::MaxValueOfType(target); return false; } else if((b & 0x80) != 0) { // Reached EOF return false; } return true; } }; } // namespace detail typedef detail::FileReader FileReader; typedef detail::FileReader MemoryFileReader; #if defined(LIBOPENMPT_BUILD) // Initialize file reader object with pointer to data and data length. template static inline FileReader make_FileReader(mpt::span bytedata, const mpt::PathString *filename = nullptr) { return FileReader(mpt::byte_cast(bytedata), filename); } #if defined(MPT_FILEREADER_STD_ISTREAM) #if defined(MPT_FILEREADER_CALLBACK_STREAM) // Initialize file reader object with a CallbackStream. static inline FileReader make_FileReader(CallbackStream s, const mpt::PathString *filename = nullptr) { return FileReader( FileDataContainerCallbackStreamSeekable::IsSeekable(s) ? std::static_pointer_cast(std::make_shared(s)) : std::static_pointer_cast(std::make_shared(s)) , filename ); } #endif // MPT_FILEREADER_CALLBACK_STREAM // Initialize file reader object with a std::istream. static inline FileReader make_FileReader(std::istream *s, const mpt::PathString *filename = nullptr) { return FileReader( FileDataContainerStdStreamSeekable::IsSeekable(s) ? std::static_pointer_cast(std::make_shared(s)) : std::static_pointer_cast(std::make_shared(s)) , filename ); } #endif // MPT_FILEREADER_STD_ISTREAM #endif // LIBOPENMT_BUILD #if defined(MPT_ENABLE_FILEIO) // templated in order to reduce header inter-dependencies template FileReader GetFileReader(TInputFile &file) { #if defined(MPT_FILEREADER_STD_ISTREAM) typename TInputFile::ContentsRef tmp = file.Get(); if(!tmp.first) { return FileReader(); } if(!tmp.first->good()) { return FileReader(); } return FileReader(tmp.first, tmp.second); #else typename TInputFile::ContentsRef tmp = file.Get(); return FileReader(mpt::as_span(tmp.first.data, tmp.first.size), tmp.second); #endif } #endif // MPT_ENABLE_FILEIO #if defined(MPT_ENABLE_TEMPFILE) && MPT_OS_WINDOWS class OnDiskFileWrapper { private: mpt::PathString m_Filename; bool m_IsTempFile; public: OnDiskFileWrapper(FileReader &file, const mpt::PathString &fileNameExtension = MPT_PATHSTRING("tmp")); ~OnDiskFileWrapper(); public: bool IsValid() const; mpt::PathString GetFilename() const; }; // class OnDiskFileWrapper #endif // MPT_ENABLE_TEMPFILE && MPT_OS_WINDOWS OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/mptFileIO.cpp0000644000372100037210000001703313161656666020126 00000000000000/* * mptFileIO.cpp * ------------- * Purpose: File I/O wrappers * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "mptFileIO.h" #ifdef MODPLUG_TRACKER #if MPT_OS_WINDOWS #include #include #endif // MPT_OS_WINDOWS #endif // MODPLUG_TRACKER OPENMPT_NAMESPACE_BEGIN #if defined(MPT_ENABLE_FILEIO) #ifdef MODPLUG_TRACKER #if MPT_OS_WINDOWS bool SetFilesystemCompression(HANDLE hFile) { if(hFile == INVALID_HANDLE_VALUE) { return false; } USHORT format = COMPRESSION_FORMAT_DEFAULT; DWORD dummy = 0; BOOL result = DeviceIoControl(hFile, FSCTL_SET_COMPRESSION, (LPVOID)&format, sizeof(format), NULL, 0, &dummy /*required*/ , NULL); return result ? true : false; } bool SetFilesystemCompression(int fd) { if(fd < 0) { return false; } uintptr_t fhandle = _get_osfhandle(fd); HANDLE hFile = (HANDLE)fhandle; if(hFile == INVALID_HANDLE_VALUE) { return false; } return SetFilesystemCompression(hFile); } #if defined(MPT_ENABLE_FILEIO_STDIO) bool SetFilesystemCompression(FILE *file) { if(!file) { return false; } int fd = _fileno(file); if(fd == -1) { return false; } return SetFilesystemCompression(fd); } #endif // MPT_ENABLE_FILEIO_STDIO bool SetFilesystemCompression(const mpt::PathString &filename) { DWORD attributes = GetFileAttributesW(filename.AsNativePrefixed().c_str()); if(attributes == INVALID_FILE_ATTRIBUTES) { return false; } if(attributes & FILE_ATTRIBUTE_COMPRESSED) { return true; } HANDLE hFile = CreateFileW(filename.AsNativePrefixed().c_str(), GENERIC_ALL, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); if(hFile == INVALID_HANDLE_VALUE) { return false; } bool result = SetFilesystemCompression(hFile); CloseHandle(hFile); hFile = INVALID_HANDLE_VALUE; return result; } #endif // MPT_OS_WINDOWS #endif // MODPLUG_TRACKER namespace mpt { LazyFileRef & LazyFileRef::operator = (const std::vector &data) { mpt::ofstream file(m_Filename, std::ios::binary); file.exceptions(std::ios_base::failbit | std::ios_base::badbit); mpt::IO::WriteRaw(file, data.data(), data.size()); mpt::IO::Flush(file); return *this; } LazyFileRef & LazyFileRef::operator = (const std::vector &data) { mpt::ofstream file(m_Filename, std::ios::binary); file.exceptions(std::ios_base::failbit | std::ios_base::badbit); mpt::IO::WriteRaw(file, data.data(), data.size()); mpt::IO::Flush(file); return *this; } LazyFileRef & LazyFileRef::operator = (const std::string &data) { mpt::ofstream file(m_Filename, std::ios::binary); file.exceptions(std::ios_base::failbit | std::ios_base::badbit); mpt::IO::WriteRaw(file, data.data(), data.size()); mpt::IO::Flush(file); return *this; } LazyFileRef::operator std::vector () const { mpt::ifstream file(m_Filename, std::ios::binary); if(!mpt::IO::IsValid(file)) { return std::vector(); } file.exceptions(std::ios_base::failbit | std::ios_base::badbit); mpt::IO::SeekEnd(file); std::vector buf(mpt::saturate_cast(mpt::IO::TellRead(file))); mpt::IO::SeekBegin(file); mpt::IO::ReadRaw(file, buf.data(), buf.size()); return buf; } LazyFileRef::operator std::vector () const { mpt::ifstream file(m_Filename, std::ios::binary); if(!mpt::IO::IsValid(file)) { return std::vector(); } file.exceptions(std::ios_base::failbit | std::ios_base::badbit); mpt::IO::SeekEnd(file); std::vector buf(mpt::saturate_cast(mpt::IO::TellRead(file))); mpt::IO::SeekBegin(file); mpt::IO::ReadRaw(file, buf.data(), buf.size()); return buf; } LazyFileRef::operator std::string () const { mpt::ifstream file(m_Filename, std::ios::binary); if(!mpt::IO::IsValid(file)) { return std::string(); } file.exceptions(std::ios_base::failbit | std::ios_base::badbit); mpt::IO::SeekEnd(file); std::vector buf(mpt::saturate_cast(mpt::IO::TellRead(file))); mpt::IO::SeekBegin(file); mpt::IO::ReadRaw(file, buf.data(), buf.size()); return std::string(buf.begin(), buf.end()); } } // namespace mpt #ifdef MODPLUG_TRACKER #if MPT_OS_WINDOWS CMappedFile::~CMappedFile() { Close(); } bool CMappedFile::Open(const mpt::PathString &filename) { m_hFile = CreateFileW( filename.AsNativePrefixed().c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(m_hFile == INVALID_HANDLE_VALUE) { m_hFile = nullptr; return false; } m_FileName = filename; return true; } void CMappedFile::Close() { m_FileName = mpt::PathString(); // Unlock file if(m_hFMap) { if(m_pData) { UnmapViewOfFile(m_pData); m_pData = nullptr; } CloseHandle(m_hFMap); m_hFMap = nullptr; } else if(m_pData) { free(m_pData); m_pData = nullptr; } // Close file handle if(m_hFile) { CloseHandle(m_hFile); m_hFile = nullptr; } } size_t CMappedFile::GetLength() { LARGE_INTEGER size; if(GetFileSizeEx(m_hFile, &size) == FALSE) { return 0; } return mpt::saturate_cast(size.QuadPart); } const mpt::byte *CMappedFile::Lock() { size_t length = GetLength(); if(!length) return nullptr; void *lpStream; HANDLE hmf = CreateFileMapping( m_hFile, NULL, PAGE_READONLY, 0, 0, NULL); // Try memory-mapping first if(hmf) { lpStream = MapViewOfFile( hmf, FILE_MAP_READ, 0, 0, length); if(lpStream) { m_hFMap = hmf; m_pData = lpStream; return mpt::void_cast(lpStream); } CloseHandle(hmf); hmf = nullptr; } // Fallback if memory-mapping fails for some weird reason if((lpStream = malloc(length)) == nullptr) return nullptr; memset(lpStream, 0, length); size_t bytesToRead = length; size_t bytesRead = 0; while(bytesToRead > 0) { DWORD chunkToRead = mpt::saturate_cast(length); DWORD chunkRead = 0; if(ReadFile(m_hFile, mpt::void_cast(lpStream) + bytesRead, chunkToRead, &chunkRead, NULL) == FALSE) { // error free(lpStream); return nullptr; } bytesRead += chunkRead; bytesToRead -= chunkRead; } m_pData = lpStream; return mpt::void_cast(lpStream); } #endif // MPT_OS_WINDOWS #endif // MODPLUG_TRACKER InputFile::InputFile() { return; } InputFile::InputFile(const mpt::PathString &filename) : m_Filename(filename) { #if defined(MPT_FILEREADER_STD_ISTREAM) m_File.open(m_Filename, std::ios::binary | std::ios::in); #else m_File.Open(m_Filename); #endif } InputFile::~InputFile() { return; } bool InputFile::Open(const mpt::PathString &filename) { m_Filename = filename; #if defined(MPT_FILEREADER_STD_ISTREAM) m_File.open(m_Filename, std::ios::binary | std::ios::in); return m_File.good(); #else return m_File.Open(m_Filename); #endif } bool InputFile::IsValid() const { #if defined(MPT_FILEREADER_STD_ISTREAM) return m_File.good(); #else return m_File.IsOpen(); #endif } #if defined(MPT_FILEREADER_STD_ISTREAM) InputFile::ContentsRef InputFile::Get() { InputFile::ContentsRef result; result.first = &m_File; result.second = m_File.good() ? &m_Filename : nullptr; return result; } #else InputFile::ContentsRef InputFile::Get() { InputFile::ContentsRef result; result.first.data = nullptr; result.first.size = 0; result.second = nullptr; if(!m_File.IsOpen()) { return result; } result.first.data = m_File.Lock(); result.first.size = m_File.GetLength(); result.second = &m_Filename; return result; } #endif #else // !MPT_ENABLE_FILEIO MPT_MSVC_WORKAROUND_LNK4221(mptFileIO) #endif // MPT_ENABLE_FILEIO OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/mptUUID.h0000644000372100037210000001006313074146275017217 00000000000000/* * mptUUID.h * --------- * Purpose: UUID utility functions. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "Endianness.h" #if MPT_OS_WINDOWS #if defined(MODPLUG_TRACKER) || !defined(NO_DMO) #include #include #endif // MODPLUG_TRACKER || !NO_DMO #endif // MPT_OS_WINDOWS OPENMPT_NAMESPACE_BEGIN #if MPT_OS_WINDOWS namespace Util { #if defined(MODPLUG_TRACKER) || !defined(NO_DMO) // COM CLSID<->string conversion // A CLSID string is not necessarily a standard UUID string, // it might also be a symbolic name for the interface. // (see CLSIDFromString ( http://msdn.microsoft.com/en-us/library/windows/desktop/ms680589%28v=vs.85%29.aspx )) std::wstring CLSIDToString(CLSID clsid); CLSID StringToCLSID(const std::wstring &str); bool VerifyStringToCLSID(const std::wstring &str, CLSID &clsid); bool IsCLSID(const std::wstring &str); // COM IID<->string conversion IID StringToIID(const std::wstring &str); std::wstring IIDToString(IID iid); // General GUID<->string conversion. // The string must/will be in standard GUID format: {4F9A455D-E7EF-4367-B2F0-0C83A38A5C72} GUID StringToGUID(const std::wstring &str); std::wstring GUIDToString(GUID guid); // Create a COM GUID GUID CreateGUID(); #if !MPT_OS_WINDOWS_WINRT // General UUID<->string conversion. // The string must/will be in standard UUID format: 4f9a455d-e7ef-4367-b2f0-0c83a38a5c72 UUID StringToUUID(const mpt::ustring &str); mpt::ustring UUIDToString(UUID uuid); #endif // !MPT_OS_WINDOWS_WINRT // Checks the UUID against the NULL UUID. Returns false if it is NULL, true otherwise. bool IsValid(UUID uuid); #endif // MODPLUG_TRACKER || !NO_DMO } // namespace Util #endif // MPT_OS_WINDOWS // Microsoft on-disk layout struct GUIDms { uint32le Data1; uint16le Data2; uint16le Data3; uint64be Data4; // yes, big endian here }; STATIC_ASSERT(sizeof(GUIDms) == 16); namespace mpt { struct UUID { private: uint32be Data1; uint16be Data2; uint16be Data3; uint64be Data4; public: uint32 GetData1() const; uint16 GetData2() const; uint16 GetData3() const; uint64 GetData4() const; public: // xxxxxxxx-xxxx-Mmxx-Nnxx-xxxxxxxxxxxx // <--32-->-<16>-<16>-<-------64------> bool IsNil() const; bool IsValid() const; uint8 Variant() const; uint8 Version() const; bool IsRFC4122() const; private: uint8 Mm() const; uint8 Nn() const; void MakeRFC4122(uint8 version); public: #if MPT_OS_WINDOWS && (defined(MODPLUG_TRACKER) || !defined(NO_DMO)) explicit UUID(::UUID uuid); operator ::UUID () const; static UUID FromGroups(uint32 group1, uint16 group2, uint16 group3, uint16 group4, uint64 group5); #define MPT_UUID_HELPER( prefix , value , suffix ) ( prefix ## value ## suffix ) #define MPT_UUID(group1, group2, group3, group4, group5) mpt::UUID::FromGroups(MPT_UUID_HELPER(0x,group1,u), MPT_UUID_HELPER(0x,group2,u), MPT_UUID_HELPER(0x,group3,u), MPT_UUID_HELPER(0x,group4,u), MPT_UUID_HELPER(0x,group5,ull)) #endif // MPT_OS_WINDOWS && (MODPLUG_TRACKER || !NO_DMO) public: UUID(); explicit UUID(uint32 Data1, uint16 Data2, uint16 Data3, uint64 Data4); explicit UUID(GUIDms guid); operator GUIDms () const; friend bool operator==(const mpt::UUID & a, const mpt::UUID & b); friend bool operator!=(const mpt::UUID & a, const mpt::UUID & b); public: // Create a UUID static UUID Generate(); // Create a UUID that contains local, traceable information. // Safe for local use. May be faster. static UUID GenerateLocalUseOnly(); // Create a RFC4122 Random UUID. static UUID RFC4122Random(); public: // General UUID<->string conversion. // The string must/will be in standard UUID format: 4f9a455d-e7ef-4367-b2f0-0c83a38a5c72 static UUID FromString(const std::string &str); static UUID FromString(const mpt::ustring &str); std::string ToString() const; mpt::ustring ToUString() const; }; STATIC_ASSERT(sizeof(mpt::UUID) == 16); bool operator==(const mpt::UUID & a, const mpt::UUID & b); bool operator!=(const mpt::UUID & a, const mpt::UUID & b); } // namespace mpt OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/Logging.cpp0000644000372100037210000002270013161656666017661 00000000000000/* * Logging.cpp * ----------- * Purpose: General logging * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Logging.h" #include "mptFileIO.h" #if defined(MODPLUG_TRACKER) #include #endif #include "version.h" #include #include #include #include OPENMPT_NAMESPACE_BEGIN namespace mpt { namespace log { #ifndef NO_LOGGING #if !defined(MPT_LOG_GLOBAL_LEVEL_STATIC) #if defined(MPT_LOG_GLOBAL_LEVEL) int GlobalLogLevel = static_cast(MPT_LOG_GLOBAL_LEVEL); #else int GlobalLogLevel = static_cast(LogDebug); #endif #endif #if defined(MODPLUG_TRACKER) && !defined(MPT_LOG_IS_DISABLED) bool FileEnabled = false; bool DebuggerEnabled = true; bool ConsoleEnabled = false; static char g_FacilitySolo[1024] = {0}; static char g_FacilityBlocked[1024] = {0}; void SetFacilities(const std::string &solo, const std::string &blocked) { std::strcpy(g_FacilitySolo, solo.c_str()); std::strcpy(g_FacilityBlocked, blocked.c_str()); } bool IsFacilityActive(const char *facility) { if(facility) { if(std::strlen(g_FacilitySolo) > 0) { if(std::strcmp(facility, g_FacilitySolo) != 0) { return false; } } if(std::strlen(g_FacilityBlocked) > 0) { if(std::strcmp(facility, g_FacilitySolo) == 0) { return false; } } } return true; } #endif void Logger::SendLogMessage(const Context &context, LogLevel level, const char *facility, const mpt::ustring &text) { #ifdef MPT_LOG_IS_DISABLED MPT_UNREFERENCED_PARAMETER(context); MPT_UNREFERENCED_PARAMETER(level); MPT_UNREFERENCED_PARAMETER(facility); MPT_UNREFERENCED_PARAMETER(text); #else // !MPT_LOG_IS_DISABLED MPT_MAYBE_CONSTANT_IF(mpt::log::GlobalLogLevel < level) { return; } #if defined(MODPLUG_TRACKER) if(!IsFacilityActive(facility)) { return; } #else // !MODPLUG_TRACKER MPT_UNREFERENCED_PARAMETER(facility); #endif // MODPLUG_TRACKER // remove eol if already present and add log level prefix const mpt::ustring message = LogLevelToString(level) + MPT_USTRING(": ") + mpt::String::RTrim(text, MPT_USTRING("\r\n")); const mpt::ustring file = mpt::ToUnicode(mpt::CharsetASCII, context.file); const mpt::ustring function = mpt::ToUnicode(mpt::CharsetASCII, context.function); const mpt::ustring line = mpt::ufmt::dec(context.line); #if defined(MODPLUG_TRACKER) && !defined(MPT_BUILD_WINESUPPORT) #if MPT_OS_WINDOWS static uint64 s_lastlogtime = 0; uint64 cur = mpt::Date::ANSI::Now(); uint64 diff = cur/10000 - s_lastlogtime; s_lastlogtime = cur/10000; #else uint64 cur = 0; uint64 diff = 0; #endif if(mpt::log::FileEnabled) { static FILE * s_logfile = nullptr; if(!s_logfile) { s_logfile = mpt_fopen(MPT_PATHSTRING("mptrack.log"), "a"); } if(s_logfile) { fprintf(s_logfile, mpt::ToCharset(mpt::CharsetUTF8, mpt::format(MPT_USTRING("%1+%2 %3(%4): %5 [%6]\n")) ( mpt::Date::ANSI::ToString(cur) , mpt::ufmt::dec<6>(diff) , file , line , message , function )).c_str()); fflush(s_logfile); } } if(mpt::log::DebuggerEnabled) { OutputDebugStringW(mpt::ToWide(mpt::format(MPT_USTRING("%1(%2): +%3 %4 [%5]\n")) ( file , line , mpt::ufmt::dec<6>(diff) , message , function )).c_str()); } if(mpt::log::ConsoleEnabled) { static bool consoleInited = false; if(!consoleInited) { AllocConsole(); consoleInited = true; } std::wstring consoletext = mpt::ToWide(message) + L"\r\n"; DWORD dummy = 0; WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), consoletext.c_str(), consoletext.length(), &dummy, NULL); } #elif defined(MODPLUG_TRACKER) && defined(MPT_BUILD_WINESUPPORT) std::clog << "NativeSupport: " << mpt::ToCharset(mpt::CharsetLocaleOrUTF8, file) << "(" << mpt::ToCharset(mpt::CharsetLocaleOrUTF8, line) << ")" << ": " << mpt::ToCharset(mpt::CharsetLocaleOrUTF8, message) << " [" << mpt::ToCharset(mpt::CharsetLocaleOrUTF8, function) << "]" << std::endl; #else // !MODPLUG_TRACKER std::clog << "libopenmpt: " << mpt::ToCharset(mpt::CharsetLocaleOrUTF8, file) << "(" << mpt::ToCharset(mpt::CharsetLocaleOrUTF8, line) << ")" << ": " << mpt::ToCharset(mpt::CharsetLocaleOrUTF8, message) << " [" << mpt::ToCharset(mpt::CharsetLocaleOrUTF8, function) << "]" << std::endl; #endif // MODPLUG_TRACKER #endif // MPT_LOG_IS_DISABLED } void LegacyLogger::operator () (const AnyStringLocale &text) { SendLogMessage(context, MPT_LEGACY_LOGLEVEL, "", text); } void LegacyLogger::operator () (const char *format, ...) { static const std::size_t LOGBUF_SIZE = 1024; char message[LOGBUF_SIZE]; va_list va; va_start(va, format); vsnprintf(message, LOGBUF_SIZE, format, va); va_end(va); message[LOGBUF_SIZE - 1] = '\0'; SendLogMessage(context, MPT_LEGACY_LOGLEVEL, "", mpt::ToUnicode(mpt::CharsetLocaleOrUTF8, message)); } void LegacyLogger::operator () (LogLevel level, const mpt::ustring &text) { SendLogMessage(context, level, "", text); } #endif // !NO_LOGGING #if defined(MODPLUG_TRACKER) namespace Trace { #if MPT_OS_WINDOWS // Debugging functionality will use simple globals. bool volatile g_Enabled = false; static bool g_Sealed = false; struct Entry { uint32 Index; uint32 ThreadId; uint64 Timestamp; const char * Function; const char * File; int Line; }; inline bool operator < (const Entry &a, const Entry &b) { /* return false || (a.Timestamp < b.Timestamp) || (a.ThreadID < b.ThreadID) || (a.File < b.File) || (a.Line < b.Line) || (a.Function < b.Function) ; */ return false || (a.Index < b.Index) ; } static std::vector Entries; static std::atomic NextIndex(0); static uint32 ThreadIdGUI = 0; static uint32 ThreadIdAudio = 0; static uint32 ThreadIdNotify = 0; void Enable(std::size_t numEntries) { if(g_Sealed) { return; } Entries.clear(); Entries.resize(numEntries); NextIndex.store(0); g_Enabled = true; } void Disable() { if(g_Sealed) { return; } g_Enabled = false; } MPT_NOINLINE void Trace(const mpt::log::Context & context) { // This will get called in realtime contexts and hot paths. // No blocking allowed here. const uint32 index = NextIndex.fetch_add(1); #if 1 LARGE_INTEGER time; time.QuadPart = 0; QueryPerformanceCounter(&time); const uint64 timestamp = time.QuadPart; #else FILETIME time = FILETIME(); GetSystemTimeAsFileTime(&time); const uint64 timestamp = (static_cast(time.dwHighDateTime) << 32) | (static_cast(time.dwLowDateTime) << 0); #endif const uint32 threadid = static_cast(GetCurrentThreadId()); mpt::log::Trace::Entry & entry = Entries[index % Entries.size()]; entry.Index = index; entry.ThreadId = threadid; entry.Timestamp = timestamp; entry.Function = context.function; entry.File = context.file; entry.Line = context.line; } void Seal() { if(!g_Enabled) { return; } g_Enabled = false; g_Sealed = true; uint32 count = NextIndex.fetch_add(0); if(count < Entries.size()) { Entries.resize(count); } } bool Dump(const mpt::PathString &filename) { if(!g_Sealed) { return false; } LARGE_INTEGER qpcNow; qpcNow.QuadPart = 0; QueryPerformanceCounter(&qpcNow); uint64 ftNow = mpt::Date::ANSI::Now(); // sort according to index in case of overflows std::stable_sort(Entries.begin(), Entries.end()); mpt::ofstream f(filename, std::ios::out); f << "Build: OpenMPT " << MptVersion::GetVersionStringExtended() << std::endl; bool qpcValid = false; LARGE_INTEGER qpcFreq; qpcFreq.QuadPart = 0; QueryPerformanceFrequency(&qpcFreq); if(qpcFreq.QuadPart > 0) { qpcValid = true; } f << "Dump: " << mpt::ToCharset(mpt::CharsetUTF8, mpt::Date::ANSI::ToString(ftNow)) << std::endl; f << "Captured events: " << Entries.size() << std::endl; if(qpcValid && (Entries.size() > 0)) { double period = static_cast(Entries[Entries.size() - 1].Timestamp - Entries[0].Timestamp) / static_cast(qpcFreq.QuadPart); double eventsPerSecond = Entries.size() / period; f << "Period [s]: " << mpt::fmt::fix(period) << std::endl; f << "Events/second: " << mpt::fmt::fix(eventsPerSecond) << std::endl; } for(std::size_t i = 0; i < Entries.size(); ++i) { mpt::log::Trace::Entry & entry = Entries[i]; if(!entry.Function) entry.Function = ""; if(!entry.File) entry.File = ""; std::string time; if(qpcValid) { time = mpt::ToCharset(mpt::CharsetUTF8, mpt::Date::ANSI::ToString( ftNow - static_cast( static_cast(qpcNow.QuadPart - entry.Timestamp) * (10000000.0 / static_cast(qpcFreq.QuadPart) ) ) ) ); } else { time = mpt::format("0x%1")(mpt::fmt::hex0<16>(entry.Timestamp)); } f << time; if(entry.ThreadId == ThreadIdGUI) { f << " -----GUI "; } else if(entry.ThreadId == ThreadIdAudio) { f << " ---Audio "; } else if(entry.ThreadId == ThreadIdNotify) { f << " --Notify "; } else { f << " " << mpt::fmt::hex0<8>(entry.ThreadId) << " "; } f << entry.File << "(" << entry.Line << "): " << entry.Function; f << std::endl; } return true; } void SetThreadId(mpt::log::Trace::ThreadKind kind, uint32 id) { if(id == 0) { return; } switch(kind) { case ThreadKindGUI: ThreadIdGUI = id; break; case ThreadKindAudio: ThreadIdAudio = id; break; case ThreadKindNotify: ThreadIdNotify = id; break; } } #endif // MPT_OS_WINDOWS } // namespace Trace #endif // MODPLUG_TRACKER } // namespace log } // namespace mpt OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/serialization_utils.h0000644000372100037210000003511313161656666022037 00000000000000/* * serialization_utils.h * --------------------- * Purpose: Serializing data to and from MPTM files. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "../common/typedefs.h" #include "../common/mptTypeTraits.h" #include "../common/mptIO.h" #include "../common/Endianness.h" #include #include #include #include #include #include #include #include #include #include OPENMPT_NAMESPACE_BEGIN namespace srlztn //SeRiaLiZaTioN { typedef std::ios::off_type Offtype; typedef Offtype Postype; typedef uintptr_t DataSize; // Data size type. typedef uintptr_t RposType; // Relative position type. typedef uintptr_t NumType; // Entry count type. const DataSize invalidDatasize = DataSize(-1); enum { SNT_PROGRESS = 0x08000000, // = 1 << 27 SNT_FAILURE = 0x40000000, // = 1 << 30 SNT_NOTE = 0x20000000, // = 1 << 29 SNT_WARNING = 0x10000000, // = 1 << 28 SNT_NONE = 0, SNRW_BADGIVEN_STREAM = 1 | SNT_FAILURE, // Read failures. SNR_BADSTREAM_AFTER_MAPHEADERSEEK = 2 | SNT_FAILURE, SNR_STARTBYTE_MISMATCH = 3 | SNT_FAILURE, SNR_BADSTREAM_AT_MAP_READ = 4 | SNT_FAILURE, SNR_INSUFFICIENT_STREAM_OFFTYPE = 5 | SNT_FAILURE, SNR_OBJECTCLASS_IDMISMATCH = 6 | SNT_FAILURE, SNR_TOO_MANY_ENTRIES_TO_READ = 7 | SNT_FAILURE, SNR_INSUFFICIENT_RPOSTYPE = 8 | SNT_FAILURE, // Read notes and warnings. SNR_ZEROENTRYCOUNT = 0x80 | SNT_NOTE, // 0x80 == 1 << 7 SNR_NO_ENTRYIDS_WITH_CUSTOMID_DEFINED = 0x100 | SNT_NOTE, SNR_LOADING_OBJECT_WITH_LARGER_VERSION = 0x200 | SNT_NOTE, // Write failures. SNW_INSUFFICIENT_FIXEDSIZE = (0x10) | SNT_FAILURE, SNW_CHANGING_IDSIZE_WITH_FIXED_IDSIZESETTING = (0x11) | SNT_FAILURE, SNW_DATASIZETYPE_OVERFLOW = (0x13) | SNT_FAILURE, SNW_MAX_WRITE_COUNT_REACHED = (0x14) | SNT_FAILURE, SNW_INSUFFICIENT_DATASIZETYPE = (0x16) | SNT_FAILURE }; enum { IdSizeVariable = uint16_max, IdSizeMaxFixedSize = (uint8_max >> 1) }; typedef int32 SsbStatus; struct ReadEntry { ReadEntry() : nIdpos(0), rposStart(0), nSize(invalidDatasize), nIdLength(0) {} uintptr_t nIdpos; // Index of id start in ID array. RposType rposStart; // Entry start position. DataSize nSize; // Entry size. uint16 nIdLength; // Length of id. }; enum Rwf { RwfWMapStartPosEntry, // Write. True to include data start pos entry to map. RwfWMapSizeEntry, // Write. True to include data size entry to map. RwfWMapDescEntry, // Write. True to include description entry to map. RwfWVersionNum, // Write. True to include version numeric. RwfRMapCached, // Read. True if map has been cached. RwfRMapHasId, // Read. True if map has IDs RwfRMapHasStartpos, // Read. True if map data start pos. RwfRMapHasSize, // Read. True if map has entry size. RwfRMapHasDesc, // Read. True if map has entry description. RwfRTwoBytesDescChar, // Read. True if map description characters are two bytes. RwfRHeaderIsRead, // Read. True when header is read. RwfRwHasMap, // Read/write. True if map exists. RwfNumFlags }; template inline void Binarywrite(std::ostream& oStrm, const T& data) { mpt::IO::WriteIntLE(oStrm, data); } template<> inline void Binarywrite(std::ostream& oStrm, const float& data) { IEEE754binary32LE tmp = IEEE754binary32LE(data); mpt::IO::Write(oStrm, tmp); } template<> inline void Binarywrite(std::ostream& oStrm, const double& data) { IEEE754binary64LE tmp = IEEE754binary64LE(data); mpt::IO::Write(oStrm, tmp); } template inline void WriteItem(std::ostream& oStrm, const T& data) { static_assert(std::is_trivial::value == true, ""); Binarywrite(oStrm, data); } void WriteItemString(std::ostream& oStrm, const std::string &str); template <> inline void WriteItem(std::ostream& oStrm, const std::string& str) {WriteItemString(oStrm, str);} template inline void Binaryread(std::istream& iStrm, T& data) { mpt::IO::ReadIntLE(iStrm, data); } template<> inline void Binaryread(std::istream& iStrm, float& data) { IEEE754binary32LE tmp = IEEE754binary32LE(0.0f); mpt::IO::Read(iStrm, tmp); data = tmp; } template<> inline void Binaryread(std::istream& iStrm, double& data) { IEEE754binary64LE tmp = IEEE754binary64LE(0.0); mpt::IO::Read(iStrm, tmp); data = tmp; } //Read only given number of bytes to the beginning of data; data bytes are memset to 0 before reading. template inline void Binaryread(std::istream& iStrm, T& data, const Offtype bytecount) { mpt::IO::ReadBinaryTruncatedLE(iStrm, data, static_cast(bytecount)); } template <> inline void Binaryread(std::istream& iStrm, float& data, const Offtype bytecount) { typedef IEEE754binary32LE T; mpt::byte bytes[sizeof(T)]; std::memset(bytes, 0, sizeof(T)); mpt::IO::ReadRaw(iStrm, bytes, std::min(static_cast(bytecount), sizeof(T))); // There is not much we can sanely do for truncated floats, // thus we ignore what we just read and return 0. data = 0.0f; } template <> inline void Binaryread(std::istream& iStrm, double& data, const Offtype bytecount) { typedef IEEE754binary64LE T; mpt::byte bytes[sizeof(T)]; std::memset(bytes, 0, sizeof(T)); mpt::IO::ReadRaw(iStrm, bytes, std::min(static_cast(bytecount), sizeof(T))); // There is not much we can sanely do for truncated floats, // thus we ignore what we just read and return 0. data = 0.0; } template inline void ReadItem(std::istream& iStrm, T& data, const DataSize nSize) { static_assert(std::is_trivial::value == true, ""); if (nSize == sizeof(T) || nSize == invalidDatasize) Binaryread(iStrm, data); else Binaryread(iStrm, data, nSize); } void ReadItemString(std::istream& iStrm, std::string& str, const DataSize); template <> inline void ReadItem(std::istream& iStrm, std::string& str, const DataSize nSize) { ReadItemString(iStrm, str, nSize); } class ID { private: std::string m_ID; // NOTE: can contain null characters ('\0') public: ID() { } ID(const std::string &id) : m_ID(id) { } ID(const char *beg, const char *end) : m_ID(beg, end) { } ID(const char *id) : m_ID(id?id:"") { } ID(const char * str, std::size_t len) : m_ID(str, str + len) { } template static ID FromInt(const T &val) { STATIC_ASSERT(std::numeric_limits::is_integer); typename mpt::make_le::type valle; valle = val; return ID(std::string(mpt::as_raw_memory(valle), mpt::as_raw_memory(valle) + sizeof(valle))); } bool IsPrintable() const; mpt::ustring AsString() const; const char *GetBytes() const { return m_ID.c_str(); } std::size_t GetSize() const { return m_ID.length(); } bool operator == (const ID &other) const { return m_ID == other.m_ID; } bool operator != (const ID &other) const { return m_ID != other.m_ID; } }; class Ssb { protected: Ssb(); public: SsbStatus GetStatus() const { return m_Status; } protected: // When writing, returns the number of entries written. // When reading, returns the number of entries read not including unrecognized entries. NumType GetCounter() const {return m_nCounter;} void SetFlag(Rwf flag, bool val) {m_Flags.set(flag, val);} bool GetFlag(Rwf flag) const {return m_Flags[flag];} protected: SsbStatus m_Status; uint32 m_nFixedEntrySize; // Read/write: If > 0, data entries have given fixed size. Postype m_posStart; // Read/write: Stream position at the beginning of object. uint16 m_nIdbytes; // Read/Write: Tells map ID entry size in bytes. If size is variable, value is IdSizeVariable. NumType m_nCounter; // Read/write: Keeps count of entries written/read. std::bitset m_Flags; // Read/write: Various flags. protected: static const uint8 s_DefaultFlagbyte = 0; static const char s_EntryID[3]; }; class SsbRead : public Ssb { public: enum ReadRv // Read return value. { EntryRead, EntryNotFound }; enum IdMatchStatus { IdMatch, IdMismatch }; typedef std::vector::const_iterator ReadIterator; SsbRead(std::istream& iStrm); // Call this to begin reading: must be called before other read functions. void BeginRead(const ID &id, const uint64& nVersion); // After calling BeginRead(), this returns number of entries in the file. NumType GetNumEntries() const {return m_nReadEntrycount;} // Returns read iterator to the beginning of entries. // The behaviour of read iterators is undefined if map doesn't // contain entry ids or data begin positions. ReadIterator GetReadBegin(); // Returns read iterator to the end(one past last) of entries. ReadIterator GetReadEnd(); // Compares given id with read entry id IdMatchStatus CompareId(const ReadIterator& iter, const ID &id); uint64 GetReadVersion() {return m_nReadVersion;} // Read item using default read implementation. template ReadRv ReadItem(T& obj, const ID &id) {return ReadItem(obj, id, srlztn::ReadItem);} // Read item using given function. template ReadRv ReadItem(T& obj, const ID &id, FuncObj); // Read item using read iterator. template ReadRv ReadIterItem(const ReadIterator& iter, T& obj) {return ReadIterItem(iter, obj, srlztn::ReadItem);} template ReadRv ReadIterItem(const ReadIterator& iter, T& obj, FuncObj func); private: // Reads map to cache. void CacheMap(); // Searches for entry with given ID. If found, returns pointer to corresponding entry, else // returns nullptr. const ReadEntry* Find(const ID &id); // Called after reading an object. ReadRv OnReadEntry(const ReadEntry* pE, const ID &id, const Postype& posReadBegin); void AddReadNote(const SsbStatus s); // Called after reading entry. pRe is a pointer to associated map entry if exists. void AddReadNote(const ReadEntry* const pRe, const NumType nNum); void ResetReadstatus(); private: // mapData is a cache that facilitates faster access to the stored data // without having to reparse on every access. // Iterator invalidation in CacheMap() is not a problem because every code // path that ever returns an iterator into mapData does CacheMap exactly once // beforehand. Following calls use this already cached map. As the data is // immutable when reading, there is no need to ever invalidate the cache and // redo CacheMap(). std::istream* m_pIstrm; // Read: Pointer to read stream. std::vector m_Idarray; // Read: Holds entry ids. std::vector mapData; // Read: Contains map information. uint64 m_nReadVersion; // Read: Version is placed here when reading. RposType m_rposMapBegin; // Read: If map exists, rpos of map begin, else m_rposEndofHdrData. Postype m_posMapEnd; // Read: If map exists, map end position, else pos of end of hdrData. Postype m_posDataBegin; // Read: Data begin position. RposType m_rposEndofHdrData; // Read: rpos of end of header data. NumType m_nReadEntrycount; // Read: Number of entries. NumType m_nNextReadHint; // Read: Hint where to start looking for the next read entry. }; class SsbWrite : public Ssb { public: SsbWrite(std::ostream& oStrm); // Write header void BeginWrite(const ID &id, const uint64& nVersion); // Write item using default write implementation. template void WriteItem(const T& obj, const ID &id) {WriteItem(obj, id, &srlztn::WriteItem);} // Write item using given function. template void WriteItem(const T& obj, const ID &id, FuncObj); // Writes mapping. void FinishWrite(); private: // Called after writing an item. void OnWroteItem(const ID &id, const Postype& posBeforeWrite); void AddWriteNote(const SsbStatus s); void AddWriteNote(const ID &id, const NumType nEntryNum, const DataSize nBytecount, const RposType rposStart); // Writes mapping item to mapstream. void WriteMapItem(const ID &id, const RposType& rposDataStart, const DataSize& nDatasize, const char* pszDesc); void ResetWritestatus() {m_Status = SNT_NONE;} void IncrementWriteCounter(); private: std::ostream* m_pOstrm; // Write: Pointer to write stream. Postype m_posEntrycount; // Write: Pos of entrycount field. Postype m_posMapPosField; // Write: Pos of map position field. std::string m_MapStreamString; // Write: Map stream string. }; template void SsbWrite::WriteItem(const T& obj, const ID &id, FuncObj Func) { const Postype pos = m_pOstrm->tellp(); Func(*m_pOstrm, obj); OnWroteItem(id, pos); } template SsbRead::ReadRv SsbRead::ReadItem(T& obj, const ID &id, FuncObj Func) { const ReadEntry* pE = Find(id); const Postype pos = m_pIstrm->tellg(); if (pE != nullptr || GetFlag(RwfRMapHasId) == false) Func(*m_pIstrm, obj, (pE) ? (pE->nSize) : invalidDatasize); return OnReadEntry(pE, id, pos); } template SsbRead::ReadRv SsbRead::ReadIterItem(const ReadIterator& iter, T& obj, FuncObj func) { m_pIstrm->clear(); if (iter->rposStart != 0) m_pIstrm->seekg(m_posStart + Postype(iter->rposStart)); const Postype pos = m_pIstrm->tellg(); func(*m_pIstrm, obj, iter->nSize); return OnReadEntry(&(*iter), ID(&m_Idarray[iter->nIdpos], iter->nIdLength), pos); } inline SsbRead::IdMatchStatus SsbRead::CompareId(const ReadIterator& iter, const ID &id) { if(iter->nIdpos >= m_Idarray.size()) return IdMismatch; return (id == ID(&m_Idarray[iter->nIdpos], iter->nIdLength)) ? IdMatch : IdMismatch; } inline SsbRead::ReadIterator SsbRead::GetReadBegin() { MPT_ASSERT(GetFlag(RwfRMapHasId) && (GetFlag(RwfRMapHasStartpos) || GetFlag(RwfRMapHasSize) || m_nFixedEntrySize > 0)); if (GetFlag(RwfRMapCached) == false) CacheMap(); return mapData.begin(); } inline SsbRead::ReadIterator SsbRead::GetReadEnd() { if (GetFlag(RwfRMapCached) == false) CacheMap(); return mapData.end(); } template struct VectorWriter { VectorWriter(size_t nCount) : m_nCount(nCount) {} void operator()(std::ostream &oStrm, const std::vector &vec) { for(size_t i = 0; i < m_nCount; i++) { Binarywrite(oStrm, vec[i]); } } size_t m_nCount; }; template struct VectorReader { VectorReader(size_t nCount) : m_nCount(nCount) {} void operator()(std::istream& iStrm, std::vector &vec, const size_t) { vec.resize(m_nCount); for(std::size_t i = 0; i < m_nCount; ++i) { Binaryread(iStrm, vec[i]); } } size_t m_nCount; }; template struct ArrayReader { ArrayReader(size_t nCount) : m_nCount(nCount) {} void operator()(std::istream& iStrm, T* pData, const size_t) { for(std::size_t i=0; isecond; } #endif // MPT_ENABLE_DYNBIND #if MPT_COMPONENT_MANAGER ComponentFactoryBase::ComponentFactoryBase(const std::string &id, const std::string &settingsKey) : m_ID(id) , m_SettingsKey(settingsKey) { return; } ComponentFactoryBase::~ComponentFactoryBase() { return; } std::string ComponentFactoryBase::GetID() const { return m_ID; } std::string ComponentFactoryBase::GetSettingsKey() const { return m_SettingsKey; } void ComponentFactoryBase::PreConstruct() const { MPT_LOG(LogInformation, "Components", mpt::format(MPT_USTRING("Constructing Component %1")) ( mpt::ToUnicode(mpt::CharsetASCII, m_ID) ) ); } void ComponentFactoryBase::Initialize(ComponentManager &componentManager, std::shared_ptr component) const { if(componentManager.IsComponentBlocked(GetSettingsKey())) { return; } componentManager.InitializeComponent(component); } // Global list of component register functions. // We do not use a global scope static list head because the corresponding // mutex would be no POD type and would thus not be safe to be usable in // zero-initialized state. // Function scope static initialization is guaranteed to be thread safe // in C++11. // We use this implementation to be future-proof. // MSVC currently does not exploit the possibility of using multiple threads // for global lifetime object's initialization. // An implementation with a simple global list head and no mutex at all would // thus work fine for MSVC (currently). static mpt::mutex & ComponentListMutex() { static mpt::mutex g_ComponentListMutex; return g_ComponentListMutex; } static ComponentListEntry * & ComponentListHead() { static ComponentListEntry *g_ComponentListHead = nullptr; return g_ComponentListHead; } bool ComponentListPush(ComponentListEntry *entry) { MPT_LOCK_GUARD guard(ComponentListMutex()); entry->next = ComponentListHead(); ComponentListHead() = entry; return true; } static std::shared_ptr g_ComponentManager; void ComponentManager::Init(const IComponentManagerSettings &settings) { MPT_LOG(LogInformation, "Components", MPT_USTRING("Init")); // cannot use make_shared because the constructor is private g_ComponentManager = std::shared_ptr(new ComponentManager(settings)); } void ComponentManager::Release() { MPT_LOG(LogInformation, "Components", MPT_USTRING("Release")); g_ComponentManager = nullptr; } std::shared_ptr ComponentManager::Instance() { return g_ComponentManager; } ComponentManager::ComponentManager(const IComponentManagerSettings &settings) : m_Settings(settings) { MPT_LOCK_GUARD guard(ComponentListMutex()); for(ComponentListEntry *entry = ComponentListHead(); entry; entry = entry->next) { entry->reg(*this); } } void ComponentManager::Register(const IComponentFactory &componentFactory) { if(m_Components.find(componentFactory.GetID()) != m_Components.end()) { return; } RegisteredComponent registeredComponent; registeredComponent.settingsKey = componentFactory.GetSettingsKey(); registeredComponent.factoryMethod = componentFactory.GetStaticConstructor(); registeredComponent.instance = nullptr; registeredComponent.weakInstance = std::weak_ptr(); m_Components.insert(std::make_pair(componentFactory.GetID(), registeredComponent)); } void ComponentManager::Startup() { MPT_LOG(LogDebug, "Components", MPT_USTRING("Startup")); if(m_Settings.LoadOnStartup()) { for(auto &it : m_Components) { it.second.instance = it.second.factoryMethod(*this); it.second.weakInstance = it.second.instance; } } if(!m_Settings.KeepLoaded()) { for(auto &it : m_Components) { it.second.instance = nullptr; } } } bool ComponentManager::IsComponentBlocked(const std::string &settingsKey) const { return m_Settings.IsBlocked(settingsKey); } void ComponentManager::InitializeComponent(std::shared_ptr component) const { if(!component) { return; } if(component->IsInitialized()) { return; } component->Initialize(); } std::shared_ptr ComponentManager::GetComponent(const IComponentFactory &componentFactory) { std::shared_ptr component = nullptr; auto it = m_Components.find(componentFactory.GetID()); if(it != m_Components.end()) { // registered component if((*it).second.instance) { // loaded component = (*it).second.instance; } else { // not loaded component = (*it).second.weakInstance.lock(); if(!component) { component = (*it).second.factoryMethod(*this); } if(m_Settings.KeepLoaded()) { // keep the component loaded (*it).second.instance = component; } (*it).second.weakInstance = component; } } else { // unregistered component component = componentFactory.Construct(*this); } MPT_ASSERT(component); return component; } std::shared_ptr ComponentManager::ReloadComponent(const IComponentFactory &componentFactory) { std::shared_ptr component = nullptr; auto it = m_Components.find(componentFactory.GetID()); if(it != m_Components.end()) { // registered component if((*it).second.instance) { // loaded (*it).second.instance = nullptr; if(!(*it).second.weakInstance.expired()) { throw std::runtime_error("Component not completely unloaded. Cannot reload."); } (*it).second.weakInstance = std::weak_ptr(); } // not loaded component = (*it).second.factoryMethod(*this); if(m_Settings.KeepLoaded()) { // keep the component loaded (*it).second.instance = component; } (*it).second.weakInstance = component; } else { // unregistered component component = componentFactory.Construct(*this); } MPT_ASSERT(component); return component; } std::vector ComponentManager::GetRegisteredComponents() const { std::vector result; result.reserve(m_Components.size()); for(const auto &it : m_Components) { result.push_back(it.first); } return result; } ComponentInfo ComponentManager::GetComponentInfo(std::string name) const { ComponentInfo result; result.name = name; result.state = ComponentStateUnregistered; result.settingsKey = ""; result.type = ComponentTypeUnknown; const auto it = m_Components.find(name); if(it == m_Components.end()) { result.state = ComponentStateUnregistered; return result; } result.settingsKey = it->second.settingsKey; if(IsComponentBlocked(it->second.settingsKey)) { result.state = ComponentStateBlocked; return result; } std::shared_ptr component = it->second.instance; if(!component) { component = it->second.weakInstance.lock(); } if(!component) { result.state = ComponentStateUnintialized; return result; } result.type = component->GetType(); if(!component->IsInitialized()) { result.state = ComponentStateUnintialized; return result; } if(!component->IsAvailable()) { result.state = ComponentStateUnavailable; return result; } result.state = ComponentStateAvailable; return result; } mpt::PathString ComponentManager::GetComponentPath() const { return m_Settings.Path(); } #endif // MPT_COMPONENT_MANAGER #endif // MPT_ENABLE_COMPONENTS OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/serialization_utils.cpp0000644000372100037210000005067713161656666022406 00000000000000/* * serialization_utils.cpp * ----------------------- * Purpose: Serializing data to and from MPTM files. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "serialization_utils.h" #include #include #include "misc_util.h" #include "mptBufferIO.h" OPENMPT_NAMESPACE_BEGIN namespace srlztn { //#define SSB_LOGGING #ifdef SSB_LOGGING #define SSB_LOG(x) Log(x) #else #define SSB_LOG(x) MPT_DO { } MPT_WHILE_0 #endif static const uint8 HeaderId_FlagByte = 0; // Indexing starts from 0. static inline bool Testbit(uint8 val, uint8 bitindex) {return ((val & (1 << bitindex)) != 0);} static inline void Setbit(uint8& val, uint8 bitindex, bool newval) { if(newval) val |= (1 << bitindex); else val &= ~(1 << bitindex); } bool ID::IsPrintable() const { for(std::size_t i = 0; i < m_ID.length(); ++i) { if(m_ID[i] <= 0 || isprint(static_cast(m_ID[i])) == 0) { return false; } } return true; } //Format: First bit tells whether the size indicator is 1 or 2 bytes. static void WriteAdaptive12String(std::ostream& oStrm, const std::string& str) { uint16 s = static_cast(str.size()); LimitMax(s, uint16(uint16_max / 2)); mpt::IO::WriteAdaptiveInt16LE(oStrm, s); oStrm.write(str.c_str(), s); } void WriteItemString(std::ostream& oStrm, const std::string &str) { uint32 id = static_cast(std::min(str.size(), (uint32_max >> 4))) << 4; id |= 12; // 12 == 1100b Binarywrite(oStrm, id); id >>= 4; if(id > 0) oStrm.write(str.data(), id); } void ReadItemString(std::istream& iStrm, std::string& str, const DataSize) { // bits 0,1: Bytes per char type: 1,2,3,4. // bits 2,3: Bytes in size indicator, 1,2,3,4 uint32 id = 0; Binaryread(iStrm, id, 1); const uint8 nSizeBytes = (id & 12) >> 2; // 12 == 1100b if (nSizeBytes > 0) { uint8 bytes = std::min(3, nSizeBytes); uint8 v2 = 0; uint8 v3 = 0; uint8 v4 = 0; if(bytes >= 1) Binaryread(iStrm, v2); if(bytes >= 2) Binaryread(iStrm, v3); if(bytes >= 3) Binaryread(iStrm, v4); id &= 0xff; id |= (v2 << 8) | (v3 << 16) | (v4 << 24); } // Limit to 1 MB. str.resize(std::min(id >> 4, 1000000)); for(size_t i = 0; i < str.size(); i++) iStrm.read(&str[i], 1); id = (id >> 4) - static_cast(str.size()); if(id > 0) iStrm.ignore(id); } mpt::ustring ID::AsString() const { if(IsPrintable()) { return mpt::ToUnicode(mpt::CharsetISO8859_1, m_ID); } if(m_ID.length() > 8) { return mpt::ustring(); } uint64le val; val.set(0); std::memcpy(&val, m_ID.data(), m_ID.length()); return mpt::ufmt::val(val); } const char Ssb::s_EntryID[3] = {'2','2','8'}; #ifdef SSB_LOGGING static const MPT_UCHAR_TYPE tstrWriteHeader[] = MPT_ULITERAL("Write header with ID = %1\n"); static const MPT_UCHAR_TYPE tstrWriteProgress[] = MPT_ULITERAL("Wrote entry: {num, id, rpos, size} = {%1, %2, %3, %4}\n"); static const MPT_UCHAR_TYPE tstrWritingMap[] = MPT_ULITERAL("Writing map to rpos: %1\n"); static const MPT_UCHAR_TYPE tstrMapEntryWrite[] = MPT_ULITERAL("Writing map entry: id=%1, rpos=%2, size=%3\n"); static const MPT_UCHAR_TYPE strWriteNote[] = MPT_ULITERAL("Write note: "); static const MPT_UCHAR_TYPE tstrEndOfStream[] = MPT_ULITERAL("End of stream(rpos): %1\n"); static const MPT_UCHAR_TYPE tstrReadingHeader[] = MPT_ULITERAL("Read header with expected ID = %1\n"); static const MPT_UCHAR_TYPE strNoMapInFile[] = MPT_ULITERAL("No map in the file.\n"); static const MPT_UCHAR_TYPE strIdMismatch[] = MPT_ULITERAL("ID mismatch, terminating read.\n"); static const MPT_UCHAR_TYPE strIdMatch[] = MPT_ULITERAL("ID match, continuing reading.\n"); static const MPT_UCHAR_TYPE tstrReadingMap[] = MPT_ULITERAL("Reading map from rpos: %1\n"); static const MPT_UCHAR_TYPE tstrEndOfMap[] = MPT_ULITERAL("End of map(rpos): %1\n"); static const MPT_UCHAR_TYPE tstrReadProgress[] = MPT_ULITERAL("Read entry: {num, id, rpos, size, desc} = {%1, %2, %3, %4, %5}\n"); static const MPT_UCHAR_TYPE tstrNoEntryFound[] = MPT_ULITERAL("No entry with id %1 found.\n"); static const MPT_UCHAR_TYPE strReadNote[] = MPT_ULITERAL("Read note: "); #endif Ssb::Ssb() : m_Status(SNT_NONE) , m_nFixedEntrySize(0) , m_posStart(0) , m_nIdbytes(IdSizeVariable) , m_nCounter(0) , m_Flags((1 << RwfWMapStartPosEntry) + (1 << RwfWMapSizeEntry) + (1 << RwfWVersionNum)) { return; } SsbWrite::SsbWrite(std::ostream& oStrm) : m_pOstrm(&oStrm) , m_posEntrycount(0) , m_posMapPosField(0) { return; } SsbRead::SsbRead(std::istream& iStrm) : m_pIstrm(&iStrm) , m_nReadVersion(0) , m_rposMapBegin(0) , m_posMapEnd(0) , m_posDataBegin(0) , m_rposEndofHdrData(0) , m_nReadEntrycount(0) , m_nNextReadHint(0) { return; } void SsbWrite::AddWriteNote(const SsbStatus s) { m_Status |= s; SSB_LOG(mpt::format(MPT_USTRING("%1: 0x%2\n"))(strWriteNote, mpt::ufmt::hex(s))); } void SsbRead::AddReadNote(const SsbStatus s) { m_Status |= s; SSB_LOG(mpt::format(MPT_USTRING("%1: 0x%2\n"))(strReadNote, mpt::ufmt::hex(s))); } void SsbRead::AddReadNote(const ReadEntry* const pRe, const NumType nNum) { m_Status |= SNT_PROGRESS; SSB_LOG(mpt::format(mpt::ustring(tstrReadProgress))( nNum, (pRe && pRe->nIdLength < 30 && m_Idarray.size() > 0) ? ID(&m_Idarray[pRe->nIdpos], pRe->nIdLength).AsString() : MPT_USTRING(""), (pRe) ? pRe->rposStart : 0, (pRe && pRe->nSize != invalidDatasize) ? mpt::ufmt::val(pRe->nSize) : MPT_USTRING(""), MPT_USTRING(""))); #ifndef SSB_LOGGING MPT_UNREFERENCED_PARAMETER(pRe); MPT_UNREFERENCED_PARAMETER(nNum); #endif } // Called after writing an entry. void SsbWrite::AddWriteNote(const ID &id, const NumType nEntryNum, const DataSize nBytecount, const RposType rposStart) { m_Status |= SNT_PROGRESS; SSB_LOG(mpt::format(mpt::ustring(tstrWriteProgress))(nEntryNum, id.AsString(), rposStart, nBytecount)); #ifndef SSB_LOGGING MPT_UNREFERENCED_PARAMETER(id); MPT_UNREFERENCED_PARAMETER(nEntryNum); MPT_UNREFERENCED_PARAMETER(nBytecount); MPT_UNREFERENCED_PARAMETER(rposStart); #endif } void SsbRead::ResetReadstatus() { m_Status = SNT_NONE; m_Idarray.reserve(32); m_Idarray.push_back(0); } void SsbWrite::WriteMapItem(const ID &id, const RposType& rposDataStart, const DataSize& nDatasize, const char* pszDesc) { SSB_LOG(mpt::format(mpt::ustring(tstrMapEntryWrite))( (id.GetSize() > 0) ? id.AsString() : MPT_USTRING(""), rposDataStart, nDatasize)); mpt::ostringstream mapStream; if(m_nIdbytes > 0) { if (m_nIdbytes != IdSizeVariable && id.GetSize() != m_nIdbytes) { AddWriteNote(SNW_CHANGING_IDSIZE_WITH_FIXED_IDSIZESETTING); return; } if (m_nIdbytes == IdSizeVariable) //Variablesize ID? mpt::IO::WriteAdaptiveInt16LE(mapStream, static_cast(id.GetSize())); if(id.GetSize() > 0) mapStream.write(id.GetBytes(), id.GetSize()); } if (GetFlag(RwfWMapStartPosEntry)) //Startpos mpt::IO::WriteAdaptiveInt64LE(mapStream, rposDataStart); if (GetFlag(RwfWMapSizeEntry)) //Entrysize mpt::IO::WriteAdaptiveInt64LE(mapStream, nDatasize); if (GetFlag(RwfWMapDescEntry)) //Entry descriptions WriteAdaptive12String(mapStream, std::string(pszDesc)); m_MapStreamString.append(mapStream.str()); } void SsbWrite::IncrementWriteCounter() { m_nCounter++; if (m_nCounter >= (uint16_max >> 2)) { FinishWrite(); AddWriteNote(SNW_MAX_WRITE_COUNT_REACHED); } } void SsbWrite::BeginWrite(const ID &id, const uint64& nVersion) { std::ostream& oStrm = *m_pOstrm; SSB_LOG(mpt::format(mpt::ustring(tstrWriteHeader))(id.AsString())); ResetWritestatus(); if(!oStrm.good()) { AddWriteNote(SNRW_BADGIVEN_STREAM); return; } // Start bytes. oStrm.write(s_EntryID, sizeof(s_EntryID)); m_posStart = oStrm.tellp() - Offtype(sizeof(s_EntryID)); // Object ID. { uint8 idsize = static_cast(id.GetSize()); Binarywrite(oStrm, idsize); if(idsize > 0) oStrm.write(id.GetBytes(), id.GetSize()); } // Form header. uint8 header = 0; SetFlag(RwfWMapStartPosEntry, GetFlag(RwfWMapStartPosEntry) && m_nFixedEntrySize == 0); SetFlag(RwfWMapSizeEntry, GetFlag(RwfWMapSizeEntry) && m_nFixedEntrySize == 0); header = (m_nIdbytes != 4) ? (m_nIdbytes & 3) : 3; //0,1 : Bytes per IDtype, 0,1,2,4 Setbit(header, 2, GetFlag(RwfWMapStartPosEntry)); //2 : Startpos in map? Setbit(header, 3, GetFlag(RwfWMapSizeEntry)); //3 : Datasize in map? Setbit(header, 4, GetFlag(RwfWVersionNum)); //4 : Version numeric field? Setbit(header, 7, GetFlag(RwfWMapDescEntry)); //7 : Entrydescriptions in map? // Write header Binarywrite(oStrm, header); // Additional options. uint8 tempU8 = 0; Setbit(tempU8, 0, (m_nIdbytes == IdSizeVariable) || (m_nIdbytes == 3) || (m_nIdbytes > 4)); Setbit(tempU8, 1, m_nFixedEntrySize != 0); const uint8 flags = tempU8; if(flags != s_DefaultFlagbyte) { mpt::IO::WriteAdaptiveInt32LE(oStrm, 2); //Headersize - now it is 2. Binarywrite(oStrm, HeaderId_FlagByte); Binarywrite(oStrm, flags); } else mpt::IO::WriteAdaptiveInt32LE(oStrm, 0); if(Testbit(header, 4)) // Version(numeric)? mpt::IO::WriteAdaptiveInt64LE(oStrm, nVersion); if(Testbit(flags, 0)) // Custom IDbytecount? { uint8 n = (m_nIdbytes == IdSizeVariable) ? 1 : static_cast((m_nIdbytes << 1)); Binarywrite(oStrm, n); } if(Testbit(flags, 1)) // Fixedsize entries? mpt::IO::WriteAdaptiveInt32LE(oStrm, m_nFixedEntrySize); //Entrycount. Reserve two bytes(max uint16_max / 4 entries), actual value is written after writing data. m_posEntrycount = oStrm.tellp(); Binarywrite(oStrm, 0); SetFlag(RwfRwHasMap, (m_nIdbytes != 0 || GetFlag(RwfWMapStartPosEntry) || GetFlag(RwfWMapSizeEntry) || GetFlag(RwfWMapDescEntry))); m_posMapPosField = oStrm.tellp(); if (GetFlag(RwfRwHasMap)) //Mapping begin pos(reserve space - actual value is written after writing data) Binarywrite(oStrm, 0); } SsbRead::ReadRv SsbRead::OnReadEntry(const ReadEntry* pE, const ID &id, const Postype& posReadBegin) { if (pE != nullptr) AddReadNote(pE, m_nCounter); else if (GetFlag(RwfRMapHasId) == false) // Not ID's in map. { ReadEntry e; e.rposStart = static_cast(posReadBegin - m_posStart); e.nSize = static_cast(m_pIstrm->tellg() - posReadBegin); AddReadNote(&e, m_nCounter); } else // Entry not found. { SSB_LOG(mpt::format(mpt::ustring(tstrNoEntryFound))(id.AsString())); #ifndef SSB_LOGGING MPT_UNREFERENCED_PARAMETER(id); #endif return EntryNotFound; } m_nCounter++; return EntryRead; } void SsbWrite::OnWroteItem(const ID &id, const Postype& posBeforeWrite) { const Offtype nRawEntrySize = m_pOstrm->tellp() - posBeforeWrite; if (nRawEntrySize < 0 || static_cast(nRawEntrySize) > std::numeric_limits::max()) { AddWriteNote(SNW_INSUFFICIENT_DATASIZETYPE); return; } if(GetFlag(RwfRMapHasSize) && (nRawEntrySize < 0 || static_cast(nRawEntrySize) > (std::numeric_limits::max() >> 2))) { AddWriteNote(SNW_DATASIZETYPE_OVERFLOW); return; } DataSize nEntrySize = static_cast(nRawEntrySize); // Handle fixed size entries: if (m_nFixedEntrySize > 0) { if(nEntrySize <= m_nFixedEntrySize) { for(uint32 i = 0; iput(0); nEntrySize = m_nFixedEntrySize; } else { AddWriteNote(SNW_INSUFFICIENT_FIXEDSIZE); return; } } if (GetFlag(RwfRwHasMap)) WriteMapItem(id, static_cast(posBeforeWrite - m_posStart), nEntrySize, ""); AddWriteNote(id, m_nCounter, nEntrySize, static_cast(posBeforeWrite - m_posStart)); IncrementWriteCounter(); } void SsbRead::BeginRead(const ID &id, const uint64& nVersion) { std::istream& iStrm = *m_pIstrm; SSB_LOG(mpt::format(mpt::ustring(tstrReadingHeader))(id.AsString())); ResetReadstatus(); if (!iStrm.good()) { AddReadNote(SNRW_BADGIVEN_STREAM); return; } m_posStart = iStrm.tellg(); // Start bytes. { char temp[sizeof(s_EntryID)]; ArrayReader(sizeof(s_EntryID))(iStrm, temp, sizeof(s_EntryID)); if(std::memcmp(temp, s_EntryID, sizeof(s_EntryID))) { AddReadNote(SNR_STARTBYTE_MISMATCH); return; } } // Compare IDs. uint8 storedIdLen = 0; Binaryread(iStrm, storedIdLen); char storedIdBuf[256]; MemsetZero(storedIdBuf); if(storedIdLen > 0) { iStrm.read(storedIdBuf, storedIdLen); } if(!(id == ID(storedIdBuf, storedIdLen))) { AddReadNote(SNR_OBJECTCLASS_IDMISMATCH); } if ((m_Status & SNT_FAILURE) != 0) { SSB_LOG(mpt::ustring(strIdMismatch)); return; } SSB_LOG(mpt::ustring(strIdMatch)); // Header uint8 tempU8; Binaryread(iStrm, tempU8); const uint8 header = tempU8; m_nIdbytes = ((header & 3) == 3) ? 4 : (header & 3); if (Testbit(header, 6)) SetFlag(RwfRTwoBytesDescChar, true); // Read headerdata size uint32 tempU32 = 0; mpt::IO::ReadAdaptiveInt32LE(iStrm, tempU32); const uint32 headerdatasize = tempU32; // If headerdatasize != 0, read known headerdata and ignore rest. uint8 flagbyte = s_DefaultFlagbyte; if(headerdatasize >= 2) { Binaryread(iStrm, tempU8); if(tempU8 == HeaderId_FlagByte) Binaryread(iStrm, flagbyte); iStrm.ignore( (tempU8 == HeaderId_FlagByte) ? headerdatasize - 2 : headerdatasize - 1); } uint64 tempU64 = 0; // Read version numeric if available. if (Testbit(header, 4)) { mpt::IO::ReadAdaptiveInt64LE(iStrm, tempU64); m_nReadVersion = tempU64; if(tempU64 > nVersion) AddReadNote(SNR_LOADING_OBJECT_WITH_LARGER_VERSION); } if (Testbit(header, 5)) { Binaryread(iStrm, tempU8); iStrm.ignore(tempU8); } if(Testbit(flagbyte, 0)) // Custom ID? { Binaryread(iStrm, tempU8); if ((tempU8 & 1) != 0) m_nIdbytes = IdSizeVariable; else m_nIdbytes = (tempU8 >> 1); if(m_nIdbytes == 0) AddReadNote(SNR_NO_ENTRYIDS_WITH_CUSTOMID_DEFINED); } m_nFixedEntrySize = 0; if(Testbit(flagbyte, 1)) // Fixedsize entries? mpt::IO::ReadAdaptiveInt32LE(iStrm, m_nFixedEntrySize); SetFlag(RwfRMapHasStartpos, Testbit(header, 2)); SetFlag(RwfRMapHasSize, Testbit(header, 3)); SetFlag(RwfRMapHasId, (m_nIdbytes > 0)); SetFlag(RwfRMapHasDesc, Testbit(header, 7)); SetFlag(RwfRwHasMap, GetFlag(RwfRMapHasId) || GetFlag(RwfRMapHasStartpos) || GetFlag(RwfRMapHasSize) || GetFlag(RwfRMapHasDesc)); if (GetFlag(RwfRwHasMap) == false) { SSB_LOG(mpt::ustring(strNoMapInFile)); } if (Testbit(flagbyte, 2)) // Object description? { uint16 size = 0; mpt::IO::ReadAdaptiveInt16LE(iStrm, size); iStrm.ignore(size * (GetFlag(RwfRTwoBytesDescChar) ? 2 : 1)); } if(Testbit(flagbyte, 3)) iStrm.ignore(5); // Read entrycount mpt::IO::ReadAdaptiveInt64LE(iStrm, tempU64); if(tempU64 > 16000) // The current code can only write 16383 entries because it uses a Adaptive64LE with a fixed size=2 // Additionally, 16000 is an arbitrary limit to avoid an out-of-memory DoS when caching the map. { AddReadNote(SNR_TOO_MANY_ENTRIES_TO_READ); return; } m_nReadEntrycount = static_cast(tempU64); if(m_nReadEntrycount == 0) AddReadNote(SNR_ZEROENTRYCOUNT); // Read map rpos if map exists. if (GetFlag(RwfRwHasMap)) { mpt::IO::ReadAdaptiveInt64LE(iStrm, tempU64); if(tempU64 > static_cast(std::numeric_limits::max())) { AddReadNote(SNR_INSUFFICIENT_STREAM_OFFTYPE); return; } } const Offtype rawEndOfHdrData = iStrm.tellg() - m_posStart; if (rawEndOfHdrData < 0 || static_cast(rawEndOfHdrData) > std::numeric_limits::max()) { AddReadNote(SNR_INSUFFICIENT_RPOSTYPE); return; } m_rposEndofHdrData = static_cast(rawEndOfHdrData); m_rposMapBegin = (GetFlag(RwfRwHasMap)) ? static_cast(tempU64) : m_rposEndofHdrData; if (GetFlag(RwfRwHasMap) == false) m_posMapEnd = m_posStart + m_rposEndofHdrData; SetFlag(RwfRHeaderIsRead, true); } void SsbRead::CacheMap() { std::istream& iStrm = *m_pIstrm; if(GetFlag(RwfRwHasMap) || m_nFixedEntrySize > 0) { iStrm.seekg(m_posStart + m_rposMapBegin); if(iStrm.fail()) { AddReadNote(SNR_BADSTREAM_AFTER_MAPHEADERSEEK); return; } SSB_LOG(mpt::format(mpt::ustring(tstrReadingMap))(m_rposMapBegin)); mapData.resize(m_nReadEntrycount); m_Idarray.reserve(m_nReadEntrycount * 4); //Read map for(NumType i = 0; i 0 && (Util::MaxValueOfType(nOldEnd) - nOldEnd >= nIdsize)) { m_Idarray.resize(nOldEnd + nIdsize); iStrm.read(&m_Idarray[nOldEnd], nIdsize); } mapData[i].nIdLength = nIdsize; mapData[i].nIdpos = nOldEnd; // Read position. if(GetFlag(RwfRMapHasStartpos)) { uint64 tempU64; mpt::IO::ReadAdaptiveInt64LE(iStrm, tempU64); if(tempU64 > static_cast(std::numeric_limits::max())) { AddReadNote(SNR_INSUFFICIENT_STREAM_OFFTYPE); return; } mapData[i].rposStart = static_cast(tempU64); } // Read entry size. if (m_nFixedEntrySize > 0) mapData[i].nSize = m_nFixedEntrySize; else if(GetFlag(RwfRMapHasSize)) // Map has datasize field. { uint64 tempU64; mpt::IO::ReadAdaptiveInt64LE(iStrm, tempU64); if(tempU64 > static_cast(std::numeric_limits::max())) { AddReadNote(SNR_INSUFFICIENT_STREAM_OFFTYPE); return; } mapData[i].nSize = static_cast(tempU64); } // If there's no entry startpos in map, count start pos from datasizes. // Here readentry.rposStart is set to relative position from databegin. if (mapData[i].nSize != invalidDatasize && GetFlag(RwfRMapHasStartpos) == false) mapData[i].rposStart = (i > 0) ? mapData[i-1].rposStart + mapData[i-1].nSize : 0; if(GetFlag(RwfRMapHasDesc)) //Map has entrydescriptions? { uint16 size = 0; mpt::IO::ReadAdaptiveInt16LE(iStrm, size); if(GetFlag(RwfRTwoBytesDescChar)) iStrm.ignore(size * 2); else iStrm.ignore(size); } } m_posMapEnd = iStrm.tellg(); SSB_LOG(mpt::format(mpt::ustring(tstrEndOfMap))(m_posMapEnd - m_posStart)); } SetFlag(RwfRMapCached, true); m_posDataBegin = (m_rposMapBegin == m_rposEndofHdrData) ? m_posMapEnd : m_posStart + Postype(m_rposEndofHdrData); m_pIstrm->seekg(m_posDataBegin); // If there are no positions in the map but there are entry sizes, rposStart will // be relative to data start. Now that posDataBegin is known, make them relative to // startpos. if (GetFlag(RwfRMapHasStartpos) == false && (GetFlag(RwfRMapHasSize) || m_nFixedEntrySize > 0)) { const RposType offset = static_cast(m_posDataBegin - m_posStart); for(size_t i = 0; i < m_nReadEntrycount; i++) mapData[i].rposStart += offset; } } const ReadEntry* SsbRead::Find(const ID &id) { m_pIstrm->clear(); if (GetFlag(RwfRMapCached) == false) CacheMap(); if (m_nFixedEntrySize > 0 && GetFlag(RwfRMapHasStartpos) == false && GetFlag(RwfRMapHasSize) == false) m_pIstrm->seekg(m_posDataBegin + Postype(m_nFixedEntrySize * m_nCounter)); if (GetFlag(RwfRMapHasId) == true) { const size_t nEntries = mapData.size(); for(size_t i0 = 0; i0 < nEntries; i0++) { const size_t i = (i0 + m_nNextReadHint) % nEntries; if(mapData[i].nIdpos < m_Idarray.size() && id == ID(&m_Idarray[mapData[i].nIdpos], mapData[i].nIdLength)) { m_nNextReadHint = (i + 1) % nEntries; if (mapData[i].rposStart != 0) m_pIstrm->seekg(m_posStart + Postype(mapData[i].rposStart)); return &mapData[i]; } } } return nullptr; } void SsbWrite::FinishWrite() { std::ostream& oStrm = *m_pOstrm; const Postype posDataEnd = oStrm.tellp(); Postype posMapStart = oStrm.tellp(); SSB_LOG(mpt::format(mpt::ustring(tstrWritingMap))(posMapStart - m_posStart)); if (GetFlag(RwfRwHasMap)) //Write map { oStrm.write(m_MapStreamString.c_str(), m_MapStreamString.length()); } const Postype posMapEnd = oStrm.tellp(); // Write entry count. oStrm.seekp(m_posEntrycount); // Write a fixed size=2 Adaptive64LE because space for this value has already been reserved berforehand. mpt::IO::WriteAdaptiveInt64LE(oStrm, m_nCounter, 2, 2); if (GetFlag(RwfRwHasMap)) { // Write map start position. oStrm.seekp(m_posMapPosField); const uint64 rposMap = posMapStart - m_posStart; // Write a fixed size=8 Adaptive64LE because space for this value has already been reserved berforehand. mpt::IO::WriteAdaptiveInt64LE(oStrm, rposMap, 8, 8); } // Seek to end. oStrm.seekp(std::max(posMapEnd, posDataEnd)); SSB_LOG(mpt::format(mpt::ustring(tstrEndOfStream))(oStrm.tellp() - m_posStart)); } } // namespace srlztn OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/mptRandom.h0000644000372100037210000004330513214727756017703 00000000000000/* * mptRandom.h * ----------- * Purpose: PRNG * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "mptMutex.h" #include #include #ifdef MODPLUG_TRACKER #include #endif // MODPLUG_TRACKER OPENMPT_NAMESPACE_BEGIN // NOTE: // We implement our own PRNG and distribution functions as the implementations // of std::uniform_int_distribution is either wrong (not uniform in MSVC2010) or // not guaranteed to be livelock-free for bad PRNGs (in GCC, Clang, boost). // We resort to a simpler implementation with only power-of-2 result ranges for // both the underlying PRNG and our interface function. This saves us from // complicated code having to deal with partial bits of entropy. // Our interface still somewhat follows the mindset of C++11 (with the // addition of a simple wrapper function mpt::random which saves the caller from // instantiating distribution objects for the common uniform distribution case. // We are still using std::random_device for initial seeding when avalable and // after working around its set of problems. namespace mpt { #ifdef MPT_BUILD_FUZZER static const uint32 FUZZER_RNG_SEED = 3141592653u; // pi #endif // MPT_BUILD_FUZZER namespace detail { MPT_CONSTEXPR11_FUN int lower_bound_entropy_bits(unsigned int x) { // easy to compile-time evaluate even for stupid compilers return x >= 0xffffffffu ? 32 : x >= 0x7fffffffu ? 31 : x >= 0x3fffffffu ? 30 : x >= 0x1fffffffu ? 29 : x >= 0x0fffffffu ? 28 : x >= 0x07ffffffu ? 27 : x >= 0x03ffffffu ? 26 : x >= 0x01ffffffu ? 25 : x >= 0x00ffffffu ? 24 : x >= 0x007fffffu ? 23 : x >= 0x003fffffu ? 22 : x >= 0x001fffffu ? 21 : x >= 0x000fffffu ? 20 : x >= 0x0007ffffu ? 19 : x >= 0x0003ffffu ? 18 : x >= 0x0001ffffu ? 17 : x >= 0x0000ffffu ? 16 : x >= 0x00007fffu ? 15 : x >= 0x00003fffu ? 14 : x >= 0x00001fffu ? 13 : x >= 0x00000fffu ? 12 : x >= 0x000007ffu ? 11 : x >= 0x000003ffu ? 10 : x >= 0x000001ffu ? 9 : x >= 0x000000ffu ? 8 : x >= 0x0000007fu ? 7 : x >= 0x0000003fu ? 6 : x >= 0x0000001fu ? 5 : x >= 0x0000000fu ? 4 : x >= 0x00000007u ? 3 : x >= 0x00000003u ? 2 : x >= 0x00000001u ? 1 : 0; } } template struct engine_traits { typedef typename Trng::result_type result_type; static MPT_CONSTEXPR11_FUN int result_bits() { return Trng::result_bits(); } template static inline Trng make(Trd & rd) { return Trng(rd); } }; template inline T random(Trng & rng) { STATIC_ASSERT(std::numeric_limits::is_integer); typedef typename std::make_unsigned::type unsigned_T; const unsigned int rng_bits = mpt::engine_traits::result_bits(); unsigned_T result = 0; for(std::size_t entropy = 0; entropy < (sizeof(T) * 8); entropy += rng_bits) { MPT_CONSTANT_IF(rng_bits < (sizeof(T) * 8)) { MPT_CONSTEXPR11_VAR unsigned int shift_bits = rng_bits % (sizeof(T) * 8); // silence utterly stupid MSVC and GCC warnings about shifting by too big amount (in which case this branch is not even taken however) result = (result << shift_bits) ^ static_cast(rng()); } else { result = static_cast(rng()); } } return static_cast(result); } template inline T random(Trng & rng) { STATIC_ASSERT(std::numeric_limits::is_integer); typedef typename std::make_unsigned::type unsigned_T; const unsigned int rng_bits = mpt::engine_traits::result_bits(); unsigned_T result = 0; for(std::size_t entropy = 0; entropy < std::min(required_entropy_bits, sizeof(T) * 8); entropy += rng_bits) { MPT_CONSTANT_IF(rng_bits < (sizeof(T) * 8)) { MPT_CONSTEXPR11_VAR unsigned int shift_bits = rng_bits % (sizeof(T) * 8); // silence utterly stupid MSVC and GCC warnings about shifting by too big amount (in which case this branch is not even taken however) result = (result << shift_bits) ^ static_cast(rng()); } else { result = static_cast(rng()); } } MPT_CONSTANT_IF(required_entropy_bits >= (sizeof(T) * 8)) { return static_cast(result); } else { return static_cast(result & ((static_cast(1) << required_entropy_bits) - static_cast(1))); } } template inline T random(Trng & rng, std::size_t required_entropy_bits) { STATIC_ASSERT(std::numeric_limits::is_integer); typedef typename std::make_unsigned::type unsigned_T; const unsigned int rng_bits = mpt::engine_traits::result_bits(); unsigned_T result = 0; for(std::size_t entropy = 0; entropy < std::min(required_entropy_bits, sizeof(T) * 8); entropy += rng_bits) { MPT_CONSTANT_IF(rng_bits < (sizeof(T) * 8)) { MPT_CONSTEXPR11_VAR unsigned int shift_bits = rng_bits % (sizeof(T) * 8); // silence utterly stupid MSVC and GCC warnings about shifting by too big amount (in which case this branch is not even taken however) result = (result << shift_bits) ^ static_cast(rng()); } else { result = static_cast(rng()); } } if(required_entropy_bits >= (sizeof(T) * 8)) { return static_cast(result); } else { return static_cast(result & ((static_cast(1) << required_entropy_bits) - static_cast(1))); } } template struct float_traits { }; template <> struct float_traits { typedef uint32 mantissa_uint_type; static const int mantissa_bits = 24; }; template <> struct float_traits { typedef uint64 mantissa_uint_type; static const int mantissa_bits = 53; }; template <> struct float_traits { typedef uint64 mantissa_uint_type; static const int mantissa_bits = 63; }; template struct uniform_real_distribution { private: T a; T b; public: inline uniform_real_distribution(T a, T b) : a(a) , b(b) { return; } template inline T operator()(Trng & rng) const { typedef typename float_traits::mantissa_uint_type uint_type; const int bits = float_traits::mantissa_bits; return ((b - a) * static_cast(mpt::random(rng)) / static_cast((static_cast(1u) << bits))) + a; } }; template inline T random(Trng & rng, T min, T max) { STATIC_ASSERT(!std::numeric_limits::is_integer); typedef mpt::uniform_real_distribution dis_type; dis_type dis(min, max); return static_cast(dis(rng)); } namespace rng { #if MPT_COMPILER_MSVC #pragma warning(push) #pragma warning(disable:4724) // potential mod by 0 #endif // MPT_COMPILER_MSVC template class lcg { public: typedef Tstate state_type; typedef Tvalue result_type; private: state_type state; public: template explicit inline lcg(Trng & rd) : state(mpt::random(rd)) { operator()(); // we return results from the current state and update state after returning. results in better pipelining. } explicit inline lcg(state_type seed) : state(seed) { operator()(); // we return results from the current state and update state after returning. results in better pipelining. } public: static MPT_CONSTEXPR11_FUN result_type min() { return static_cast(0); } static MPT_CONSTEXPR11_FUN result_type max() { STATIC_ASSERT(((result_mask >> result_shift) << result_shift) == result_mask); return static_cast(result_mask >> result_shift); } static MPT_CONSTEXPR11_FUN int result_bits() { STATIC_ASSERT(((static_cast(1) << result_bits_) - 1) == (result_mask >> result_shift)); return result_bits_; } inline result_type operator()() { // we return results from the current state and update state after returning. results in better pipelining. state_type s = state; result_type result = static_cast((s & result_mask) >> result_shift); s = Util::ModIfNotZero((a * s) + c); state = s; return result; } }; #if MPT_COMPILER_MSVC #pragma warning(pop) #endif // MPT_COMPILER_MSVC typedef lcg lcg_msvc; typedef lcg lcg_c99; typedef lcg lcg_musl; } // namespace rng #ifdef MODPLUG_TRACKER namespace rng { class crand { public: typedef void state_type; typedef int result_type; private: static void reseed(uint32 seed); public: template static void reseed(Trd & rd) { reseed(mpt::random(rd)); } public: crand() { } explicit crand(const std::string &) { } public: static MPT_CONSTEXPR11_FUN result_type min() { return 0; } static MPT_CONSTEXPR11_FUN result_type max() { return RAND_MAX; } static MPT_CONSTEXPR11_FUN int result_bits() { return detail::lower_bound_entropy_bits(RAND_MAX); } result_type operator()(); }; } // namespace rng #endif // MODPLUG_TRACKER // C++11 std::random_device may be implemented as a deterministic PRNG. // There is no way to seed this PRNG and it is allowed to be seeded with the // same value on each program invocation. This makes std::random_device // completely useless even as a non-cryptographic entropy pool. // We fallback to time-seeded std::mt19937 if std::random_device::entropy() is // 0 or less. class sane_random_device { private: mpt::mutex m; std::string token; std::random_device rd; bool rd_reliable; std::unique_ptr rd_fallback; public: typedef unsigned int result_type; private: void init_fallback(); public: sane_random_device(); sane_random_device(const std::string & token); static MPT_CONSTEXPR11_FUN result_type min() { return std::numeric_limits::min(); } static MPT_CONSTEXPR11_FUN result_type max() { return std::numeric_limits::max(); } static MPT_CONSTEXPR11_FUN int result_bits() { return sizeof(result_type) * 8; } result_type operator()(); }; template class seed_seq_values { private: unsigned int seeds[N]; public: template explicit seed_seq_values(Trd & rd) { for(std::size_t i = 0; i < N; ++i) { seeds[i] = rd(); } } const unsigned int * begin() const { return seeds + 0; } const unsigned int * end() const { return seeds + N; } }; // C++11 random does not provide any sane way to determine the amount of entropy // required to seed a particular engine. VERY STUPID. // List the ones we are likely to use. template <> struct engine_traits { static const std::size_t seed_bits = sizeof(std::mt19937::result_type) * 8 * std::mt19937::state_size; typedef std::mt19937 rng_type; typedef rng_type::result_type result_type; static MPT_CONSTEXPR11_FUN int result_bits() { return rng_type::word_size; } template static inline rng_type make(Trd & rd) { mpt::seed_seq_values values(rd); std::seed_seq seed(values.begin(), values.end()); return rng_type(seed); } }; template <> struct engine_traits { static const std::size_t seed_bits = sizeof(std::mt19937_64::result_type) * 8 * std::mt19937_64::state_size; typedef std::mt19937_64 rng_type; typedef rng_type::result_type result_type; static MPT_CONSTEXPR11_FUN int result_bits() { return rng_type::word_size; } template static inline rng_type make(Trd & rd) { mpt::seed_seq_values values(rd); std::seed_seq seed(values.begin(), values.end()); return rng_type(seed); } }; template <> struct engine_traits { static const std::size_t seed_bits = std::ranlux24_base::word_size; typedef std::ranlux24_base rng_type; typedef rng_type::result_type result_type; static MPT_CONSTEXPR11_FUN int result_bits() { return rng_type::word_size; } template static inline rng_type make(Trd & rd) { mpt::seed_seq_values values(rd); std::seed_seq seed(values.begin(), values.end()); return rng_type(seed); } }; template <> struct engine_traits { static const std::size_t seed_bits = std::ranlux48_base::word_size; typedef std::ranlux48_base rng_type; typedef rng_type::result_type result_type; static MPT_CONSTEXPR11_FUN int result_bits() { return rng_type::word_size; } template static inline rng_type make(Trd & rd) { mpt::seed_seq_values values(rd); std::seed_seq seed(values.begin(), values.end()); return rng_type(seed); } }; template <> struct engine_traits { static const std::size_t seed_bits = std::ranlux24_base::word_size; typedef std::ranlux24 rng_type; typedef rng_type::result_type result_type; static MPT_CONSTEXPR11_FUN int result_bits() { return std::ranlux24_base::word_size; } template static inline rng_type make(Trd & rd) { mpt::seed_seq_values values(rd); std::seed_seq seed(values.begin(), values.end()); return rng_type(seed); } }; template <> struct engine_traits { static const std::size_t seed_bits = std::ranlux48_base::word_size; typedef std::ranlux48 rng_type; typedef rng_type::result_type result_type; static MPT_CONSTEXPR11_FUN int result_bits() { return std::ranlux48_base::word_size; } template static inline rng_type make(Trd & rd) { mpt::seed_seq_values values(rd); std::seed_seq seed(values.begin(), values.end()); return rng_type(seed); } }; class prng_random_device_seeder { private: uint8 generate_seed8(); uint16 generate_seed16(); uint32 generate_seed32(); uint64 generate_seed64(); protected: template inline T generate_seed(); protected: prng_random_device_seeder(); }; template <> inline uint8 prng_random_device_seeder::generate_seed() { return generate_seed8(); } template <> inline uint16 prng_random_device_seeder::generate_seed() { return generate_seed16(); } template <> inline uint32 prng_random_device_seeder::generate_seed() { return generate_seed32(); } template <> inline uint64 prng_random_device_seeder::generate_seed() { return generate_seed64(); } template class prng_random_device : public prng_random_device_seeder { public: typedef unsigned int result_type; private: mpt::mutex m; Trng rng; public: prng_random_device() : rng(generate_seed()) { return; } prng_random_device(const std::string &) : rng(generate_seed()) { return; } static MPT_CONSTEXPR11_FUN result_type min() { return std::numeric_limits::min(); } static MPT_CONSTEXPR11_FUN result_type max() { return std::numeric_limits::max(); } static MPT_CONSTEXPR11_FUN int result_bits() { return sizeof(unsigned int) * 8; } result_type operator()() { MPT_LOCK_GUARD l(m); return mpt::random(rng); } }; #ifdef MPT_BUILD_FUZZER // 1. Use deterministic seeding typedef mpt::prng_random_device random_device; // 2. Use fast PRNGs in order to not waste time fuzzing more complex PRNG // implementations. typedef mpt::rng::lcg_msvc fast_prng; typedef mpt::rng::lcg_c99 main_prng; typedef mpt::rng::lcg_musl best_prng; #else // !MPT_BUILD_FUZZER // mpt::random_device always generates 32 bits of entropy typedef mpt::sane_random_device random_device; // We cannot use std::minstd_rand here because it has not a power-of-2 sized // output domain which we rely upon. typedef mpt::rng::lcg_msvc fast_prng; // about 3 ALU operations, ~32bit of state, suited for inner loops typedef std::mt19937 main_prng; #if MPT_MSVC_AT_LEAST(2017,5) && defined(_MSC_FULL_VER) #if (_MSC_FULL_VER < 191225831) // work-around compiler crash // c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.12.25827\include\random(978): fatal error C1001: An internal error has occurred in the compiler. // (compiler file 'f:\dd\vctools\compiler\utc\src\p2\main.c', line 258) // reported at: https://developercommunity.visualstudio.com/content/problem/162089/random-engines-crashing-vs-155-optimizer.html?childToView=164098#comment-164098 typedef std::mt19937_64 best_prng; #else typedef std::ranlux48 best_prng; #endif #else typedef std::ranlux48 best_prng; #endif #endif // MPT_BUILD_FUZZER typedef mpt::main_prng default_prng; typedef mpt::main_prng prng; template inline Trng make_prng(Trd & rd) { return mpt::engine_traits::make(rd); } template class thread_safe_prng : private Trng { private: mpt::mutex m; public: typedef typename Trng::result_type result_type; public: template explicit thread_safe_prng(Trd & rd) : Trng(mpt::make_prng(rd)) { return; } thread_safe_prng(Trng rng) : Trng(rng) { return; } public: static MPT_CONSTEXPR11_FUN typename engine_traits::result_type min() { return Trng::min(); } static MPT_CONSTEXPR11_FUN typename engine_traits::result_type max() { return Trng::max(); } static MPT_CONSTEXPR11_FUN int result_bits() { return engine_traits::result_bits(); } public: typename engine_traits::result_type operator()() { MPT_LOCK_GUARD l(m); return Trng::operator()(); } }; mpt::random_device & global_random_device(); mpt::thread_safe_prng & global_prng(); #if defined(MODPLUG_TRACKER) && !defined(MPT_BUILD_WINESUPPORT) void set_global_random_device(mpt::random_device *rd); void set_global_prng(mpt::thread_safe_prng *rng); #endif // MODPLUG_TRACKER && !MPT_BUILD_WINESUPPORT } // namespace mpt OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/mptLibrary.cpp0000644000372100037210000002421213161656666020420 00000000000000/* * mptLibrary.cpp * -------------- * Purpose: Shared library handling. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "mptLibrary.h" #if defined(MPT_ENABLE_DYNBIND) #if MPT_OS_WINDOWS #include #elif MPT_OS_ANDROID #include #elif defined(MPT_WITH_LTDL) #include #elif defined(MPT_WITH_DL) #include #endif #endif OPENMPT_NAMESPACE_BEGIN #if defined(MPT_ENABLE_DYNBIND) namespace mpt { #if MPT_OS_WINDOWS // KB2533623 / Win8 #ifndef LOAD_LIBRARY_SEARCH_DEFAULT_DIRS #define LOAD_LIBRARY_SEARCH_DEFAULT_DIRS 0x00001000 #endif #ifndef LOAD_LIBRARY_SEARCH_APPLICATION_DIR #define LOAD_LIBRARY_SEARCH_APPLICATION_DIR 0x00000200 #endif #ifndef LOAD_LIBRARY_SEARCH_SYSTEM32 #define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800 #endif #ifndef LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR #define LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR 0x00000100 #endif class LibraryHandle { private: HMODULE hModule; public: LibraryHandle(const mpt::LibraryPath &path) : hModule(NULL) { #if MPT_OS_WINDOWS_WINRT #if (_WIN32_WINNT < 0x0602) (void)path; hModule = NULL; // unsupported #else switch(path.GetSearchPath()) { case mpt::LibrarySearchPathDefault: hModule = LoadPackagedLibrary(path.GetFileName().AsNative().c_str(), 0); break; case mpt::LibrarySearchPathApplication: hModule = LoadPackagedLibrary(path.GetFileName().AsNative().c_str(), 0); break; case mpt::LibrarySearchPathSystem: hModule = NULL; // Only application packaged libraries can be loaded dynamically in WinRT break; case mpt::LibrarySearchPathFullPath: hModule = NULL; // Absolute path is not supported in WinRT break; case mpt::LibrarySearchPathInvalid: MPT_ASSERT_NOTREACHED(); break; } #endif #else // !MPT_OS_WINDOWS_WINRT mpt::Windows::Version WindowsVersion = mpt::Windows::Version::Current(); // Check for KB2533623: bool hasKB2533623 = false; if(WindowsVersion.IsAtLeast(mpt::Windows::Version::Win8)) { hasKB2533623 = true; } else if(WindowsVersion.IsAtLeast(mpt::Windows::Version::WinVista)) { HMODULE hKernel32DLL = LoadLibraryW(L"kernel32.dll"); if(hKernel32DLL) { if(::GetProcAddress(hKernel32DLL, "SetDefaultDllDirectories") != nullptr) { hasKB2533623 = true; } FreeLibrary(hKernel32DLL); hKernel32DLL = NULL; } } if(hasKB2533623) { switch(path.GetSearchPath()) { case mpt::LibrarySearchPathDefault: hModule = LoadLibraryExW(path.GetFileName().AsNative().c_str(), NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); break; case mpt::LibrarySearchPathSystem: hModule = LoadLibraryExW(path.GetFileName().AsNative().c_str(), NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); break; #if defined(MODPLUG_TRACKER) // Using restricted search paths applies to potential DLL dependencies // recursively. // This fails loading for e.g. Codec or Plugin DLLs in application // directory if they depend on the MSVC C or C++ runtime (which is // located in the system directory). // Just rely on the default search path here. case mpt::LibrarySearchPathApplication: { const mpt::PathString dllPath = mpt::GetAppPath(); if(!dllPath.empty() && mpt::PathIsAbsolute(dllPath) && dllPath.IsDirectory()) { hModule = LoadLibraryW((dllPath + path.GetFileName()).AsNative().c_str()); } } break; case mpt::LibrarySearchPathFullPath: hModule = LoadLibraryW(path.GetFileName().AsNative().c_str()); break; #else // For libopenmpt, do the safe thing. case mpt::LibrarySearchPathApplication: hModule = LoadLibraryExW(path.GetFileName().AsNative().c_str(), NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR); break; case mpt::LibrarySearchPathFullPath: hModule = LoadLibraryExW(path.GetFileName().AsNative().c_str(), NULL, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR); break; #endif case mpt::LibrarySearchPathInvalid: MPT_ASSERT_NOTREACHED(); break; } } else { switch(path.GetSearchPath()) { case mpt::LibrarySearchPathDefault: hModule = LoadLibraryW(path.GetFileName().AsNative().c_str()); break; case mpt::LibrarySearchPathApplication: { const mpt::PathString dllPath = mpt::GetAppPath(); if(!dllPath.empty() && mpt::PathIsAbsolute(dllPath) && dllPath.IsDirectory()) { hModule = LoadLibraryW((dllPath + path.GetFileName()).AsNative().c_str()); } } break; case mpt::LibrarySearchPathSystem: { const mpt::PathString dllPath = mpt::GetSystemPath(); if(!dllPath.empty() && mpt::PathIsAbsolute(dllPath) && dllPath.IsDirectory()) { hModule = LoadLibraryW((dllPath + path.GetFileName()).AsNative().c_str()); } } break; case mpt::LibrarySearchPathFullPath: hModule = LoadLibraryW(path.GetFileName().AsNative().c_str()); break; case mpt::LibrarySearchPathInvalid: MPT_ASSERT_NOTREACHED(); break; } } #endif // MPT_OS_WINDOWS_WINRT } ~LibraryHandle() { if(IsValid()) { FreeLibrary(hModule); } hModule = NULL; } public: bool IsValid() const { return (hModule != NULL); } FuncPtr GetProcAddress(const std::string &symbol) const { if(!IsValid()) { return nullptr; } return reinterpret_cast(::GetProcAddress(hModule, symbol.c_str())); } }; #elif MPT_OS_ANDROID // Fake implementation. // Load shared objects from the JAVA side of things. class LibraryHandle { public: LibraryHandle(const mpt::LibraryPath &path) { return; } ~LibraryHandle() { return; } public: bool IsValid() const { return true; } FuncPtr GetProcAddress(const std::string &symbol) const { if(!IsValid()) { return nullptr; } return reinterpret_cast(dlsym(0, symbol.c_str())); } }; #elif defined(MPT_WITH_LTDL) class LibraryHandle { private: bool inited; lt_dlhandle handle; public: LibraryHandle(const mpt::LibraryPath &path) : inited(false) , handle(0) { if(lt_dlinit() != 0) { return; } inited = true; handle = lt_dlopenext(path.GetFileName().AsNative().c_str()); } ~LibraryHandle() { if(IsValid()) { lt_dlclose(handle); } handle = 0; if(inited) { lt_dlexit(); inited = false; } } public: bool IsValid() const { return handle != 0; } FuncPtr GetProcAddress(const std::string &symbol) const { if(!IsValid()) { return nullptr; } return reinterpret_cast(lt_dlsym(handle, symbol.c_str())); } }; #elif defined(MPT_WITH_DL) class LibraryHandle { private: void* handle; public: LibraryHandle(const mpt::LibraryPath &path) : handle(NULL) { handle = dlopen(path.GetFileName().AsNative().c_str(), RTLD_NOW); } ~LibraryHandle() { if(IsValid()) { dlclose(handle); } handle = NULL; } public: bool IsValid() const { return handle != NULL; } FuncPtr GetProcAddress(const std::string &symbol) const { if(!IsValid()) { return NULL; } return reinterpret_cast(dlsym(handle, symbol.c_str())); } }; #else // MPT_OS // dummy implementation class LibraryHandle { public: LibraryHandle(const mpt::LibraryPath &path) { MPT_UNREFERENCED_PARAMETER(path); return; } ~LibraryHandle() { return; } public: bool IsValid() const { return false; } FuncPtr GetProcAddress(const std::string &symbol) const { MPT_UNREFERENCED_PARAMETER(symbol); if(!IsValid()) { return nullptr; } return nullptr; } }; #endif // MPT_OS LibraryPath::LibraryPath(mpt::LibrarySearchPath searchPath, class mpt::PathString const &fileName) : searchPath(searchPath) , fileName(fileName) { return; } mpt::LibrarySearchPath LibraryPath::GetSearchPath() const { return searchPath; } mpt::PathString LibraryPath::GetFileName() const { return fileName; } mpt::PathString LibraryPath::GetDefaultPrefix() { #if MPT_OS_WINDOWS return MPT_PATHSTRING(""); #elif MPT_OS_ANDROID return MPT_PATHSTRING("lib"); #elif defined(MPT_WITH_LTDL) return MPT_PATHSTRING("lib"); #elif defined(MPT_WITH_DL) return MPT_PATHSTRING("lib"); #else return MPT_PATHSTRING("lib"); #endif } mpt::PathString LibraryPath::GetDefaultSuffix() { #if MPT_OS_WINDOWS return MPT_PATHSTRING(".dll"); #elif MPT_OS_ANDROID return MPT_PATHSTRING(".so"); #elif defined(MPT_WITH_LTDL) return MPT_PATHSTRING(""); // handled by libltdl #elif defined(MPT_WITH_DL) return MPT_PATHSTRING(".so"); #else return mpt::PathString(); #endif } LibraryPath LibraryPath::App(const mpt::PathString &basename) { return LibraryPath(mpt::LibrarySearchPathApplication, GetDefaultPrefix() + basename + GetDefaultSuffix()); } LibraryPath LibraryPath::AppFullName(const mpt::PathString &fullname) { return LibraryPath(mpt::LibrarySearchPathApplication, fullname + GetDefaultSuffix()); } #if defined(MODPLUG_TRACKER) && !defined(MPT_BUILD_WINESUPPORT) LibraryPath LibraryPath::AppDataFullName(const mpt::PathString &fullname, const mpt::PathString &appdata) { if(appdata.empty()) { return LibraryPath(mpt::LibrarySearchPathInvalid, MPT_PATHSTRING("")); } return LibraryPath(mpt::LibrarySearchPathFullPath, appdata.WithTrailingSlash() + fullname + GetDefaultSuffix()); } #endif // MODPLUG_TRACKER && !MPT_BUILD_WINESUPPORT LibraryPath LibraryPath::System(const mpt::PathString &basename) { return LibraryPath(mpt::LibrarySearchPathSystem, GetDefaultPrefix() + basename + GetDefaultSuffix()); } LibraryPath LibraryPath::FullPath(const mpt::PathString &path) { return LibraryPath(mpt::LibrarySearchPathFullPath, path); } Library::Library() { return; } Library::Library(const mpt::LibraryPath &path) { if(path.GetSearchPath() == mpt::LibrarySearchPathInvalid) { return; } if(path.GetFileName().empty()) { return; } m_Handle = std::make_shared(path); } void Library::Unload() { *this = mpt::Library(); } bool Library::IsValid() const { return m_Handle && m_Handle->IsValid(); } FuncPtr Library::GetProcAddress(const std::string &symbol) const { if(!IsValid()) { return nullptr; } return m_Handle->GetProcAddress(symbol); } } // namespace mpt #endif // MPT_ENABLE_DYNBIND OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/Endianness.h0000644000372100037210000010404313076363620020016 00000000000000/* * Endianness.h * ------------ * Purpose: Code for deadling with endianness. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include #include #include #include #if MPT_COMPILER_MSVC #include #endif // Platform has native IEEE floating point representation _AND_ floating point // endianess is the same as integer endianness. // We just test __STDC_IEC_559__ for now. #if MPT_COMPILER_GENERIC #define MPT_PLATFORM_IEEE_FLOAT 0 #elif MPT_COMPILER_MSVC #define MPT_PLATFORM_IEEE_FLOAT 1 #else // MPT_COMPILER #if MPT_PLATFORM_ENDIAN_KNOWN #if defined(__STDC_IEC_559__) #if (__STDC_IEC_559__) #define MPT_PLATFORM_IEEE_FLOAT 1 #else #define MPT_PLATFORM_IEEE_FLOAT 0 #endif #else #define MPT_PLATFORM_IEEE_FLOAT 0 #endif #else #define MPT_PLATFORM_IEEE_FLOAT 0 #endif #endif // MPT_COMPILER #if !MPT_PLATFORM_IEEE_FLOAT #include #endif OPENMPT_NAMESPACE_BEGIN namespace mpt { struct endian_type { uint16 value; }; static MPT_FORCEINLINE bool operator == (const endian_type & a, const endian_type & b) { return a.value == b.value; } static MPT_FORCEINLINE bool operator != (const endian_type & a, const endian_type & b) { return a.value != b.value; } static const endian_type endian_big = { 0x1234u }; static const endian_type endian_little = { 0x3412u }; namespace detail { static MPT_FORCEINLINE endian_type endian_probe() { STATIC_ASSERT(sizeof(endian_type) == 2); const mpt::byte probe[2] = { 0x12, 0x34 }; endian_type test; std::memcpy(&test, probe, 2); return test; } } static MPT_FORCEINLINE endian_type endian() { #if defined(MPT_PLATFORM_LITTLE_ENDIAN) return endian_little; #elif defined(MPT_PLATFORM_BIG_ENDIAN) return endian_big; #else return detail::endian_probe(); #endif } static MPT_FORCEINLINE bool endian_is_little() { return endian() == endian_little; } static MPT_FORCEINLINE bool endian_is_big() { return endian() == endian_big; } } // namespace mpt namespace mpt { namespace detail { enum Endianness { BigEndian, LittleEndian, #if MPT_PLATFORM_ENDIAN_KNOWN #if defined(MPT_PLATFORM_BIG_ENDIAN) NativeEndian = BigEndian, #else NativeEndian = LittleEndian, #endif #endif }; } } // namespace mpt::detail struct BigEndian_tag { static const mpt::detail::Endianness Endianness = mpt::detail::BigEndian; }; struct LittleEndian_tag { static const mpt::detail::Endianness Endianness = mpt::detail::LittleEndian; }; // Ending swaps: // SwapBytesBE(x) and variants may be used either to: // -Convert integer x, which is in big endian format (for example read from file), // to endian format of current architecture. // -Convert value x from endian format of current architecture to big endian format. // Similarly SwapBytesLE(x) converts known little endian format to format of current // endian architecture or value x in format of current architecture to little endian // format. #if MPT_COMPILER_GCC #define MPT_bswap16 __builtin_bswap16 #define MPT_bswap32 __builtin_bswap32 #define MPT_bswap64 __builtin_bswap64 #elif MPT_COMPILER_MSVC #define MPT_bswap16 _byteswap_ushort #define MPT_bswap32 _byteswap_ulong #define MPT_bswap64 _byteswap_uint64 #endif namespace mpt { namespace detail { // catch system macros #ifndef MPT_bswap16 #ifdef bswap16 static MPT_FORCEINLINE uint16 mpt_bswap16(uint16 x) { return bswap16(x); } #define MPT_bswap16 mpt::detail::mpt_bswap16 #endif #endif #ifndef MPT_bswap32 #ifdef bswap32 static MPT_FORCEINLINE uint32 mpt_bswap32(uint32 x) { return bswap32(x); } #define MPT_bswap32 mpt::detail::mpt_bswap32 #endif #endif #ifndef MPT_bswap64 #ifdef bswap64 static MPT_FORCEINLINE uint64 mpt_bswap64(uint64 x) { return bswap64(x); } #define MPT_bswap64 mpt::detail::mpt_bswap64 #endif #endif } } // namespace mpt::detail // No intrinsics available #ifndef MPT_bswap16 #define MPT_bswap16(x) \ ( uint16(0) \ | ((static_cast(x) >> 8) & 0x00FFu) \ | ((static_cast(x) << 8) & 0xFF00u) \ ) \ /**/ #endif #ifndef MPT_bswap32 #define MPT_bswap32(x) \ ( uint32(0) \ | ((static_cast(x) & 0x000000FFu) << 24) \ | ((static_cast(x) & 0x0000FF00u) << 8) \ | ((static_cast(x) & 0x00FF0000u) >> 8) \ | ((static_cast(x) & 0xFF000000u) >> 24) \ ) \ /**/ #endif #ifndef MPT_bswap64 #define MPT_bswap64(x) \ ( uint64(0) \ | (((static_cast(x) >> 0) & 0xffull) << 56) \ | (((static_cast(x) >> 8) & 0xffull) << 48) \ | (((static_cast(x) >> 16) & 0xffull) << 40) \ | (((static_cast(x) >> 24) & 0xffull) << 32) \ | (((static_cast(x) >> 32) & 0xffull) << 24) \ | (((static_cast(x) >> 40) & 0xffull) << 16) \ | (((static_cast(x) >> 48) & 0xffull) << 8) \ | (((static_cast(x) >> 56) & 0xffull) << 0) \ ) \ /**/ #endif #if MPT_PLATFORM_ENDIAN_KNOWN #if defined(MPT_PLATFORM_BIG_ENDIAN) #define MPT_bswap64le(x) MPT_bswap64(x) #define MPT_bswap32le(x) MPT_bswap32(x) #define MPT_bswap16le(x) MPT_bswap16(x) #define MPT_bswap64be(x) (x) #define MPT_bswap32be(x) (x) #define MPT_bswap16be(x) (x) #elif defined(MPT_PLATFORM_LITTLE_ENDIAN) #define MPT_bswap64be(x) MPT_bswap64(x) #define MPT_bswap32be(x) MPT_bswap32(x) #define MPT_bswap16be(x) MPT_bswap16(x) #define MPT_bswap64le(x) (x) #define MPT_bswap32le(x) (x) #define MPT_bswap16le(x) (x) #endif #else // !MPT_PLATFORM_ENDIAN_KNOWN template static MPT_FORCEINLINE std::array EndianEncode(T val) { STATIC_ASSERT(std::numeric_limits::is_integer); STATIC_ASSERT(!std::numeric_limits::is_signed); STATIC_ASSERT(sizeof(T) == size); typedef T base_type; typedef typename std::make_unsigned::type unsigned_base_type; typedef Tendian endian_type; unsigned_base_type uval = static_cast(val); std::array data; MPT_CONSTANT_IF(endian_type::Endianness == mpt::detail::LittleEndian) { for(std::size_t i = 0; i < sizeof(base_type); ++i) { data[i] = static_cast(static_cast((uval >> (i*8)) & 0xffu)); } } else { for(std::size_t i = 0; i < sizeof(base_type); ++i) { data[(sizeof(base_type)-1) - i] = static_cast(static_cast((uval >> (i*8)) & 0xffu)); } } return data; } template static MPT_FORCEINLINE T EndianDecode(std::array data) { STATIC_ASSERT(std::numeric_limits::is_integer); STATIC_ASSERT(!std::numeric_limits::is_signed); STATIC_ASSERT(sizeof(T) == size); typedef T base_type; typedef typename std::make_unsigned::type unsigned_base_type; typedef Tendian endian_type; base_type val = base_type(); unsigned_base_type uval = unsigned_base_type(); MPT_CONSTANT_IF(endian_type::Endianness == mpt::detail::LittleEndian) { for(std::size_t i = 0; i < sizeof(base_type); ++i) { uval |= static_cast(static_cast(data[i])) << (i*8); } } else { for(std::size_t i = 0; i < sizeof(base_type); ++i) { uval |= static_cast(static_cast(data[(sizeof(base_type)-1) - i])) << (i*8); } } val = static_cast(uval); return val; } template static MPT_FORCEINLINE T MPT_bswap_impl(T val) { typedef typename std::make_unsigned::type Tu; std::array data = EndianEncode(val); std::memcpy(&val, data.data(), sizeof(T)); return val; } #define MPT_bswap64be(x) MPT_bswap_impl(x) #define MPT_bswap32be(x) MPT_bswap_impl(x) #define MPT_bswap16be(x) MPT_bswap_impl(x) #define MPT_bswap64le(x) MPT_bswap_impl(x) #define MPT_bswap32le(x) MPT_bswap_impl(x) #define MPT_bswap16le(x) MPT_bswap_impl(x) #endif // MPT_PLATFORM_ENDIAN_KNOWN static MPT_FORCEINLINE uint64 SwapBytesBE(uint64 value) { return MPT_bswap64be(value); } static MPT_FORCEINLINE uint32 SwapBytesBE(uint32 value) { return MPT_bswap32be(value); } static MPT_FORCEINLINE uint16 SwapBytesBE(uint16 value) { return MPT_bswap16be(value); } static MPT_FORCEINLINE uint64 SwapBytesLE(uint64 value) { return MPT_bswap64le(value); } static MPT_FORCEINLINE uint32 SwapBytesLE(uint32 value) { return MPT_bswap32le(value); } static MPT_FORCEINLINE uint16 SwapBytesLE(uint16 value) { return MPT_bswap16le(value); } static MPT_FORCEINLINE int64 SwapBytesBE(int64 value) { return MPT_bswap64be(value); } static MPT_FORCEINLINE int32 SwapBytesBE(int32 value) { return MPT_bswap32be(value); } static MPT_FORCEINLINE int16 SwapBytesBE(int16 value) { return MPT_bswap16be(value); } static MPT_FORCEINLINE int64 SwapBytesLE(int64 value) { return MPT_bswap64le(value); } static MPT_FORCEINLINE int32 SwapBytesLE(int32 value) { return MPT_bswap32le(value); } static MPT_FORCEINLINE int16 SwapBytesLE(int16 value) { return MPT_bswap16le(value); } // Do NOT remove these overloads, even if they seem useless. // We do not want risking to extend 8bit integers to int and then // endian-converting and casting back to int. // Thus these overloads. static MPT_FORCEINLINE uint8 SwapBytesLE(uint8 value) { return value; } static MPT_FORCEINLINE int8 SwapBytesLE(int8 value) { return value; } static MPT_FORCEINLINE char SwapBytesLE(char value) { return value; } static MPT_FORCEINLINE uint8 SwapBytesBE(uint8 value) { return value; } static MPT_FORCEINLINE int8 SwapBytesBE(int8 value) { return value; } static MPT_FORCEINLINE char SwapBytesBE(char value) { return value; } static MPT_FORCEINLINE uint64 SwapBytes(uint64 value) { return MPT_bswap64(value); } static MPT_FORCEINLINE uint32 SwapBytes(uint32 value) { return MPT_bswap32(value); } static MPT_FORCEINLINE uint16 SwapBytes(uint16 value) { return MPT_bswap16(value); } static MPT_FORCEINLINE int64 SwapBytes(int64 value) { return MPT_bswap64(value); } static MPT_FORCEINLINE int32 SwapBytes(int32 value) { return MPT_bswap32(value); } static MPT_FORCEINLINE int16 SwapBytes(int16 value) { return MPT_bswap16(value); } static MPT_FORCEINLINE uint8 SwapBytes(uint8 value) { return value; } static MPT_FORCEINLINE int8 SwapBytes(int8 value) { return value; } static MPT_FORCEINLINE char SwapBytes(char value) { return value; } #undef MPT_bswap16le #undef MPT_bswap32le #undef MPT_bswap64le #undef MPT_bswap16be #undef MPT_bswap32be #undef MPT_bswap64be #undef MPT_bswap16 #undef MPT_bswap32 #undef MPT_bswap64 // 1.0f --> 0x3f800000u static MPT_FORCEINLINE uint32 EncodeIEEE754binary32(float32 f) { #if MPT_PLATFORM_IEEE_FLOAT STATIC_ASSERT(sizeof(uint32) == sizeof(float32)); #if MPT_COMPILER_UNION_TYPE_ALIASES union { float32 f; uint32 i; } conv; conv.f = f; return conv.i; #else uint32 i = 0; std::memcpy(&i, &f, sizeof(float32)); return i; #endif #else int e = 0; float m = std::frexp(f, &e); if(e == 0 && std::fabs(m) == 0.0f) { uint32 expo = 0u; uint32 sign = std::signbit(m) ? 0x01u : 0x00u; uint32 mant = 0u; uint32 i = 0u; i |= (mant << 0) & 0x007fffffu; i |= (expo << 23) & 0x7f800000u; i |= (sign << 31) & 0x80000000u; return i; } else { uint32 expo = e + 127 - 1; uint32 sign = std::signbit(m) ? 0x01u : 0x00u; uint32 mant = static_cast(std::fabs(std::ldexp(m, 24))); uint32 i = 0u; i |= (mant << 0) & 0x007fffffu; i |= (expo << 23) & 0x7f800000u; i |= (sign << 31) & 0x80000000u; return i; } #endif } static MPT_FORCEINLINE uint64 EncodeIEEE754binary64(float64 f) { #if MPT_PLATFORM_IEEE_FLOAT STATIC_ASSERT(sizeof(uint64) == sizeof(float64)); #if MPT_COMPILER_UNION_TYPE_ALIASES union { float64 f; uint64 i; } conv; conv.f = f; return conv.i; #else uint64 i = 0; std::memcpy(&i, &f, sizeof(float64)); return i; #endif #else int e = 0; double m = std::frexp(f, &e); if(e == 0 && std::fabs(m) == 0.0) { uint64 expo = 0u; uint64 sign = std::signbit(m) ? 0x01u : 0x00u; uint64 mant = 0u; uint64 i = 0u; i |= (mant << 0) & 0x000fffffffffffffull; i |= (expo << 52) & 0x7ff0000000000000ull; i |= (sign << 63) & 0x8000000000000000ull; return i; } else { uint64 expo = e + 1023 - 1; uint64 sign = std::signbit(m) ? 0x01u : 0x00u; uint64 mant = static_cast(std::fabs(std::ldexp(m, 53))); uint64 i = 0u; i |= (mant << 0) & 0x000fffffffffffffull; i |= (expo << 52) & 0x7ff0000000000000ull; i |= (sign << 63) & 0x8000000000000000ull; return i; } #endif } // 0x3f800000u --> 1.0f static MPT_FORCEINLINE float32 DecodeIEEE754binary32(uint32 i) { #if MPT_PLATFORM_IEEE_FLOAT STATIC_ASSERT(sizeof(uint32) == sizeof(float32)); #if MPT_COMPILER_UNION_TYPE_ALIASES union { uint32 i; float32 f; } conv; conv.i = i; return conv.f; #else float32 f = 0.0f; std::memcpy(&f, &i, sizeof(float32)); return f; #endif #else uint32 mant = (i & 0x007fffffu) >> 0; uint32 expo = (i & 0x7f800000u) >> 23; uint32 sign = (i & 0x80000000u) >> 31; if(expo == 0) { float m = sign ? -static_cast(mant) : static_cast(mant); int e = expo - 127 + 1 - 24; float f = std::ldexp(m, e); return static_cast(f); } else { mant |= 0x00800000u; float m = sign ? -static_cast(mant) : static_cast(mant); int e = expo - 127 + 1 - 24; float f = std::ldexp(m, e); return static_cast(f); } #endif } static MPT_FORCEINLINE float64 DecodeIEEE754binary64(uint64 i) { #if MPT_PLATFORM_IEEE_FLOAT STATIC_ASSERT(sizeof(uint64) == sizeof(float64)); #if MPT_COMPILER_UNION_TYPE_ALIASES union { uint64 i; float64 f; } conv; conv.i = i; return conv.f; #else float64 f = 0.0; std::memcpy(&f, &i, sizeof(float64)); return f; #endif #else uint64 mant = (i & 0x000fffffffffffffull) >> 0; uint64 expo = (i & 0x7ff0000000000000ull) >> 52; uint64 sign = (i & 0x8000000000000000ull) >> 63; if(expo == 0) { double m = sign ? -static_cast(mant) : static_cast(mant); int e = expo - 1023 + 1 - 53; double f = std::ldexp(m, e); return static_cast(f); } else { mant |= 0x0010000000000000ull; double m = sign ? -static_cast(mant) : static_cast(mant); int e = expo - 1023 + 1 - 53; double f = std::ldexp(m, e); return static_cast(f); } #endif } // template parameters are byte indices corresponding to the individual bytes of iee754 in memory template struct IEEE754binary32Emulated { private: typedef IEEE754binary32Emulated self_t; mpt::byte bytes[4]; public: MPT_FORCEINLINE mpt::byte GetByte(std::size_t i) const { return bytes[i]; } MPT_FORCEINLINE IEEE754binary32Emulated() { } MPT_FORCEINLINE explicit IEEE754binary32Emulated(float32 f) { SetInt32(EncodeIEEE754binary32(f)); } // b0...b3 are in memory order, i.e. depend on the endianness of this type // little endian: (0x00,0x00,0x80,0x3f) // big endian: (0x3f,0x80,0x00,0x00) MPT_FORCEINLINE explicit IEEE754binary32Emulated(mpt::byte b0, mpt::byte b1, mpt::byte b2, mpt::byte b3) { bytes[0] = b0; bytes[1] = b1; bytes[2] = b2; bytes[3] = b3; } MPT_FORCEINLINE operator float32 () const { return DecodeIEEE754binary32(GetInt32()); } MPT_FORCEINLINE self_t & SetInt32(uint32 i) { bytes[hihi] = static_cast(i >> 24); bytes[hilo] = static_cast(i >> 16); bytes[lohi] = static_cast(i >> 8); bytes[lolo] = static_cast(i >> 0); return *this; } MPT_FORCEINLINE uint32 GetInt32() const { return 0u | (static_cast(bytes[hihi]) << 24) | (static_cast(bytes[hilo]) << 16) | (static_cast(bytes[lohi]) << 8) | (static_cast(bytes[lolo]) << 0) ; } MPT_FORCEINLINE bool operator == (const self_t &cmp) const { return true && bytes[0] == cmp.bytes[0] && bytes[1] == cmp.bytes[1] && bytes[2] == cmp.bytes[2] && bytes[3] == cmp.bytes[3] ; } MPT_FORCEINLINE bool operator != (const self_t &cmp) const { return !(*this == cmp); } }; template struct IEEE754binary64Emulated { private: typedef IEEE754binary64Emulated self_t; mpt::byte bytes[8]; public: MPT_FORCEINLINE mpt::byte GetByte(std::size_t i) const { return bytes[i]; } MPT_FORCEINLINE IEEE754binary64Emulated() { } MPT_FORCEINLINE explicit IEEE754binary64Emulated(float64 f) { SetInt64(EncodeIEEE754binary64(f)); } MPT_FORCEINLINE explicit IEEE754binary64Emulated(mpt::byte b0, mpt::byte b1, mpt::byte b2, mpt::byte b3, mpt::byte b4, mpt::byte b5, mpt::byte b6, mpt::byte b7) { bytes[0] = b0; bytes[1] = b1; bytes[2] = b2; bytes[3] = b3; bytes[4] = b4; bytes[5] = b5; bytes[6] = b6; bytes[7] = b7; } MPT_FORCEINLINE operator float64 () const { return DecodeIEEE754binary64(GetInt64()); } MPT_FORCEINLINE self_t & SetInt64(uint64 i) { bytes[hihihi] = static_cast(i >> 56); bytes[hihilo] = static_cast(i >> 48); bytes[hilohi] = static_cast(i >> 40); bytes[hilolo] = static_cast(i >> 32); bytes[lohihi] = static_cast(i >> 24); bytes[lohilo] = static_cast(i >> 16); bytes[lolohi] = static_cast(i >> 8); bytes[lololo] = static_cast(i >> 0); return *this; } MPT_FORCEINLINE uint64 GetInt64() const { return 0u | (static_cast(bytes[hihihi]) << 56) | (static_cast(bytes[hihilo]) << 48) | (static_cast(bytes[hilohi]) << 40) | (static_cast(bytes[hilolo]) << 32) | (static_cast(bytes[lohihi]) << 24) | (static_cast(bytes[lohilo]) << 16) | (static_cast(bytes[lolohi]) << 8) | (static_cast(bytes[lololo]) << 0) ; } MPT_FORCEINLINE bool operator == (const self_t &cmp) const { return true && bytes[0] == cmp.bytes[0] && bytes[1] == cmp.bytes[1] && bytes[2] == cmp.bytes[2] && bytes[3] == cmp.bytes[3] && bytes[4] == cmp.bytes[4] && bytes[5] == cmp.bytes[5] && bytes[6] == cmp.bytes[6] && bytes[7] == cmp.bytes[7] ; } MPT_FORCEINLINE bool operator != (const self_t &cmp) const { return !(*this == cmp); } }; typedef IEEE754binary32Emulated<0,1,2,3> IEEE754binary32EmulatedBE; typedef IEEE754binary32Emulated<3,2,1,0> IEEE754binary32EmulatedLE; typedef IEEE754binary64Emulated<0,1,2,3,4,5,6,7> IEEE754binary64EmulatedBE; typedef IEEE754binary64Emulated<7,6,5,4,3,2,1,0> IEEE754binary64EmulatedLE; MPT_BINARY_STRUCT(IEEE754binary32EmulatedBE, 4) MPT_BINARY_STRUCT(IEEE754binary32EmulatedLE, 4) MPT_BINARY_STRUCT(IEEE754binary64EmulatedBE, 8) MPT_BINARY_STRUCT(IEEE754binary64EmulatedLE, 8) #if MPT_PLATFORM_IEEE_FLOAT struct IEEE754binary32Native { private: float32 value; public: MPT_FORCEINLINE mpt::byte GetByte(std::size_t i) const { #if defined(MPT_PLATFORM_LITTLE_ENDIAN) return static_cast(EncodeIEEE754binary32(value) >> (i*8)); #elif defined(MPT_PLATFORM_BIG_ENDIAN) return static_cast(EncodeIEEE754binary32(value) >> ((4-1-i)*8)); #else STATIC_ASSERT(false); #endif } MPT_FORCEINLINE IEEE754binary32Native() { } MPT_FORCEINLINE explicit IEEE754binary32Native(float32 f) { value = f; } // b0...b3 are in memory order, i.e. depend on the endianness of this type // little endian: (0x00,0x00,0x80,0x3f) // big endian: (0x3f,0x80,0x00,0x00) MPT_FORCEINLINE explicit IEEE754binary32Native(mpt::byte b0, mpt::byte b1, mpt::byte b2, mpt::byte b3) { #if defined(MPT_PLATFORM_LITTLE_ENDIAN) value = DecodeIEEE754binary32(0u | (static_cast(b0) << 0) | (static_cast(b1) << 8) | (static_cast(b2) << 16) | (static_cast(b3) << 24) ); #elif defined(MPT_PLATFORM_BIG_ENDIAN) value = DecodeIEEE754binary32(0u | (static_cast(b0) << 24) | (static_cast(b1) << 16) | (static_cast(b2) << 8) | (static_cast(b3) << 0) ); #else STATIC_ASSERT(false); #endif } MPT_FORCEINLINE operator float32 () const { return value; } MPT_FORCEINLINE IEEE754binary32Native & SetInt32(uint32 i) { value = DecodeIEEE754binary32(i); return *this; } MPT_FORCEINLINE uint32 GetInt32() const { return EncodeIEEE754binary32(value); } MPT_FORCEINLINE bool operator == (const IEEE754binary32Native &cmp) const { return value == cmp.value; } MPT_FORCEINLINE bool operator != (const IEEE754binary32Native &cmp) const { return value != cmp.value; } }; struct IEEE754binary64Native { private: float64 value; public: MPT_FORCEINLINE mpt::byte GetByte(std::size_t i) const { #if defined(MPT_PLATFORM_LITTLE_ENDIAN) return static_cast(EncodeIEEE754binary64(value) >> (i*8)); #elif defined(MPT_PLATFORM_BIG_ENDIAN) return static_cast(EncodeIEEE754binary64(value) >> ((8-1-i)*8)); #else STATIC_ASSERT(false); #endif } MPT_FORCEINLINE IEEE754binary64Native() { } MPT_FORCEINLINE explicit IEEE754binary64Native(float64 f) { value = f; } MPT_FORCEINLINE explicit IEEE754binary64Native(mpt::byte b0, mpt::byte b1, mpt::byte b2, mpt::byte b3, mpt::byte b4, mpt::byte b5, mpt::byte b6, mpt::byte b7) { #if defined(MPT_PLATFORM_LITTLE_ENDIAN) value = DecodeIEEE754binary64(0ull | (static_cast(b0) << 0) | (static_cast(b1) << 8) | (static_cast(b2) << 16) | (static_cast(b3) << 24) | (static_cast(b4) << 32) | (static_cast(b5) << 40) | (static_cast(b6) << 48) | (static_cast(b7) << 56) ); #elif defined(MPT_PLATFORM_BIG_ENDIAN) value = DecodeIEEE754binary64(0ull | (static_cast(b0) << 56) | (static_cast(b1) << 48) | (static_cast(b2) << 40) | (static_cast(b3) << 32) | (static_cast(b4) << 24) | (static_cast(b5) << 16) | (static_cast(b6) << 8) | (static_cast(b7) << 0) ); #else STATIC_ASSERT(false); #endif } MPT_FORCEINLINE operator float64 () const { return value; } MPT_FORCEINLINE IEEE754binary64Native & SetInt64(uint64 i) { value = DecodeIEEE754binary64(i); return *this; } MPT_FORCEINLINE uint64 GetInt64() const { return EncodeIEEE754binary64(value); } MPT_FORCEINLINE bool operator == (const IEEE754binary64Native &cmp) const { return value == cmp.value; } MPT_FORCEINLINE bool operator != (const IEEE754binary64Native &cmp) const { return value != cmp.value; } }; STATIC_ASSERT(sizeof(IEEE754binary32Native) == 4); STATIC_ASSERT(sizeof(IEEE754binary64Native) == 8); #if MPT_PLATFORM_IEEE_FLOAT namespace mpt { template <> struct is_binary_safe< IEEE754binary32Native > : public std::true_type { }; template <> struct is_binary_safe< IEEE754binary64Native > : public std::true_type { }; } #endif // MPT_PLATFORM_IEEE_FLOAT #if defined(MPT_PLATFORM_LITTLE_ENDIAN) typedef IEEE754binary32Native IEEE754binary32LE; typedef IEEE754binary32EmulatedBE IEEE754binary32BE; typedef IEEE754binary64Native IEEE754binary64LE; typedef IEEE754binary64EmulatedBE IEEE754binary64BE; #elif defined(MPT_PLATFORM_BIG_ENDIAN) typedef IEEE754binary32EmulatedLE IEEE754binary32LE; typedef IEEE754binary32Native IEEE754binary32BE; typedef IEEE754binary64EmulatedLE IEEE754binary64LE; typedef IEEE754binary64Native IEEE754binary64BE; #endif #else // !MPT_PLATFORM_IEEE_FLOAT typedef IEEE754binary32EmulatedLE IEEE754binary32LE; typedef IEEE754binary32EmulatedBE IEEE754binary32BE; typedef IEEE754binary64EmulatedLE IEEE754binary64LE; typedef IEEE754binary64EmulatedBE IEEE754binary64BE; #endif // MPT_PLATFORM_IEEE_FLOAT STATIC_ASSERT(sizeof(IEEE754binary32LE) == 4); STATIC_ASSERT(sizeof(IEEE754binary32BE) == 4); STATIC_ASSERT(sizeof(IEEE754binary64LE) == 8); STATIC_ASSERT(sizeof(IEEE754binary64BE) == 8); typedef IEEE754binary32LE float32le; typedef IEEE754binary32BE float32be; typedef IEEE754binary64LE float64le; typedef IEEE754binary64BE float64be; STATIC_ASSERT(sizeof(float32le) == 4); STATIC_ASSERT(sizeof(float32be) == 4); STATIC_ASSERT(sizeof(float64le) == 8); STATIC_ASSERT(sizeof(float64be) == 8); // On-disk integer types with defined endianness and no alignemnt requirements // Note: To easily debug module loaders (and anything else that uses this // wrapper struct), you can use the Debugger Visualizers available in // build/vs/debug/ to conveniently view the wrapped contents. template struct packed { public: typedef T base_type; typedef Tendian endian_type; private: #if MPT_PLATFORM_ENDIAN_KNOWN mpt::byte data[sizeof(base_type)]; #else // !MPT_PLATFORM_ENDIAN_KNOWN std::array data; #endif // MPT_PLATFORM_ENDIAN_KNOWN public: MPT_FORCEINLINE void set(base_type val) { STATIC_ASSERT(std::numeric_limits::is_integer); #if MPT_PLATFORM_ENDIAN_KNOWN MPT_CONSTANT_IF(mpt::detail::NativeEndian != endian_type::Endianness) { val = SwapBytes(val); } std::memcpy(data, &val, sizeof(val)); #else // !MPT_PLATFORM_ENDIAN_KNOWN typedef typename std::make_unsigned::type unsigned_base_type; data = EndianEncode(val); #endif // MPT_PLATFORM_ENDIAN_KNOWN } MPT_FORCEINLINE base_type get() const { STATIC_ASSERT(std::numeric_limits::is_integer); #if MPT_PLATFORM_ENDIAN_KNOWN base_type val = base_type(); std::memcpy(&val, data, sizeof(val)); MPT_CONSTANT_IF(mpt::detail::NativeEndian != endian_type::Endianness) { val = SwapBytes(val); } return val; #else // !MPT_PLATFORM_ENDIAN_KNOWN typedef typename std::make_unsigned::type unsigned_base_type; return EndianDecode(data); #endif // MPT_PLATFORM_ENDIAN_KNOWN } MPT_FORCEINLINE packed & operator = (const base_type & val) { set(val); return *this; } MPT_FORCEINLINE operator base_type () const { return get(); } public: packed & operator &= (base_type val) { set(get() & val); return *this; } packed & operator |= (base_type val) { set(get() | val); return *this; } packed & operator ^= (base_type val) { set(get() ^ val); return *this; } packed & operator += (base_type val) { set(get() + val); return *this; } packed & operator -= (base_type val) { set(get() - val); return *this; } packed & operator *= (base_type val) { set(get() * val); return *this; } packed & operator /= (base_type val) { set(get() / val); return *this; } packed & operator %= (base_type val) { set(get() % val); return *this; } packed & operator ++ () { set(get() + 1); return *this; } // prefix packed & operator -- () { set(get() - 1); return *this; } // prefix base_type operator ++ (int) { base_type old = get(); set(old + 1); return old; } // postfix base_type operator -- (int) { base_type old = get(); set(old - 1); return old; } // postfix }; typedef packed< int64, LittleEndian_tag> int64le; typedef packed< int32, LittleEndian_tag> int32le; typedef packed< int16, LittleEndian_tag> int16le; typedef packed< int8 , LittleEndian_tag> int8le; typedef packed uint64le; typedef packed uint32le; typedef packed uint16le; typedef packed uint8le; typedef packed< int64, BigEndian_tag> int64be; typedef packed< int32, BigEndian_tag> int32be; typedef packed< int16, BigEndian_tag> int16be; typedef packed< int8 , BigEndian_tag> int8be; typedef packed uint64be; typedef packed uint32be; typedef packed uint16be; typedef packed uint8be; MPT_BINARY_STRUCT(int64le, 8) MPT_BINARY_STRUCT(int32le, 4) MPT_BINARY_STRUCT(int16le, 2) MPT_BINARY_STRUCT(int8le , 1) MPT_BINARY_STRUCT(uint64le, 8) MPT_BINARY_STRUCT(uint32le, 4) MPT_BINARY_STRUCT(uint16le, 2) MPT_BINARY_STRUCT(uint8le , 1) MPT_BINARY_STRUCT(int64be, 8) MPT_BINARY_STRUCT(int32be, 4) MPT_BINARY_STRUCT(int16be, 2) MPT_BINARY_STRUCT(int8be , 1) MPT_BINARY_STRUCT(uint64be, 8) MPT_BINARY_STRUCT(uint32be, 4) MPT_BINARY_STRUCT(uint16be, 2) MPT_BINARY_STRUCT(uint8be , 1) namespace mpt { template struct make_le { typedef packed type; }; template struct make_be { typedef packed type; }; } // namespace mpt // Small helper class to support unaligned memory access on all platforms. // This is only used to make old module loaders work everywhere. // Do not use in new code. template class const_unaligned_ptr_le { public: typedef T value_type; private: const mpt::byte *mem; value_type Read() const { mpt::byte bytes[sizeof(value_type)]; std::memcpy(bytes, mem, sizeof(value_type)); #if defined(MPT_PLATFORM_BIG_ENDIAN) std::reverse(bytes, bytes + sizeof(value_type)); #endif value_type val = value_type(); std::memcpy(&val, bytes, sizeof(value_type)); return val; } public: const_unaligned_ptr_le() : mem(nullptr) {} const_unaligned_ptr_le(const const_unaligned_ptr_le & other) : mem(other.mem) {} const_unaligned_ptr_le & operator = (const const_unaligned_ptr_le & other) { mem = other.mem; return *this; } explicit const_unaligned_ptr_le(const uint8 *mem) : mem(mem) {} explicit const_unaligned_ptr_le(const char *mem) : mem(mpt::byte_cast(mem)) {} const_unaligned_ptr_le & operator += (std::size_t count) { mem += count * sizeof(value_type); return *this; } const_unaligned_ptr_le & operator -= (std::size_t count) { mem -= count * sizeof(value_type); return *this; } const_unaligned_ptr_le & operator ++ () { mem += sizeof(value_type); return *this; } const_unaligned_ptr_le & operator -- () { mem -= sizeof(value_type); return *this; } const_unaligned_ptr_le operator ++ (int) { const_unaligned_ptr_le result = *this; ++result; return result; } const_unaligned_ptr_le operator -- (int) { const_unaligned_ptr_le result = *this; --result; return result; } const_unaligned_ptr_le operator + (std::size_t count) const { const_unaligned_ptr_le result = *this; result += count; return result; } const_unaligned_ptr_le operator - (std::size_t count) const { const_unaligned_ptr_le result = *this; result -= count; return result; } const value_type operator * () const { return Read(); } const value_type operator [] (std::size_t i) const { return *((*this) + i); } operator bool () const { return mem != nullptr; } }; template class const_unaligned_ptr_be { public: typedef T value_type; private: const mpt::byte *mem; value_type Read() const { mpt::byte bytes[sizeof(value_type)]; std::memcpy(bytes, mem, sizeof(value_type)); #if defined(MPT_PLATFORM_LITTLE_ENDIAN) std::reverse(bytes, bytes + sizeof(value_type)); #endif value_type val = value_type(); std::memcpy(&val, bytes, sizeof(value_type)); return val; } public: const_unaligned_ptr_be() : mem(nullptr) {} const_unaligned_ptr_be(const const_unaligned_ptr_be & other) : mem(other.mem) {} const_unaligned_ptr_be & operator = (const const_unaligned_ptr_be & other) { mem = other.mem; return *this; } explicit const_unaligned_ptr_be(const uint8 *mem) : mem(mem) {} explicit const_unaligned_ptr_be(const char *mem) : mem(mpt::byte_cast(mem)) {} const_unaligned_ptr_be & operator += (std::size_t count) { mem += count * sizeof(value_type); return *this; } const_unaligned_ptr_be & operator -= (std::size_t count) { mem -= count * sizeof(value_type); return *this; } const_unaligned_ptr_be & operator ++ () { mem += sizeof(value_type); return *this; } const_unaligned_ptr_be & operator -- () { mem -= sizeof(value_type); return *this; } const_unaligned_ptr_be operator ++ (int) { const_unaligned_ptr_be result = *this; ++result; return result; } const_unaligned_ptr_be operator -- (int) { const_unaligned_ptr_be result = *this; --result; return result; } const_unaligned_ptr_be operator + (std::size_t count) const { const_unaligned_ptr_be result = *this; result += count; return result; } const_unaligned_ptr_be operator - (std::size_t count) const { const_unaligned_ptr_be result = *this; result -= count; return result; } const value_type operator * () const { return Read(); } const value_type operator [] (std::size_t i) const { return *((*this) + i); } operator bool () const { return mem != nullptr; } }; template class const_unaligned_ptr { public: typedef T value_type; private: const mpt::byte *mem; value_type Read() const { value_type val = value_type(); std::memcpy(&val, mem, sizeof(value_type)); return val; } public: const_unaligned_ptr() : mem(nullptr) {} const_unaligned_ptr(const const_unaligned_ptr & other) : mem(other.mem) {} const_unaligned_ptr & operator = (const const_unaligned_ptr & other) { mem = other.mem; return *this; } explicit const_unaligned_ptr(const uint8 *mem) : mem(mem) {} explicit const_unaligned_ptr(const char *mem) : mem(mpt::byte_cast(mem)) {} const_unaligned_ptr & operator += (std::size_t count) { mem += count * sizeof(value_type); return *this; } const_unaligned_ptr & operator -= (std::size_t count) { mem -= count * sizeof(value_type); return *this; } const_unaligned_ptr & operator ++ () { mem += sizeof(value_type); return *this; } const_unaligned_ptr & operator -- () { mem -= sizeof(value_type); return *this; } const_unaligned_ptr operator ++ (int) { const_unaligned_ptr result = *this; ++result; return result; } const_unaligned_ptr operator -- (int) { const_unaligned_ptr result = *this; --result; return result; } const_unaligned_ptr operator + (std::size_t count) const { const_unaligned_ptr result = *this; result += count; return result; } const_unaligned_ptr operator - (std::size_t count) const { const_unaligned_ptr result = *this; result -= count; return result; } const value_type operator * () const { return Read(); } const value_type operator [] (std::size_t i) const { return *((*this) + i); } operator bool () const { return mem != nullptr; } }; OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/mptBufferIO.h0000644000372100037210000001066612572534475020130 00000000000000/* * mptBufferIO.h * ------------- * Purpose: A wrapper around std::stringstream, fixing MSVC tell/seek problems with empty streams. * Notes : You should only ever use these wrappers instead of plain std::stringstream classes. * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include #include #include #include #include OPENMPT_NAMESPACE_BEGIN // MSVC std::stringbuf (and thereby std::ostringstream, std::istringstream and // std::stringstream) fail seekpos() and seekoff() when the stringbuf is // currently empty. // seekpos() and seekoff() can get called via tell*() or seek*() iostream // members. seekoff() (and thereby tell*()), but not seekpos(), has been fixed // from VS2010 onwards to handle this specific case and changed to not fail // when the stringbuf is empty. // Work-around strategy: // As re-implementing or duplicating the whole std::stringbuf semantics would be // rather convoluted, we make use of the knowledge of specific inner workings of // the MSVC implementation here and just fix-up where it causes problems. This // keeps the additional code at a minimum size. namespace mpt { #if MPT_COMPILER_MSVC class stringbuf : public std::stringbuf { public: stringbuf(std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) : std::stringbuf(mode) { return; } stringbuf(const std::string &str, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) : std::stringbuf(str, mode) { return; } public: virtual pos_type seekoff(off_type off, std::ios_base::seekdir way, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out) { pos_type result = std::stringbuf::seekoff(off, way, which); if(result == pos_type(-1)) { if((which & std::ios_base::in) || (which & std::ios_base::out)) { if(off == 0) { result = 0; } } } return result; } virtual pos_type seekpos(pos_type ptr, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) { pos_type result = std::stringbuf::seekpos(ptr, mode); if(result == pos_type(-1)) { if((mode & std::ios_base::in) || (mode & std::ios_base::out)) { if(static_cast(ptr) == 0) { result = 0; } } } return result; } }; class istringstream : public std::basic_istream { private: mpt::stringbuf buf; public: istringstream(std::ios_base::openmode mode = std::ios_base::in) : std::basic_istream(&buf) , buf(mode | std::ios_base::in) { } istringstream(const std::string &str, std::ios_base::openmode mode = std::ios_base::in) : std::basic_istream(&buf) , buf(str, mode | std::ios_base::in) { } ~istringstream() { } public: mpt::stringbuf *rdbuf() const { return const_cast(&buf); } std::string str() const { return buf.str(); } void str(const std::string &str) { buf.str(str); } }; class ostringstream : public std::basic_ostream { private: mpt::stringbuf buf; public: ostringstream(std::ios_base::openmode mode = std::ios_base::out) : std::basic_ostream(&buf) , buf(mode | std::ios_base::out) { } ostringstream(const std::string &str, std::ios_base::openmode mode = std::ios_base::out) : std::basic_ostream(&buf) , buf(str, mode | std::ios_base::out) { } ~ostringstream() { } public: mpt::stringbuf *rdbuf() const { return const_cast(&buf); } std::string str() const { return buf.str(); } void str(const std::string &str) { buf.str(str); } }; class stringstream : public std::basic_iostream { private: mpt::stringbuf buf; public: stringstream(std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) : std::basic_iostream(&buf) , buf(mode | std::ios_base::in | std::ios_base::out) { } stringstream(const std::string &str, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) : std::basic_iostream(&buf) , buf(str, mode | std::ios_base::in | std::ios_base::out) { } ~stringstream() { } public: mpt::stringbuf *rdbuf() const { return const_cast(&buf); } std::string str() const { return buf.str(); } void str(const std::string &str) { buf.str(str); } }; #else typedef std::stringbuf stringbuf; typedef std::istringstream istringstream; typedef std::ostringstream ostringstream; typedef std::stringstream stringstream; #endif } // namespace mpt OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/mptPathString.cpp0000644000372100037210000005046313166633425021077 00000000000000/* * mptPathString.cpp * ----------------- * Purpose: Wrapper class around the platform-native representation of path names. Should be the only type that is used to store path names. * Notes : Currently none. * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "mptPathString.h" #include "misc_util.h" #include "mptUUID.h" #if MPT_OS_WINDOWS #include #if defined(MODPLUG_TRACKER) #include #endif #endif #if MPT_OS_WINDOWS && MPT_OS_WINDOWS_WINRT #if defined(__MINGW32__) || defined(__MINGW64__) // MinGW-w64 headers do not declare this for WinRT, which is wrong. extern "C" { WINBASEAPI DWORD WINAPI GetFullPathNameW(LPCWSTR lpFileName, DWORD nBufferLength, LPWSTR lpBuffer, LPWSTR *lpFilePart); } #endif #endif OPENMPT_NAMESPACE_BEGIN #if MPT_OS_WINDOWS #define MPT_PATHSTRING_LITERAL(x) ( L ## x ) #else #define MPT_PATHSTRING_LITERAL(x) ( x ) #endif #if MPT_OS_WINDOWS namespace mpt { RawPathString PathString::AsNativePrefixed() const { if(path.length() <= MAX_PATH || path.substr(0, 4) == MPT_PATHSTRING_LITERAL("\\\\?\\")) { // Path is short enough or already in prefixed form return path; } const RawPathString absPath = mpt::GetAbsolutePath(path).AsNative(); if(absPath.substr(0, 2) == MPT_PATHSTRING_LITERAL("\\\\")) { // Path is a network share: \\server\foo.bar -> \\?\UNC\server\foo.bar return MPT_PATHSTRING_LITERAL("\\\\?\\UNC") + absPath.substr(1); } else { // Regular file: C:\foo.bar -> \\?\C:\foo.bar return MPT_PATHSTRING_LITERAL("\\\\?\\") + absPath; } } #if !MPT_OS_WINDOWS_WINRT int PathString::CompareNoCase(const PathString & a, const PathString & b) { return lstrcmpiW(a.path.c_str(), b.path.c_str()); } #endif // !MPT_OS_WINDOWS_WINRT // Convert a path to its simplified form, i.e. remove ".\" and "..\" entries // Note: We use our own implementation as PathCanonicalize is limited to MAX_PATH // and unlimited versions are only available on Windows 8 and later. // Furthermore, we also convert forward-slashes to backslashes and always remove trailing slashes. PathString PathString::Simplify() const { if(path.empty()) return PathString(); std::vector components; RawPathString root; RawPathString::size_type startPos = 0; if(path.size() >= 2 && path[1] == MPT_PATHSTRING_LITERAL(':')) { // Drive letter root = path.substr(0, 2) + MPT_PATHSTRING_LITERAL('\\'); startPos = 2; } else if(path.substr(0, 2) == MPT_PATHSTRING_LITERAL("\\\\")) { // Network share root = MPT_PATHSTRING_LITERAL("\\\\"); startPos = 2; } else if(path.substr(0, 2) == MPT_PATHSTRING_LITERAL(".\\") || path.substr(0, 2) == MPT_PATHSTRING_LITERAL("./")) { // Special case for relative paths root = MPT_PATHSTRING_LITERAL(".\\"); startPos = 2; } else if(path.size() >= 1 && (path[0] == MPT_PATHSTRING_LITERAL('\\') || path[0] == MPT_PATHSTRING_LITERAL('/'))) { // Special case for relative paths root = MPT_PATHSTRING_LITERAL("\\"); startPos = 1; } while(startPos < path.size()) { auto pos = path.find_first_of(MPT_PATHSTRING_LITERAL("\\/"), startPos); if(pos == RawPathString::npos) pos = path.size(); mpt::RawPathString dir = path.substr(startPos, pos - startPos); if(dir == MPT_PATHSTRING_LITERAL("..")) { // Go back one directory if(!components.empty()) { components.pop_back(); } } else if(dir == MPT_PATHSTRING_LITERAL(".")) { // nop } else if(!dir.empty()) { components.push_back(std::move(dir)); } startPos = pos + 1; } RawPathString result = root; result.reserve(path.size()); for(const auto &component : components) { result += component + MPT_PATHSTRING_LITERAL("\\"); } if(!components.empty()) result.pop_back(); return result; } } // namespace mpt #endif // MPT_OS_WINDOWS namespace mpt { #if MPT_OS_WINDOWS && (defined(MPT_ENABLE_DYNBIND) || defined(MPT_ENABLE_TEMPFILE)) void PathString::SplitPath(PathString *drive, PathString *dir, PathString *fname, PathString *ext) const { // We cannot use CRT splitpath here, because: // * limited to _MAX_PATH or similar // * no support for UNC paths // * no support for \\?\ prefixed paths if(drive) *drive = mpt::PathString(); if(dir) *dir = mpt::PathString(); if(fname) *fname = mpt::PathString(); if(ext) *ext = mpt::PathString(); mpt::RawPathString p = path; // remove \\?\\ prefix if(p.substr(0, 8) == MPT_PATHSTRING_LITERAL("\\\\?\\UNC\\")) { p = MPT_PATHSTRING_LITERAL("\\\\") + p.substr(8); } else if(p.substr(0, 4) == MPT_PATHSTRING_LITERAL("\\\\?\\")) { p = p.substr(4); } if (p.length() >= 2 && ( p.substr(0, 2) == MPT_PATHSTRING_LITERAL("\\\\") || p.substr(0, 2) == MPT_PATHSTRING_LITERAL("\\/") || p.substr(0, 2) == MPT_PATHSTRING_LITERAL("/\\") || p.substr(0, 2) == MPT_PATHSTRING_LITERAL("//") )) { // UNC mpt::RawPathString::size_type first_slash = p.substr(2).find_first_of(MPT_PATHSTRING_LITERAL("\\/")); if(first_slash != mpt::RawPathString::npos) { mpt::RawPathString::size_type second_slash = p.substr(2 + first_slash + 1).find_first_of(MPT_PATHSTRING_LITERAL("\\/")); if(second_slash != mpt::RawPathString::npos) { if(drive) *drive = mpt::PathString::FromNative(p.substr(0, 2 + first_slash + 1 + second_slash)); p = p.substr(2 + first_slash + 1 + second_slash); } else { if(drive) *drive = mpt::PathString::FromNative(p); p = mpt::RawPathString(); } } else { if(drive) *drive = mpt::PathString::FromNative(p); p = mpt::RawPathString(); } } else { // local if(p.length() >= 2 && (p[1] == MPT_PATHSTRING_LITERAL(':'))) { if(drive) *drive = mpt::PathString::FromNative(p.substr(0, 2)); p = p.substr(2); } else { if(drive) *drive = mpt::PathString(); } } mpt::RawPathString::size_type last_slash = p.find_last_of(MPT_PATHSTRING_LITERAL("\\/")); if(last_slash != mpt::RawPathString::npos) { if(dir) *dir = mpt::PathString::FromNative(p.substr(0, last_slash + 1)); p = p.substr(last_slash + 1); } else { if(dir) *dir = mpt::PathString(); } mpt::RawPathString::size_type last_dot = p.find_last_of(MPT_PATHSTRING_LITERAL(".")); if(last_dot == mpt::RawPathString::npos) { if(fname) *fname = mpt::PathString::FromNative(p); if(ext) *ext = mpt::PathString(); } else { if(fname) *fname = mpt::PathString::FromNative(p.substr(0, last_dot)); if(ext) *ext = mpt::PathString::FromNative(p.substr(last_dot)); } } PathString PathString::GetDrive() const { PathString drive; SplitPath(&drive, nullptr, nullptr, nullptr); return drive; } PathString PathString::GetDir() const { PathString dir; SplitPath(nullptr, &dir, nullptr, nullptr); return dir; } PathString PathString::GetPath() const { PathString drive, dir; SplitPath(&drive, &dir, nullptr, nullptr); return drive + dir; } PathString PathString::GetFileName() const { PathString fname; SplitPath(nullptr, nullptr, &fname, nullptr); return fname; } PathString PathString::GetFileExt() const { PathString ext; SplitPath(nullptr, nullptr, nullptr, &ext); return ext; } PathString PathString::GetFullFileName() const { PathString name, ext; SplitPath(nullptr, nullptr, &name, &ext); return name + ext; } bool PathString::IsDirectory() const { // Using PathIsDirectoryW here instead would increase libopenmpt dependencies by shlwapi.dll. // GetFileAttributesW also does the job just fine. #if MPT_OS_WINDOWS_WINRT WIN32_FILE_ATTRIBUTE_DATA data; MemsetZero(data); if(::GetFileAttributesExW(path.c_str(), GetFileExInfoStandard, &data) == 0) { return false; } DWORD dwAttrib = data.dwFileAttributes; #else // !MPT_OS_WINDOWS_WINRT DWORD dwAttrib = ::GetFileAttributesW(path.c_str()); #endif // MPT_OS_WINDOWS_WINRT return ((dwAttrib != INVALID_FILE_ATTRIBUTES) && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); } bool PathString::IsFile() const { #if MPT_OS_WINDOWS_WINRT WIN32_FILE_ATTRIBUTE_DATA data; MemsetZero(data); if (::GetFileAttributesExW(path.c_str(), GetFileExInfoStandard, &data) == 0) { return false; } DWORD dwAttrib = data.dwFileAttributes; #else // !MPT_OS_WINDOWS_WINRT DWORD dwAttrib = ::GetFileAttributesW(path.c_str()); #endif // MPT_OS_WINDOWS_WINRT return ((dwAttrib != INVALID_FILE_ATTRIBUTES) && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); } #endif // MPT_OS_WINDOWS && (MPT_ENABLE_DYNBIND || MPT_ENABLE_TEMPFILE) #if defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS bool PathString::FileOrDirectoryExists() const { return ::PathFileExistsW(path.c_str()) != FALSE; } #endif // MODPLUG_TRACKER && MPT_OS_WINDOWS #if defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS PathString PathString::ReplaceExt(const mpt::PathString &newExt) const { return GetDrive() + GetDir() + GetFileName() + newExt; } PathString PathString::SanitizeComponent() const { PathString result = *this; SanitizeFilename(result); return result; } // Convert an absolute path to a path that's relative to "&relativeTo". PathString PathString::AbsolutePathToRelative(const PathString &relativeTo) const { mpt::PathString result = path; if(path.empty()) { return result; } if(!_wcsnicmp(relativeTo.AsNative().c_str(), AsNative().c_str(), relativeTo.AsNative().length())) { // Path is OpenMPT's directory or a sub directory ("C:\OpenMPT\Somepath" => ".\Somepath") result = MPT_PATHSTRING(".\\"); // ".\" result += mpt::PathString::FromNative(AsNative().substr(relativeTo.AsNative().length())); } else if(!_wcsnicmp(relativeTo.AsNative().c_str(), AsNative().c_str(), 2)) { // Path is on the same drive as OpenMPT ("C:\Somepath" => "\Somepath") result = mpt::PathString::FromNative(AsNative().substr(2)); } return result; } // Convert a path that is relative to "&relativeTo" to an absolute path. PathString PathString::RelativePathToAbsolute(const PathString &relativeTo) const { mpt::PathString result = path; if(path.empty()) { return result; } if(path.length() >= 2 && path.at(0) == MPT_PATHSTRING_LITERAL('\\') && path.at(1) != MPT_PATHSTRING_LITERAL('\\')) { // Path is on the same drive as OpenMPT ("\Somepath\" => "C:\Somepath\"), but ignore network paths starting with "\\" result = mpt::PathString::FromNative(relativeTo.AsNative().substr(0, 2)); result += path; } else if(path.length() >= 2 && path.substr(0, 2) == MPT_PATHSTRING_LITERAL(".\\")) { // Path is OpenMPT's directory or a sub directory (".\Somepath\" => "C:\OpenMPT\Somepath\") result = relativeTo; // "C:\OpenMPT\" result += mpt::PathString::FromNative(AsNative().substr(2)); } return result; } #if defined(_MFC_VER) mpt::PathString PathString::TunnelOutofCString(const CString &path) { #ifdef UNICODE return mpt::PathString::FromWide(path.GetString()); #else // Since MFC code can call into our code from a lot of places, we cannot assume // that filenames we get from MFC are always encoded in our hacked UTF8-in-CString encoding. // Instead, we use a rough heuristic: if the string is parseable as UTF8, we assume it is. // This fails for CP_ACP strings, that are also valid UTF8. That's the trade-off here. if(mpt::IsUTF8(path.GetString())) { // utf8 return mpt::PathString::FromUTF8(path.GetString()); } else { // ANSI return mpt::PathString::FromWide(mpt::ToWide(path)); } #endif } CString PathString::TunnelIntoCString(const mpt::PathString &path) { #ifdef UNICODE return path.ToWide().c_str(); #else return path.ToUTF8().c_str(); #endif } #endif // MFC #endif // MODPLUG_TRACKER && MPT_OS_WINDOWS } // namespace mpt namespace mpt { bool IsPathSeparator(mpt::RawPathString::value_type c) { #if MPT_OS_WINDOWS return (c == MPT_PATHSTRING_LITERAL('\\')) || (c == MPT_PATHSTRING_LITERAL('/')); #else return c == MPT_PATHSTRING_LITERAL('/'); #endif } bool PathIsAbsolute(const mpt::PathString &path) { mpt::RawPathString rawpath = path.AsNative(); #if MPT_OS_WINDOWS if(rawpath.substr(0, 8) == MPT_PATHSTRING_LITERAL("\\\\?\\UNC\\")) { return true; } if(rawpath.substr(0, 4) == MPT_PATHSTRING_LITERAL("\\\\?\\")) { return true; } if(rawpath.substr(0, 2) == MPT_PATHSTRING_LITERAL("\\\\")) { return true; // UNC } if(rawpath.substr(0, 2) == MPT_PATHSTRING_LITERAL("//")) { return true; // UNC } return (rawpath.length()) >= 3 && (rawpath[1] == ':') && IsPathSeparator(rawpath[2]); #else return (rawpath.length() >= 1) && IsPathSeparator(rawpath[0]); #endif } #if MPT_OS_WINDOWS mpt::PathString GetAbsolutePath(const mpt::PathString &path) { DWORD size = GetFullPathNameW(path.AsNative().c_str(), 0, nullptr, nullptr); if(size == 0) { return path; } std::vector fullPathName(size, L'\0'); if(GetFullPathNameW(path.AsNative().c_str(), size, fullPathName.data(), nullptr) == 0) { return path; } return mpt::PathString::FromNative(fullPathName.data()); } #ifdef MODPLUG_TRACKER bool DeleteWholeDirectoryTree(mpt::PathString path) { if(path.AsNative().empty()) { return false; } if(PathIsRelativeW(path.AsNative().c_str()) == TRUE) { return false; } if(!path.FileOrDirectoryExists()) { return true; } if(!path.IsDirectory()) { return false; } path.EnsureTrailingSlash(); HANDLE hFind = NULL; WIN32_FIND_DATAW wfd; MemsetZero(wfd); hFind = FindFirstFileW((path + MPT_PATHSTRING("*.*")).AsNative().c_str(), &wfd); if(hFind != NULL && hFind != INVALID_HANDLE_VALUE) { do { mpt::PathString filename = mpt::PathString::FromNative(wfd.cFileName); if(filename != MPT_PATHSTRING(".") && filename != MPT_PATHSTRING("..")) { filename = path + filename; if(filename.IsDirectory()) { if(!DeleteWholeDirectoryTree(filename)) { return false; } } else if(filename.IsFile()) { if(DeleteFileW(filename.AsNative().c_str()) == 0) { return false; } } } } while(FindNextFileW(hFind, &wfd)); FindClose(hFind); } if(RemoveDirectoryW(path.AsNative().c_str()) == 0) { return false; } return true; } #endif // MODPLUG_TRACKER #endif // MPT_OS_WINDOWS #if MPT_OS_WINDOWS #if defined(MPT_ENABLE_DYNBIND) || defined(MPT_ENABLE_TEMPFILE) mpt::PathString GetAppPath() { std::vector exeFileName(MAX_PATH); while(GetModuleFileNameW(0, exeFileName.data(), mpt::saturate_cast(exeFileName.size())) >= exeFileName.size()) { if(GetLastError() != ERROR_INSUFFICIENT_BUFFER) { return mpt::PathString(); } exeFileName.resize(exeFileName.size() * 2); } return mpt::GetAbsolutePath(mpt::PathString::FromNative(exeFileName.data()).GetPath()); } #endif // MPT_ENABLE_DYNBIND || MPT_ENABLE_TEMPFILE #if defined(MPT_ENABLE_DYNBIND) #if !MPT_OS_WINDOWS_WINRT mpt::PathString GetSystemPath() { DWORD size = GetSystemDirectoryW(nullptr, 0); std::vector path(size + 1); if(!GetSystemDirectoryW(path.data(), size + 1)) { return mpt::PathString(); } return mpt::PathString::FromNative(path.data()) + MPT_PATHSTRING("\\"); } #endif // !MPT_OS_WINDOWS_WINRT #endif // MPT_ENABLE_DYNBIND #endif // MPT_OS_WINDOWS #if defined(MPT_ENABLE_TEMPFILE) #if MPT_OS_WINDOWS mpt::PathString GetTempDirectory() { DWORD size = GetTempPathW(0, nullptr); if(size) { std::vector tempPath(size + 1); if(GetTempPathW(size + 1, tempPath.data())) { return mpt::PathString::FromNative(tempPath.data()); } } // use app directory as fallback return mpt::GetAppPath(); } mpt::PathString CreateTempFileName(const mpt::PathString &fileNamePrefix, const mpt::PathString &fileNameExtension) { mpt::PathString filename = mpt::GetTempDirectory(); filename += (!fileNamePrefix.empty() ? fileNamePrefix + MPT_PATHSTRING("_") : mpt::PathString()); filename += mpt::PathString::FromUnicode(mpt::UUID::GenerateLocalUseOnly().ToUString()); filename += (!fileNameExtension.empty() ? MPT_PATHSTRING(".") + fileNameExtension : mpt::PathString()); return filename; } TempFileGuard::TempFileGuard(const mpt::PathString &filename) : filename(filename) { return; } mpt::PathString TempFileGuard::GetFilename() const { return filename; } TempFileGuard::~TempFileGuard() { if(!filename.empty()) { DeleteFileW(filename.AsNative().c_str()); } } #ifdef MODPLUG_TRACKER TempDirGuard::TempDirGuard(const mpt::PathString &dirname_) : dirname(dirname_.WithTrailingSlash()) { if(dirname.empty()) { return; } if(::CreateDirectoryW(dirname.AsNative().c_str(), NULL) == 0) { // fail dirname = mpt::PathString(); } } mpt::PathString TempDirGuard::GetDirname() const { return dirname; } TempDirGuard::~TempDirGuard() { if(!dirname.empty()) { DeleteWholeDirectoryTree(dirname); } } #endif // MODPLUG_TRACKER #endif // MPT_OS_WINDOWS #endif // MPT_ENABLE_TEMPFILE } // namespace mpt #if defined(MODPLUG_TRACKER) static inline char SanitizeFilenameChar(char c) { if( c == '\\' || c == '\"' || c == '/' || c == ':' || c == '?' || c == '<' || c == '>' || c == '|' || c == '*') { c = '_'; } return c; } static inline wchar_t SanitizeFilenameChar(wchar_t c) { if( c == L'\\' || c == L'\"' || c == L'/' || c == L':' || c == L'?' || c == L'<' || c == L'>' || c == L'|' || c == L'*') { c = L'_'; } return c; } void SanitizeFilename(mpt::PathString &filename) { mpt::RawPathString tmp = filename.AsNative(); for(auto &c : tmp) { c = SanitizeFilenameChar(c); } filename = mpt::PathString::FromNative(tmp); } void SanitizeFilename(char *beg, char *end) { for(char *it = beg; it != end; ++it) { *it = SanitizeFilenameChar(*it); } } void SanitizeFilename(wchar_t *beg, wchar_t *end) { for(wchar_t *it = beg; it != end; ++it) { *it = SanitizeFilenameChar(*it); } } void SanitizeFilename(std::string &str) { for(size_t i = 0; i < str.length(); i++) { str[i] = SanitizeFilenameChar(str[i]); } } void SanitizeFilename(std::wstring &str) { for(size_t i = 0; i < str.length(); i++) { str[i] = SanitizeFilenameChar(str[i]); } } #if MPT_USTRING_MODE_UTF8 void SanitizeFilename(mpt::u8string &str) { for(size_t i = 0; i < str.length(); i++) { str[i] = SanitizeFilenameChar(str[i]); } } #endif // MPT_USTRING_MODE_UTF8 #if defined(_MFC_VER) void SanitizeFilename(CString &str) { for(int i = 0; i < str.GetLength(); i++) { str.SetAt(i, SanitizeFilenameChar(str.GetAt(i))); } } #endif // MFC #endif // MODPLUG_TRACKER #if defined(MODPLUG_TRACKER) mpt::PathString FileType::AsFilterString(FlagSet format) const { mpt::PathString filter; if(GetShortName().empty() || GetExtensions().empty()) { return filter; } if(!GetDescription().empty()) { filter += mpt::PathString::FromUnicode(GetDescription()); } else { filter += mpt::PathString::FromUnicode(GetShortName()); } const auto extensions = GetExtensions(); if(format[FileTypeFormatShowExtensions]) { filter += MPT_PATHSTRING(" ("); bool first = true; for(const auto &ext : extensions) { if(first) { first = false; } else { filter += MPT_PATHSTRING(","); } filter += MPT_PATHSTRING("*."); filter += ext; } filter += MPT_PATHSTRING(")"); } filter += MPT_PATHSTRING("|"); { bool first = true; for(const auto &ext : extensions) { if(first) { first = false; } else { filter += MPT_PATHSTRING(";"); } filter += MPT_PATHSTRING("*."); filter += ext; } } filter += MPT_PATHSTRING("|"); return filter; } mpt::PathString FileType::AsFilterOnlyString() const { mpt::PathString filter; const auto extensions = GetExtensions(); { bool first = true; for(const auto &ext : extensions) { if(first) { first = false; } else { filter += MPT_PATHSTRING(";"); } filter += MPT_PATHSTRING("*."); filter += ext; } } return filter; } mpt::PathString ToFilterString(const FileType &fileType, FlagSet format) { return fileType.AsFilterString(format); } mpt::PathString ToFilterString(const std::vector &fileTypes, FlagSet format) { mpt::PathString filter; for(const auto &type : fileTypes) { filter += type.AsFilterString(format); } return filter; } mpt::PathString ToFilterOnlyString(const FileType &fileType, bool prependSemicolonWhenNotEmpty) { mpt::PathString filter = fileType.AsFilterOnlyString(); return filter.empty() ? filter : (prependSemicolonWhenNotEmpty ? MPT_PATHSTRING(";") : MPT_PATHSTRING("")) + filter; } mpt::PathString ToFilterOnlyString(const std::vector &fileTypes, bool prependSemicolonWhenNotEmpty) { mpt::PathString filter; for(const auto &type : fileTypes) { filter += type.AsFilterOnlyString(); } return filter.empty() ? filter : (prependSemicolonWhenNotEmpty ? MPT_PATHSTRING(";") : MPT_PATHSTRING("")) + filter; } #endif // MODPLUG_TRACKER OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/mptIO.cpp0000644000372100037210000005373613142633151017317 00000000000000/* * mptIO.cpp * --------- * Purpose: Basic functions for reading/writing binary and endian safe data to/from files/streams. * Notes : This is work-in-progress. * Some useful functions for reading and writing are still missing. * Authors: Joern Heusipp * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "mptIO.h" #include #include #include #include #if MPT_COMPILER_MSVC #include #endif // MPT_COMPILER_MSVC #if defined(MPT_ENABLE_FILEIO_STDIO) #include #include #endif // MPT_ENABLE_FILEIO_STDIO OPENMPT_NAMESPACE_BEGIN namespace mpt { namespace IO { #if MPT_COMPILER_MSVC // MSVC std::stringbuf (and thereby std::ostringstream, std::istringstream and // std::stringstream) fail seekoff() when the stringbuf is currently empty. // seekoff() can get called via tell*() or seek*() iostream members. tell*() has // been special cased from VS2010 onwards to handle this specific case and // changed to not fail when the stringbuf is empty. // In addition to using out own wrapper around std::stringstream and // std::stringbuf, we also work-around the plain native type's problem in case // we get handed such an object from third party code. This mitigation of course // requires using our consolidated and normalized IO functions. // We use the following work-around strategy: // * If the stream is already in failed state, we do not do any work-around // and bail out early. // * If the underlying streambuf is not a std::stringbuf, the work-around is // not necessary and we skip it. // * If querying the current position does not fail and returns a // position > 0, the underlying stringbuf is not empty and we also bail out. // * Otherwise, we actually query the string contained in the stringbuf to be // empty. This operation is slow as it has to copy the string into a // temporary. // Note, however, that this is only ever necessary if the current position // is 0. If it always has been 0, the stringbuf will be empty anyway and the // copy does not cost anything measurable. If it got seeked to position 0, // we have to pay the price. However, this should be relatively uncommmon in // pratice. // * The actual work-around consists of performing or emulating the requested // operation and resetting the failed state afterwards. static bool StreamIsStringStreamAndValidAndEmpty(std::ostream & f) { if(f.fail() || !f.rdbuf()) { // failed return false; } if(!dynamic_cast(f.rdbuf()) || (typeid(*(f.rdbuf())) != typeid(std::stringbuf))) { // no stringbuf return false; } std::streampos pos = f.tellp(); f.clear(f.rdstate() & ~std::ios::failbit); if(pos != std::streampos(-1) && pos > 0) { // if the position is not 0, the streambuf is not empty return false; } return dynamic_cast(f.rdbuf())->str().empty(); // slow } static bool StreamIsStringStreamAndValidAndEmpty(std::istream & f) { if(f.fail() || !f.rdbuf()) { // failed return false; } if(!dynamic_cast(f.rdbuf()) || (typeid(*(f.rdbuf())) != typeid(std::stringbuf))) { // no stringbuf return false; } std::streampos pos = f.tellg(); f.clear(f.rdstate() & ~std::ios::failbit); if(pos != std::streampos(-1) && pos > 0) { // if the position is not 0, the streambuf is not empty return false; } return dynamic_cast(f.rdbuf())->str().empty(); // slow } static bool StreamIsStringStreamAndValidAndEmpty(std::iostream & f) { if(f.fail() || !f.rdbuf()) { // failed return false; } if(!dynamic_cast(f.rdbuf()) || (typeid(*(f.rdbuf())) != typeid(std::stringbuf))) { // no stringbuf return false; } std::streampos ipos = f.tellg(); f.clear(f.rdstate() & ~std::ios::failbit); std::streampos opos = f.tellp(); f.clear(f.rdstate() & ~std::ios::failbit); if((ipos != std::streampos(-1) && ipos > 0) || (opos != std::streampos(-1) && opos > 0)) { // if the position is not 0, the streambuf is not empty return false; } return dynamic_cast(f.rdbuf())->str().empty(); // slow } #endif // MPT_COMPILER_MSVC //STATIC_ASSERT(sizeof(std::streamoff) == 8); // Assert 64bit file support. bool IsValid(std::ostream & f) { return !f.fail(); } bool IsValid(std::istream & f) { return !f.fail(); } bool IsValid(std::iostream & f) { return !f.fail(); } IO::Offset TellRead(std::istream & f) { return f.tellg(); } IO::Offset TellWrite(std::ostream & f) { return f.tellp(); } bool SeekBegin(std::ostream & f) { #if MPT_COMPILER_MSVC if(StreamIsStringStreamAndValidAndEmpty(f)) { // VS std::stringbuf fail seek when the internal buffer is empty. Work-around it in case the stream is not already in failed state. f.seekp(0); f.clear(f.rdstate() & ~std::ios::failbit); return true; } #endif f.seekp(0); return !f.fail(); } bool SeekBegin(std::istream & f) { #if MPT_COMPILER_MSVC if(StreamIsStringStreamAndValidAndEmpty(f)) { f.seekg(0); f.clear(f.rdstate() & ~std::ios::failbit); return true; } #endif f.seekg(0); return !f.fail(); } bool SeekBegin(std::iostream & f) { #if MPT_COMPILER_MSVC if(StreamIsStringStreamAndValidAndEmpty(f)) { f.seekg(0); f.clear(f.rdstate() & ~std::ios::failbit); f.seekp(0); f.clear(f.rdstate() & ~std::ios::failbit); return true; } #endif f.seekg(0); f.seekp(0); return !f.fail(); } bool SeekEnd(std::ostream & f) { #if MPT_COMPILER_MSVC if(StreamIsStringStreamAndValidAndEmpty(f)) { f.seekp(0); f.clear(f.rdstate() & ~std::ios::failbit); return true; } #endif f.seekp(0, std::ios::end); return !f.fail(); } bool SeekEnd(std::istream & f) { #if MPT_COMPILER_MSVC if(StreamIsStringStreamAndValidAndEmpty(f)) { f.seekg(0); f.clear(f.rdstate() & ~std::ios::failbit); return true; } #endif f.seekg(0, std::ios::end); return !f.fail(); } bool SeekEnd(std::iostream & f) { #if MPT_COMPILER_MSVC if(StreamIsStringStreamAndValidAndEmpty(f)) { f.seekg(0); f.clear(f.rdstate() & ~std::ios::failbit); f.seekp(0); f.clear(f.rdstate() & ~std::ios::failbit); return true; } #endif f.seekg(0, std::ios::end); f.seekp(0, std::ios::end); return !f.fail(); } bool SeekAbsolute(std::ostream & f, IO::Offset pos) { if(!OffsetFits(pos)) { return false; } #if MPT_COMPILER_MSVC if(StreamIsStringStreamAndValidAndEmpty(f)) { if(pos == 0) { f.seekp(static_cast(pos), std::ios::beg); f.clear(f.rdstate() & ~std::ios::failbit); return true; } } #endif f.seekp(static_cast(pos), std::ios::beg); return !f.fail(); } bool SeekAbsolute(std::istream & f, IO::Offset pos) { if(!OffsetFits(pos)) { return false; } #if MPT_COMPILER_MSVC if(StreamIsStringStreamAndValidAndEmpty(f)) { if(pos == 0) { f.seekg(static_cast(pos), std::ios::beg); f.clear(f.rdstate() & ~std::ios::failbit); return true; } } #endif f.seekg(static_cast(pos), std::ios::beg); return !f.fail(); } bool SeekAbsolute(std::iostream & f, IO::Offset pos) { if(!OffsetFits(pos)) { return false; } #if MPT_COMPILER_MSVC if(StreamIsStringStreamAndValidAndEmpty(f)) { if(pos == 0) { f.seekg(static_cast(pos), std::ios::beg); f.clear(f.rdstate() & ~std::ios::failbit); f.seekp(static_cast(pos), std::ios::beg); f.clear(f.rdstate() & ~std::ios::failbit); return true; } } #endif f.seekg(static_cast(pos), std::ios::beg); f.seekp(static_cast(pos), std::ios::beg); return !f.fail(); } bool SeekRelative(std::ostream & f, IO::Offset off) { if(!OffsetFits(off)) { return false; } #if MPT_COMPILER_MSVC if(StreamIsStringStreamAndValidAndEmpty(f)) { if(off == 0) { f.seekp(static_cast(off), std::ios::cur); f.clear(f.rdstate() & ~std::ios::failbit); return true; } } #endif f.seekp(static_cast(off), std::ios::cur); return !f.fail(); } bool SeekRelative(std::istream & f, IO::Offset off) { if(!OffsetFits(off)) { return false; } #if MPT_COMPILER_MSVC if(StreamIsStringStreamAndValidAndEmpty(f)) { if(off == 0) { f.seekg(static_cast(off), std::ios::cur); f.clear(f.rdstate() & ~std::ios::failbit); return true; } } #endif f.seekg(static_cast(off), std::ios::cur); return !f.fail(); } bool SeekRelative(std::iostream & f, IO::Offset off) { if(!OffsetFits(off)) { return false; } #if MPT_COMPILER_MSVC if(StreamIsStringStreamAndValidAndEmpty(f)) { if(off == 0) { f.seekg(static_cast(off), std::ios::cur); f.clear(f.rdstate() & ~std::ios::failbit); f.seekp(static_cast(off), std::ios::cur); f.clear(f.rdstate() & ~std::ios::failbit); return true; } } #endif f.seekg(static_cast(off), std::ios::cur); f.seekp(static_cast(off), std::ios::cur); return !f.fail(); } IO::Offset ReadRawImpl(std::istream & f, mpt::byte * data, std::size_t size) { return f.read(mpt::byte_cast(data), size) ? f.gcount() : std::streamsize(0); } bool WriteRawImpl(std::ostream & f, const mpt::byte * data, std::size_t size) { f.write(mpt::byte_cast(data), size); return !f.fail(); } bool IsEof(std::istream & f) { return f.eof(); } bool Flush(std::ostream & f) { f.flush(); return !f.fail(); } #if defined(MPT_ENABLE_FILEIO_STDIO) bool IsValid(FILE* & f) { return f != NULL; } #if MPT_COMPILER_MSVC IO::Offset TellRead(FILE* & f) { return _ftelli64(f); } IO::Offset TellWrite(FILE* & f) { return _ftelli64(f); } bool SeekBegin(FILE* & f) { return _fseeki64(f, 0, SEEK_SET) == 0; } bool SeekEnd(FILE* & f) { return _fseeki64(f, 0, SEEK_END) == 0; } bool SeekAbsolute(FILE* & f, IO::Offset pos) { return _fseeki64(f, pos, SEEK_SET) == 0; } bool SeekRelative(FILE* & f, IO::Offset off) { return _fseeki64(f, off, SEEK_CUR) == 0; } #elif defined(_POSIX_SOURCE) && (_POSIX_SOURCE > 0) //STATIC_ASSERT(sizeof(off_t) == 8); IO::Offset TellRead(FILE* & f) { return ftello(f); } IO::Offset TellWrite(FILE* & f) { return ftello(f); } bool SeekBegin(FILE* & f) { return fseeko(f, 0, SEEK_SET) == 0; } bool SeekEnd(FILE* & f) { return fseeko(f, 0, SEEK_END) == 0; } bool SeekAbsolute(FILE* & f, IO::Offset pos) { return OffsetFits(pos) && (fseek(f, mpt::saturate_cast(pos), SEEK_SET) == 0); } bool SeekRelative(FILE* & f, IO::Offset off) { return OffsetFits(off) && (fseek(f, mpt::saturate_cast(off), SEEK_CUR) == 0); } #else //STATIC_ASSERT(sizeof(long) == 8); // Fails on 32bit non-POSIX systems for now. IO::Offset TellRead(FILE* & f) { return ftell(f); } IO::Offset TellWrite(FILE* & f) { return ftell(f); } bool SeekBegin(FILE* & f) { return fseek(f, 0, SEEK_SET) == 0; } bool SeekEnd(FILE* & f) { return fseek(f, 0, SEEK_END) == 0; } bool SeekAbsolute(FILE* & f, IO::Offset pos) { return OffsetFits(pos) && (fseek(f, mpt::saturate_cast(pos), SEEK_SET) == 0); } bool SeekRelative(FILE* & f, IO::Offset off) { return OffsetFits(off) && (fseek(f, mpt::saturate_cast(off), SEEK_CUR) == 0); } #endif IO::Offset ReadRawImpl(FILE * & f, mpt::byte * data, std::size_t size) { return fread(mpt::void_cast(data), 1, size, f); } bool WriteRawImpl(FILE* & f, const mpt::byte * data, std::size_t size) { return fwrite(mpt::void_cast(data), 1, size, f) == size; } bool IsEof(FILE * & f) { return feof(f) != 0; } bool Flush(FILE* & f) { return fflush(f) == 0; } #endif // MPT_ENABLE_FILEIO_STDIO } // namespace IO } // namespace mpt #if defined(MPT_FILEREADER_STD_ISTREAM) FileDataContainerSeekable::FileDataContainerSeekable(off_t streamLength) : streamLength(streamLength) , cached(false) { return; } FileDataContainerSeekable::~FileDataContainerSeekable() { return; } void FileDataContainerSeekable::CacheStream() const { if(cached) { return; } cache.resize(streamLength); InternalRead(cache.data(), 0, streamLength); cached = true; } bool FileDataContainerSeekable::IsValid() const { return true; } bool FileDataContainerSeekable::HasFastGetLength() const { return true; } bool FileDataContainerSeekable::HasPinnedView() const { return cached; } const mpt::byte *FileDataContainerSeekable::GetRawData() const { CacheStream(); return cache.data(); } IFileDataContainer::off_t FileDataContainerSeekable::GetLength() const { return streamLength; } IFileDataContainer::off_t FileDataContainerSeekable::Read(mpt::byte *dst, IFileDataContainer::off_t pos, IFileDataContainer::off_t count) const { if(cached) { IFileDataContainer::off_t cache_avail = std::min(IFileDataContainer::off_t(cache.size()) - pos, count); std::copy(cache.begin() + pos, cache.begin() + pos + cache_avail, dst); return cache_avail; } else { return InternalRead(dst, pos, count); } } bool FileDataContainerStdStreamSeekable::IsSeekable(std::istream *stream) { stream->clear(); std::streampos oldpos = stream->tellg(); if(stream->fail() || oldpos == std::streampos(-1)) { stream->clear(); return false; } stream->seekg(0, std::ios::beg); if(stream->fail()) { stream->clear(); stream->seekg(oldpos); stream->clear(); return false; } stream->seekg(0, std::ios::end); if(stream->fail()) { stream->clear(); stream->seekg(oldpos); stream->clear(); return false; } std::streampos length = stream->tellg(); if(stream->fail() || length == std::streampos(-1)) { stream->clear(); stream->seekg(oldpos); stream->clear(); return false; } stream->seekg(oldpos); stream->clear(); return true; } IFileDataContainer::off_t FileDataContainerStdStreamSeekable::GetLength(std::istream *stream) { stream->clear(); std::streampos oldpos = stream->tellg(); stream->seekg(0, std::ios::end); std::streampos length = stream->tellg(); stream->seekg(oldpos); return mpt::saturate_cast(static_cast(length)); } FileDataContainerStdStreamSeekable::FileDataContainerStdStreamSeekable(std::istream *s) : FileDataContainerSeekable(GetLength(s)) , stream(s) { return; } FileDataContainerStdStreamSeekable::~FileDataContainerStdStreamSeekable() { return; } IFileDataContainer::off_t FileDataContainerStdStreamSeekable::InternalRead(mpt::byte *dst, off_t pos, off_t count) const { stream->clear(); // tellg needs eof and fail bits unset std::streampos currentpos = stream->tellg(); if(currentpos == std::streampos(-1) || static_cast(pos) != currentpos) { // inefficient istream implementations might invalidate their buffer when seeking, even when seeking to the current position stream->seekg(pos); } stream->read(mpt::byte_cast(dst), count); return static_cast(stream->gcount()); } FileDataContainerUnseekable::FileDataContainerUnseekable() : cachesize(0), streamFullyCached(false) { return; } FileDataContainerUnseekable::~FileDataContainerUnseekable() { return; } void FileDataContainerUnseekable::EnsureCacheBuffer(std::size_t requiredbuffersize) const { if(cache.size() >= cachesize + requiredbuffersize) { return; } if(cache.size() == 0) { cache.resize(Util::AlignUp(cachesize + requiredbuffersize, BUFFER_SIZE)); } else if(Util::ExponentialGrow(cache.size()) < cachesize + requiredbuffersize) { cache.resize(Util::AlignUp(cachesize + requiredbuffersize, BUFFER_SIZE)); } else { cache.resize(Util::ExponentialGrow(cache.size())); } } void FileDataContainerUnseekable::CacheStream() const { if(streamFullyCached) { return; } while(!InternalEof()) { EnsureCacheBuffer(BUFFER_SIZE); std::size_t readcount = InternalRead(&cache[cachesize], BUFFER_SIZE); cachesize += readcount; } streamFullyCached = true; } void FileDataContainerUnseekable::CacheStreamUpTo(off_t pos, off_t length) const { if(streamFullyCached) { return; } if(length > std::numeric_limits::max() - pos) { length = std::numeric_limits::max() - pos; } std::size_t target = mpt::saturate_cast(pos + length); if(target <= cachesize) { return; } std::size_t alignedpos = Util::AlignUp(target, QUANTUM_SIZE); std::size_t needcount = alignedpos - cachesize; EnsureCacheBuffer(needcount); std::size_t readcount = InternalRead(&cache[cachesize], alignedpos - cachesize); cachesize += readcount; if(!InternalEof()) { // can read further return; } streamFullyCached = true; } void FileDataContainerUnseekable::ReadCached(mpt::byte *dst, IFileDataContainer::off_t pos, IFileDataContainer::off_t count) const { std::copy(cache.begin() + pos, cache.begin() + pos + count, dst); } bool FileDataContainerUnseekable::IsValid() const { return true; } bool FileDataContainerUnseekable::HasFastGetLength() const { return false; } bool FileDataContainerUnseekable::HasPinnedView() const { return true; // we have the cache which is required for seeking anyway } const mpt::byte *FileDataContainerUnseekable::GetRawData() const { CacheStream(); return cache.data(); } IFileDataContainer::off_t FileDataContainerUnseekable::GetLength() const { CacheStream(); return cachesize; } IFileDataContainer::off_t FileDataContainerUnseekable::Read(mpt::byte *dst, IFileDataContainer::off_t pos, IFileDataContainer::off_t count) const { CacheStreamUpTo(pos, count); if(pos >= IFileDataContainer::off_t(cachesize)) { return 0; } IFileDataContainer::off_t cache_avail = std::min(IFileDataContainer::off_t(cachesize) - pos, count); ReadCached(dst, pos, cache_avail); return cache_avail; } bool FileDataContainerUnseekable::CanRead(IFileDataContainer::off_t pos, IFileDataContainer::off_t length) const { CacheStreamUpTo(pos, length); if((pos == IFileDataContainer::off_t(cachesize)) && (length == 0)) { return true; } if(pos >= IFileDataContainer::off_t(cachesize)) { return false; } return length <= IFileDataContainer::off_t(cachesize) - pos; } IFileDataContainer::off_t FileDataContainerUnseekable::GetReadableLength(IFileDataContainer::off_t pos, IFileDataContainer::off_t length) const { CacheStreamUpTo(pos, length); if(pos >= cachesize) { return 0; } return std::min(cachesize - pos, length); } FileDataContainerStdStream::FileDataContainerStdStream(std::istream *s) : stream(s) { return; } FileDataContainerStdStream::~FileDataContainerStdStream() { return; } bool FileDataContainerStdStream::InternalEof() const { if(*stream) { return false; } else { return true; } } IFileDataContainer::off_t FileDataContainerStdStream::InternalRead(mpt::byte *dst, off_t count) const { stream->read(mpt::byte_cast(dst), count); return static_cast(stream->gcount()); } #if defined(MPT_FILEREADER_CALLBACK_STREAM) bool FileDataContainerCallbackStreamSeekable::IsSeekable(CallbackStream stream) { if(!stream.stream) { return false; } if(!stream.seek) { return false; } if(!stream.tell) { return false; } int64 oldpos = stream.tell(stream.stream); if(oldpos < 0) { return false; } if(stream.seek(stream.stream, 0, CallbackStream::SeekSet) < 0) { stream.seek(stream.stream, oldpos, CallbackStream::SeekSet); return false; } if(stream.seek(stream.stream, 0, CallbackStream::SeekEnd) < 0) { stream.seek(stream.stream, oldpos, CallbackStream::SeekSet); return false; } int64 length = stream.tell(stream.stream); if(length < 0) { stream.seek(stream.stream, oldpos, CallbackStream::SeekSet); return false; } stream.seek(stream.stream, oldpos, CallbackStream::SeekSet); return true; } IFileDataContainer::off_t FileDataContainerCallbackStreamSeekable::GetLength(CallbackStream stream) { if(!stream.stream) { return 0; } if(!stream.seek) { return false; } if(!stream.tell) { return false; } int64 oldpos = stream.tell(stream.stream); if(oldpos < 0) { return 0; } if(stream.seek(stream.stream, 0, CallbackStream::SeekSet) < 0) { stream.seek(stream.stream, oldpos, CallbackStream::SeekSet); return 0; } if(stream.seek(stream.stream, 0, CallbackStream::SeekEnd) < 0) { stream.seek(stream.stream, oldpos, CallbackStream::SeekSet); return 0; } int64 length = stream.tell(stream.stream); if(length < 0) { stream.seek(stream.stream, oldpos, CallbackStream::SeekSet); return 0; } stream.seek(stream.stream, oldpos, CallbackStream::SeekSet); return mpt::saturate_cast(length); } FileDataContainerCallbackStreamSeekable::FileDataContainerCallbackStreamSeekable(CallbackStream s) : FileDataContainerSeekable(GetLength(s)) , stream(s) { return; } FileDataContainerCallbackStreamSeekable::~FileDataContainerCallbackStreamSeekable() { return; } IFileDataContainer::off_t FileDataContainerCallbackStreamSeekable::InternalRead(mpt::byte *dst, off_t pos, off_t count) const { if(!stream.read) { return 0; } if(stream.seek(stream.stream, pos, CallbackStream::SeekSet) < 0) { return 0; } int64 totalread = 0; while(count > 0) { int64 readcount = stream.read(stream.stream, dst, count); if(readcount <= 0) { break; } dst += static_cast(readcount); count -= static_cast(readcount); totalread += readcount; } return static_cast(totalread); } FileDataContainerCallbackStream::FileDataContainerCallbackStream(CallbackStream s) : FileDataContainerUnseekable() , stream(s) , eof_reached(false) { return; } FileDataContainerCallbackStream::~FileDataContainerCallbackStream() { return; } bool FileDataContainerCallbackStream::InternalEof() const { return eof_reached; } IFileDataContainer::off_t FileDataContainerCallbackStream::InternalRead(mpt::byte *dst, off_t count) const { if(eof_reached) { return 0; } if(!stream.read) { eof_reached = true; return 0; } int64 totalread = 0; while(count > 0) { int64 readcount = stream.read(stream.stream, dst, count); if(readcount <= 0) { eof_reached = true; break; } dst += static_cast(readcount); count -= static_cast(readcount); totalread += readcount; } return static_cast(totalread); } #endif // MPT_FILEREADER_CALLBACK_STREAM #endif OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/mptStringFormat.cpp0000644000372100037210000004453513130373507021427 00000000000000/* * mptStringFormat.cpp * ------------------- * Purpose: Convert other types to strings. * Notes : Currently none. * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "mptStringFormat.h" #include #include #include #include OPENMPT_NAMESPACE_BEGIN namespace mpt { template inline void SaneInsert(Tstream & s, const T & x) { s << x; } // do the right thing for signed/unsigned char and bool template void SaneInsert(Tstream & s, const bool & x) { s << static_cast(x); } template void SaneInsert(Tstream & s, const signed char & x) { s << static_cast(x); } template void SaneInsert(Tstream & s, const unsigned char & x) { s << static_cast(x); } template inline std::string ToStringHelper(const T & x) { std::ostringstream o; o.imbue(std::locale::classic()); SaneInsert(o, x); return o.str(); } #if MPT_WSTRING_FORMAT template inline std::wstring ToWStringHelper(const T & x) { std::wostringstream o; o.imbue(std::locale::classic()); SaneInsert(o, x); return o.str(); } #endif #if MPT_WSTRING_CONVERT std::string ToString(const std::wstring & x) { return mpt::ToCharset(mpt::CharsetLocaleOrUTF8, x); } std::string ToString(const wchar_t * const & x) { return mpt::ToCharset(mpt::CharsetLocaleOrUTF8, x); } std::string ToString(const wchar_t & x) { return mpt::ToCharset(mpt::CharsetLocaleOrUTF8, std::wstring(1, x)); } #endif #if MPT_USTRING_MODE_UTF8 std::string ToString(const mpt::ustring & x) { return mpt::ToCharset(mpt::CharsetLocaleOrUTF8, x); } #endif #if defined(_MFC_VER) std::string ToString(const CString & x) { return mpt::ToCharset(mpt::CharsetLocaleOrUTF8, x); } #endif std::string ToString(const bool & x) { return ToStringHelper(x); } std::string ToString(const signed char & x) { return ToStringHelper(x); } std::string ToString(const unsigned char & x) { return ToStringHelper(x); } std::string ToString(const signed short & x) { return ToStringHelper(x); } std::string ToString(const unsigned short & x) { return ToStringHelper(x); } std::string ToString(const signed int & x) { return ToStringHelper(x); } std::string ToString(const unsigned int & x) { return ToStringHelper(x); } std::string ToString(const signed long & x) { return ToStringHelper(x); } std::string ToString(const unsigned long & x) { return ToStringHelper(x); } std::string ToString(const signed long long & x) { return ToStringHelper(x); } std::string ToString(const unsigned long long & x) { return ToStringHelper(x); } std::string ToString(const float & x) { return ToStringHelper(x); } std::string ToString(const double & x) { return ToStringHelper(x); } std::string ToString(const long double & x) { return ToStringHelper(x); } mpt::ustring ToUString(const std::string & x) { return mpt::ToUnicode(mpt::CharsetLocaleOrUTF8, x); } mpt::ustring ToUString(const char * const & x) { return mpt::ToUnicode(mpt::CharsetLocaleOrUTF8, x); } mpt::ustring ToUString(const char & x) { return mpt::ToUnicode(mpt::CharsetLocaleOrUTF8, std::string(1, x)); } #if MPT_WSTRING_FORMAT #if MPT_USTRING_MODE_UTF8 mpt::ustring ToUString(const std::wstring & x) { return mpt::ToUnicode(x); } #endif mpt::ustring ToUString(const wchar_t * const & x) { return mpt::ToUnicode(x); } mpt::ustring ToUString(const wchar_t & x) { return mpt::ToUnicode(std::wstring(1, x)); } #endif #if defined(_MFC_VER) mpt::ustring ToUString(const CString & x) { return mpt::ToUnicode(x); } #endif #if MPT_USTRING_MODE_WIDE mpt::ustring ToUString(const bool & x) { return ToWStringHelper(x); } mpt::ustring ToUString(const signed char & x) { return ToWStringHelper(x); } mpt::ustring ToUString(const unsigned char & x) { return ToWStringHelper(x); } mpt::ustring ToUString(const signed short & x) { return ToWStringHelper(x); } mpt::ustring ToUString(const unsigned short & x) { return ToWStringHelper(x); } mpt::ustring ToUString(const signed int & x) { return ToWStringHelper(x); } mpt::ustring ToUString(const unsigned int & x) { return ToWStringHelper(x); } mpt::ustring ToUString(const signed long & x) { return ToWStringHelper(x); } mpt::ustring ToUString(const unsigned long & x) { return ToWStringHelper(x); } mpt::ustring ToUString(const signed long long & x) { return ToWStringHelper(x); } mpt::ustring ToUString(const unsigned long long & x) { return ToWStringHelper(x); } mpt::ustring ToUString(const float & x) { return ToWStringHelper(x); } mpt::ustring ToUString(const double & x) { return ToWStringHelper(x); } mpt::ustring ToUString(const long double & x) { return ToWStringHelper(x); } #endif #if MPT_USTRING_MODE_UTF8 mpt::ustring ToUString(const bool & x) { return mpt::ToUnicode(mpt::CharsetUTF8, ToStringHelper(x)); } mpt::ustring ToUString(const signed char & x) { return mpt::ToUnicode(mpt::CharsetUTF8, ToStringHelper(x)); } mpt::ustring ToUString(const unsigned char & x) { return mpt::ToUnicode(mpt::CharsetUTF8, ToStringHelper(x)); } mpt::ustring ToUString(const signed short & x) { return mpt::ToUnicode(mpt::CharsetUTF8, ToStringHelper(x)); } mpt::ustring ToUString(const unsigned short & x) { return mpt::ToUnicode(mpt::CharsetUTF8, ToStringHelper(x)); } mpt::ustring ToUString(const signed int & x) { return mpt::ToUnicode(mpt::CharsetUTF8, ToStringHelper(x)); } mpt::ustring ToUString(const unsigned int & x) { return mpt::ToUnicode(mpt::CharsetUTF8, ToStringHelper(x)); } mpt::ustring ToUString(const signed long & x) { return mpt::ToUnicode(mpt::CharsetUTF8, ToStringHelper(x)); } mpt::ustring ToUString(const unsigned long & x) { return mpt::ToUnicode(mpt::CharsetUTF8, ToStringHelper(x)); } mpt::ustring ToUString(const signed long long & x) { return mpt::ToUnicode(mpt::CharsetUTF8, ToStringHelper(x)); } mpt::ustring ToUString(const unsigned long long & x) { return mpt::ToUnicode(mpt::CharsetUTF8, ToStringHelper(x)); } mpt::ustring ToUString(const float & x) { return mpt::ToUnicode(mpt::CharsetUTF8, ToStringHelper(x)); } mpt::ustring ToUString(const double & x) { return mpt::ToUnicode(mpt::CharsetUTF8, ToStringHelper(x)); } mpt::ustring ToUString(const long double & x) { return mpt::ToUnicode(mpt::CharsetUTF8, ToStringHelper(x)); } #endif #if MPT_WSTRING_FORMAT std::wstring ToWString(const std::string & x) { return mpt::ToWide(mpt::CharsetLocaleOrUTF8, x); } std::wstring ToWString(const char * const & x) { return mpt::ToWide(mpt::CharsetLocaleOrUTF8, x); } std::wstring ToWString(const char & x) { return mpt::ToWide(mpt::CharsetLocaleOrUTF8, std::string(1, x)); } #if MPT_USTRING_MODE_UTF8 std::wstring ToWString(const mpt::ustring & x) { return mpt::ToWide(x); } #endif #if defined(_MFC_VER) std::wstring ToWString(const CString & x) { return mpt::ToWide(x); } #endif std::wstring ToWString(const bool & x) { return ToWStringHelper(x); } std::wstring ToWString(const signed char & x) { return ToWStringHelper(x); } std::wstring ToWString(const unsigned char & x) { return ToWStringHelper(x); } std::wstring ToWString(const signed short & x) { return ToWStringHelper(x); } std::wstring ToWString(const unsigned short & x) { return ToWStringHelper(x); } std::wstring ToWString(const signed int & x) { return ToWStringHelper(x); } std::wstring ToWString(const unsigned int & x) { return ToWStringHelper(x); } std::wstring ToWString(const signed long & x) { return ToWStringHelper(x); } std::wstring ToWString(const unsigned long & x) { return ToWStringHelper(x); } std::wstring ToWString(const signed long long & x) { return ToWStringHelper(x); } std::wstring ToWString(const unsigned long long & x) { return ToWStringHelper(x); } std::wstring ToWString(const float & x) { return ToWStringHelper(x); } std::wstring ToWString(const double & x) { return ToWStringHelper(x); } std::wstring ToWString(const long double & x) { return ToWStringHelper(x); } #endif template inline void ApplyFormat(Tostream & o, const FormatSpec & format) { FormatFlags f = format.GetFlags(); std::size_t width = format.GetWidth(); int precision = format.GetPrecision(); if(precision != -1 && width != 0 && !(f & fmt_base::NotaFix) && !(f & fmt_base::NotaSci)) { // fixup: // precision behaves differently from .# // avoid default format when precision and width are set f &= ~fmt_base::NotaNrm; f |= fmt_base::NotaFix; } if(f & fmt_base::BaseDec) { o << std::dec; } else if(f & fmt_base::BaseHex) { o << std::hex; } if(f & fmt_base::NotaNrm ) { /*nothing*/ } else if(f & fmt_base::NotaFix ) { o << std::setiosflags(std::ios::fixed); } else if(f & fmt_base::NotaSci ) { o << std::setiosflags(std::ios::scientific); } if(f & fmt_base::CaseLow) { o << std::nouppercase; } else if(f & fmt_base::CaseUpp) { o << std::uppercase; } if(f & fmt_base::FillOff) { /* nothing */ } else if(f & fmt_base::FillNul) { o << std::setw(width) << std::setfill(typename Tostream::char_type('0')); } else if(f & fmt_base::FillSpc) { o << std::setw(width) << std::setfill(typename Tostream::char_type(' ')); } if(precision != -1) { o << std::setprecision(precision); } } template inline std::string FormatValHelper(const T & x, const FormatSpec & f) { std::ostringstream o; o.imbue(std::locale::classic()); ApplyFormat(o, f); SaneInsert(o, x); return o.str(); } #if MPT_WSTRING_FORMAT template inline std::wstring FormatValWHelper(const T & x, const FormatSpec & f) { std::wostringstream o; o.imbue(std::locale::classic()); ApplyFormat(o, f); SaneInsert(o, x); return o.str(); } #endif // Parses a useful subset of standard sprintf syntax for specifying floating point formatting. template static inline FormatSpec ParseFormatStringFloat(const Tchar * str) { MPT_ASSERT(str); FormatFlags f = FormatFlags(); std::size_t width = 0; int precision = -1; if(!str) { return FormatSpec(); } const Tchar * p = str; while(*p && *p != Tchar('%')) { ++p; } ++p; while(*p && (*p == Tchar(' ') || *p == Tchar('0'))) { if(*p == Tchar(' ')) f |= mpt::fmt_base::FillSpc; if(*p == Tchar('0')) f |= mpt::fmt_base::FillNul; ++p; } if(!(f & mpt::fmt_base::FillSpc) && !(f & mpt::fmt_base::FillNul)) { f |= mpt::fmt_base::FillOff; } while(*p && (Tchar('0') <= *p && *p <= Tchar('9'))) { if(f & mpt::fmt_base::FillOff) { f &= ~mpt::fmt_base::FillOff; f |= mpt::fmt_base::FillSpc; } width *= 10; width += *p - Tchar('0'); ++p; } if(*p && *p == Tchar('.')) { ++p; precision = 0; while(*p && (Tchar('0') <= *p && *p <= Tchar('9'))) { precision *= 10; precision += *p - Tchar('0'); ++p; } } if(*p && (*p == Tchar('g') || *p == Tchar('G') || *p == Tchar('f') || *p == Tchar('F') || *p == Tchar('e') || *p == Tchar('E'))) { if(*p == Tchar('g')) f |= mpt::fmt_base::NotaNrm | mpt::fmt_base::CaseLow; if(*p == Tchar('G')) f |= mpt::fmt_base::NotaNrm | mpt::fmt_base::CaseUpp; if(*p == Tchar('f')) f |= mpt::fmt_base::NotaFix | mpt::fmt_base::CaseLow; if(*p == Tchar('F')) f |= mpt::fmt_base::NotaFix | mpt::fmt_base::CaseUpp; if(*p == Tchar('e')) f |= mpt::fmt_base::NotaSci | mpt::fmt_base::CaseLow; if(*p == Tchar('E')) f |= mpt::fmt_base::NotaSci | mpt::fmt_base::CaseUpp; ++p; } return FormatSpec().SetFlags(f).SetWidth(width).SetPrecision(precision); } FormatSpec & FormatSpec::ParsePrintf(const char * format) { *this = ParseFormatStringFloat(format); return *this; } FormatSpec & FormatSpec::ParsePrintf(const wchar_t * format) { *this = ParseFormatStringFloat(format); return *this; } FormatSpec & FormatSpec::ParsePrintf(const std::string & format) { *this = ParseFormatStringFloat(format.c_str()); return *this; } FormatSpec & FormatSpec::ParsePrintf(const std::wstring & format) { *this = ParseFormatStringFloat(format.c_str()); return *this; } std::string FormatVal(const char & x, const FormatSpec & f) { return FormatValHelper(x, f); } std::string FormatVal(const wchar_t & x, const FormatSpec & f) { return FormatValHelper(x, f); } std::string FormatVal(const bool & x, const FormatSpec & f) { return FormatValHelper(x, f); } std::string FormatVal(const signed char & x, const FormatSpec & f) { return FormatValHelper(x, f); } std::string FormatVal(const unsigned char & x, const FormatSpec & f) { return FormatValHelper(x, f); } std::string FormatVal(const signed short & x, const FormatSpec & f) { return FormatValHelper(x, f); } std::string FormatVal(const unsigned short & x, const FormatSpec & f) { return FormatValHelper(x, f); } std::string FormatVal(const signed int & x, const FormatSpec & f) { return FormatValHelper(x, f); } std::string FormatVal(const unsigned int & x, const FormatSpec & f) { return FormatValHelper(x, f); } std::string FormatVal(const signed long & x, const FormatSpec & f) { return FormatValHelper(x, f); } std::string FormatVal(const unsigned long & x, const FormatSpec & f) { return FormatValHelper(x, f); } std::string FormatVal(const signed long long & x, const FormatSpec & f) { return FormatValHelper(x, f); } std::string FormatVal(const unsigned long long & x, const FormatSpec & f) { return FormatValHelper(x, f); } std::string FormatVal(const float & x, const FormatSpec & f) { return FormatValHelper(x, f); } std::string FormatVal(const double & x, const FormatSpec & f) { return FormatValHelper(x, f); } std::string FormatVal(const long double & x, const FormatSpec & f) { return FormatValHelper(x, f); } #if MPT_WSTRING_FORMAT std::wstring FormatValW(const char & x, const FormatSpec & f) { return FormatValWHelper(x, f); } std::wstring FormatValW(const wchar_t & x, const FormatSpec & f) { return FormatValWHelper(x, f); } std::wstring FormatValW(const bool & x, const FormatSpec & f) { return FormatValWHelper(x, f); } std::wstring FormatValW(const signed char & x, const FormatSpec & f) { return FormatValWHelper(x, f); } std::wstring FormatValW(const unsigned char & x, const FormatSpec & f) { return FormatValWHelper(x, f); } std::wstring FormatValW(const signed short & x, const FormatSpec & f) { return FormatValWHelper(x, f); } std::wstring FormatValW(const unsigned short & x, const FormatSpec & f) { return FormatValWHelper(x, f); } std::wstring FormatValW(const signed int & x, const FormatSpec & f) { return FormatValWHelper(x, f); } std::wstring FormatValW(const unsigned int & x, const FormatSpec & f) { return FormatValWHelper(x, f); } std::wstring FormatValW(const signed long & x, const FormatSpec & f) { return FormatValWHelper(x, f); } std::wstring FormatValW(const unsigned long & x, const FormatSpec & f) { return FormatValWHelper(x, f); } std::wstring FormatValW(const signed long long & x, const FormatSpec & f) { return FormatValWHelper(x, f); } std::wstring FormatValW(const unsigned long long & x, const FormatSpec & f) { return FormatValWHelper(x, f); } std::wstring FormatValW(const float & x, const FormatSpec & f) { return FormatValWHelper(x, f); } std::wstring FormatValW(const double & x, const FormatSpec & f) { return FormatValWHelper(x, f); } std::wstring FormatValW(const long double & x, const FormatSpec & f) { return FormatValWHelper(x, f); } #endif namespace String { namespace detail { template Tstring PrintImplTemplate(const Tstring & format , const Tstring & x1 , const Tstring & x2 , const Tstring & x3 , const Tstring & x4 , const Tstring & x5 , const Tstring & x6 , const Tstring & x7 , const Tstring & x8 ) { Tstring result; const std::size_t len = format.length(); result.reserve(len); for(std::size_t pos = 0; pos != len; ++pos) { typename Tstring::value_type c = format[pos]; if(pos + 1 != len && c == '%') { pos++; c = format[pos]; if('1' <= c && c <= '9') { const std::size_t n = c - '0'; switch(n) { case 1: result.append(x1); break; case 2: result.append(x2); break; case 3: result.append(x3); break; case 4: result.append(x4); break; case 5: result.append(x5); break; case 6: result.append(x6); break; case 7: result.append(x7); break; case 8: result.append(x8); break; } continue; } else if(c != '%') { result.append(1, '%'); } } result.append(1, c); } return result; } #if defined(_MFC_VER) template<> CString PrintImplTemplate(const CString & format , const CString & x1 , const CString & x2 , const CString & x3 , const CString & x4 , const CString & x5 , const CString & x6 , const CString & x7 , const CString & x8 ) { CString result; const int len = format.GetLength(); result.Preallocate(len); for(int pos = 0; pos != len; ++pos) { CString::XCHAR c = format[pos]; if(pos + 1 != len && c == _T('%')) { pos++; c = format[pos]; if(_T('1') <= c && c <= _T('9')) { const std::size_t n = c - _T('0'); switch(n) { case 1: result += x1; break; case 2: result += x2; break; case 3: result += x3; break; case 4: result += x4; break; case 5: result += x5; break; case 6: result += x6; break; case 7: result += x7; break; case 8: result += x8; break; } continue; } else if(c != _T('%')) { result.AppendChar(_T('%')); } } result.AppendChar(c); } return result; } #endif std::string PrintImpl(const std::string & format , const std::string & x1 , const std::string & x2 , const std::string & x3 , const std::string & x4 , const std::string & x5 , const std::string & x6 , const std::string & x7 , const std::string & x8 ) { return PrintImplTemplate(format, x1,x2,x3,x4,x5,x6,x7,x8); } #if MPT_WSTRING_FORMAT std::wstring PrintImpl(const std::wstring & format , const std::wstring & x1 , const std::wstring & x2 , const std::wstring & x3 , const std::wstring & x4 , const std::wstring & x5 , const std::wstring & x6 , const std::wstring & x7 , const std::wstring & x8 ) { return PrintImplTemplate(format, x1,x2,x3,x4,x5,x6,x7,x8); } #endif #if MPT_USTRING_MODE_UTF8 mpt::ustring PrintImpl(const mpt::ustring & format , const mpt::ustring & x1 , const mpt::ustring & x2 , const mpt::ustring & x3 , const mpt::ustring & x4 , const mpt::ustring & x5 , const mpt::ustring & x6 , const mpt::ustring & x7 , const mpt::ustring & x8 ) { return PrintImplTemplate(format, x1,x2,x3,x4,x5,x6,x7,x8); } #endif #if defined(_MFC_VER) CString PrintImpl(const CString & format , const CString & x1 , const CString & x2 , const CString & x3 , const CString & x4 , const CString & x5 , const CString & x6 , const CString & x7 , const CString & x8 ) { return PrintImplTemplate(format, x1,x2,x3,x4,x5,x6,x7,x8); } #endif } // namespace detail } // namespace String } // namespace mpt OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/typedefs.cpp0000644000372100037210000000220212762755704020110 00000000000000/* * typedefs.cpp * ------------ * Purpose: Basic data type definitions and assorted compiler-related helpers. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "typedefs.h" #include "Endianness.h" OPENMPT_NAMESPACE_BEGIN #if MPT_PLATFORM_ENDIAN_KNOWN MPT_MSVC_WORKAROUND_LNK4221(typedefs) #else int24::int24(int other) { MPT_MAYBE_CONSTANT_IF(mpt::endian_is_big()) { bytes[0] = (static_cast(other)>>16)&0xff; bytes[1] = (static_cast(other)>> 8)&0xff; bytes[2] = (static_cast(other)>> 0)&0xff; } else { bytes[0] = (static_cast(other)>> 0)&0xff; bytes[1] = (static_cast(other)>> 8)&0xff; bytes[2] = (static_cast(other)>>16)&0xff; } } int24::operator int() const { MPT_MAYBE_CONSTANT_IF(mpt::endian_is_big()) { return (static_cast(bytes[0]) * 65536) + (bytes[1] * 256) + bytes[2]; } else { return (static_cast(bytes[2]) * 65536) + (bytes[1] * 256) + bytes[0]; } } #endif OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/mptCPU.cpp0000644000372100037210000002256413161656666017453 00000000000000/* * mptCPU.cpp * ---------- * Purpose: CPU feature detection. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "mptCPU.h" OPENMPT_NAMESPACE_BEGIN #if defined(ENABLE_ASM) uint32 RealProcSupport = 0; uint32 ProcSupport = 0; char ProcVendorID[16+1] = ""; uint16 ProcFamily = 0; uint8 ProcModel = 0; uint8 ProcStepping = 0; #if MPT_COMPILER_MSVC && (defined(ENABLE_X86) || defined(ENABLE_X64)) #include typedef char cpuid_result_string[12]; struct cpuid_result { uint32 a; uint32 b; uint32 c; uint32 d; std::string as_string() const { cpuid_result_string result; result[0+0] = (b >> 0) & 0xff; result[0+1] = (b >> 8) & 0xff; result[0+2] = (b >>16) & 0xff; result[0+3] = (b >>24) & 0xff; result[4+0] = (d >> 0) & 0xff; result[4+1] = (d >> 8) & 0xff; result[4+2] = (d >>16) & 0xff; result[4+3] = (d >>24) & 0xff; result[8+0] = (c >> 0) & 0xff; result[8+1] = (c >> 8) & 0xff; result[8+2] = (c >>16) & 0xff; result[8+3] = (c >>24) & 0xff; return std::string(result, result + 12); } }; static cpuid_result cpuid(uint32 function) { cpuid_result result; int CPUInfo[4]; __cpuid(CPUInfo, function); result.a = CPUInfo[0]; result.b = CPUInfo[1]; result.c = CPUInfo[2]; result.d = CPUInfo[3]; return result; } #if 0 static cpuid_result cpuidex(uint32 function_a, uint32 function_c) { cpuid_result result; int CPUInfo[4]; __cpuidex(CPUInfo, function_a, function_c); result.a = CPUInfo[0]; result.b = CPUInfo[1]; result.c = CPUInfo[2]; result.d = CPUInfo[3]; return result; } #endif static MPT_NOINLINE bool has_cpuid() { const size_t eflags_cpuid = 1 << 21; size_t eflags_old = __readeflags(); size_t eflags_flipped = eflags_old ^ eflags_cpuid; __writeeflags(eflags_flipped); size_t eflags_testchanged = __readeflags(); __writeeflags(eflags_old); return ((eflags_testchanged ^ eflags_old) & eflags_cpuid) != 0; } void InitProcSupport() { RealProcSupport = 0; ProcSupport = 0; MemsetZero(ProcVendorID); ProcFamily = 0; ProcModel = 0; ProcStepping = 0; if(has_cpuid()) { ProcSupport |= PROCSUPPORT_CPUID; cpuid_result VendorString = cpuid(0x00000000u); std::strcpy(ProcVendorID, VendorString.as_string().c_str()); // Cyrix 6x86 and 6x86MX do not specify the value returned in eax. // They both support 0x00000001u however. if((VendorString.as_string() == "CyrixInstead") || (VendorString.a >= 0x00000001u)) { cpuid_result StandardFeatureFlags = cpuid(0x00000001u); uint32 Stepping = (StandardFeatureFlags.a >> 0) & 0x0f; uint32 BaseModel = (StandardFeatureFlags.a >> 4) & 0x0f; uint32 BaseFamily = (StandardFeatureFlags.a >> 8) & 0x0f; uint32 ExtModel = (StandardFeatureFlags.a >> 16) & 0x0f; uint32 ExtFamily = (StandardFeatureFlags.a >> 20) & 0xff; if(VendorString.as_string() == "GenuineIntel") { if(BaseFamily == 0xf) { ProcFamily = static_cast(ExtFamily + BaseFamily); } else { ProcFamily = static_cast(BaseFamily); } if(BaseFamily == 0x6 || BaseFamily == 0xf) { ProcModel = static_cast((ExtModel << 4) | (BaseModel << 0)); } else { ProcModel = static_cast(BaseModel); } } else if(VendorString.as_string() == "AuthenticAMD") { if(BaseFamily == 0xf) { ProcFamily = static_cast(ExtFamily + BaseFamily); ProcModel = static_cast((ExtModel << 4) | (BaseModel << 0)); } else { ProcFamily = static_cast(BaseFamily); ProcModel = static_cast(BaseModel); } } else { ProcFamily = static_cast(BaseFamily); ProcModel = static_cast(BaseModel); } ProcStepping = static_cast(Stepping); if(StandardFeatureFlags.d & (1<< 4)) ProcSupport |= PROCSUPPORT_TSC; if(StandardFeatureFlags.d & (1<<15)) ProcSupport |= PROCSUPPORT_CMOV; if(StandardFeatureFlags.d & (1<< 0)) ProcSupport |= PROCSUPPORT_FPU; if(StandardFeatureFlags.d & (1<<23)) ProcSupport |= PROCSUPPORT_MMX; if(StandardFeatureFlags.d & (1<<25)) ProcSupport |= PROCSUPPORT_SSE; if(StandardFeatureFlags.d & (1<<26)) ProcSupport |= PROCSUPPORT_SSE2; if(StandardFeatureFlags.c & (1<< 0)) ProcSupport |= PROCSUPPORT_SSE3; if(StandardFeatureFlags.c & (1<< 9)) ProcSupport |= PROCSUPPORT_SSSE3; if(StandardFeatureFlags.c & (1<<19)) ProcSupport |= PROCSUPPORT_SSE4_1; if(StandardFeatureFlags.c & (1<<20)) ProcSupport |= PROCSUPPORT_SSE4_2; } // 3DNow! manual recommends to just execute 0x80000000u. // It is totally unknown how earlier CPUs from other vendors // would behave. // Thus we only execute 0x80000000u on other vendors CPUs for the earliest // that we found it documented for and that actually supports 3DNow!. // We only need 0x80000000u in order to detect 3DNow!. // Thus, this is enough for us. if((VendorString.as_string() == "AuthenticAMD") || (VendorString.as_string() == "AMDisbetter!")) { // AMD if((ProcFamily > 5) || ((ProcFamily == 5) && (ProcModel >= 8))) { // >= K6-2 (K6 = Family 5, K6-2 = Model 8) // Not sure if earlier AMD CPUs support 0x80000000u. // AMD 5k86 and AMD K5 manuals do not mention it. cpuid_result ExtendedVendorString = cpuid(0x80000000u); if(ExtendedVendorString.a >= 0x80000001u) { cpuid_result ExtendedFeatureFlags = cpuid(0x80000001u); if(ExtendedFeatureFlags.d & (1<< 4)) ProcSupport |= PROCSUPPORT_TSC; if(ExtendedFeatureFlags.d & (1<<15)) ProcSupport |= PROCSUPPORT_CMOV; if(ExtendedFeatureFlags.d & (1<< 0)) ProcSupport |= PROCSUPPORT_FPU; if(ExtendedFeatureFlags.d & (1<<23)) ProcSupport |= PROCSUPPORT_MMX; if(ExtendedFeatureFlags.d & (1<<22)) ProcSupport |= PROCSUPPORT_AMD_MMXEXT; if(ExtendedFeatureFlags.d & (1<<31)) ProcSupport |= PROCSUPPORT_AMD_3DNOW; if(ExtendedFeatureFlags.d & (1<<30)) ProcSupport |= PROCSUPPORT_AMD_3DNOWEXT; } } } else if(VendorString.as_string() == "CentaurHauls") { // Centaur (IDT WinChip or VIA C3) if(ProcFamily == 5) { // IDT if(ProcModel >= 8) { // >= WinChip 2 cpuid_result ExtendedVendorString = cpuid(0x80000000u); if(ExtendedVendorString.a >= 0x80000001u) { cpuid_result ExtendedFeatureFlags = cpuid(0x80000001u); if(ExtendedFeatureFlags.d & (1<<31)) ProcSupport |= PROCSUPPORT_AMD_3DNOW; } } } else if(ProcFamily >= 6) { // VIA if((ProcFamily >= 7) || ((ProcFamily == 6) && (ProcModel >= 7))) { // >= C3 Samuel 2 cpuid_result ExtendedVendorString = cpuid(0x80000000u); if(ExtendedVendorString.a >= 0x80000001u) { cpuid_result ExtendedFeatureFlags = cpuid(0x80000001u); if(ExtendedFeatureFlags.d & (1<<31)) ProcSupport |= PROCSUPPORT_AMD_3DNOW; } } } } else if(VendorString.as_string() == "CyrixInstead") { // Cyrix // 6x86 : 5.2.x // 6x86L : 5.2.x // MediaGX : 4.4.x // 6x86MX : 6.0.x // MII : 6.0.x // MediaGXm: 5.4.x // well, doh ... if((ProcFamily == 5) && (ProcModel >= 4)) { // Cyrix MediaGXm cpuid_result ExtendedVendorString = cpuid(0x80000000u); if(ExtendedVendorString.a >= 0x80000001u) { cpuid_result ExtendedFeatureFlags = cpuid(0x80000001u); if(ExtendedFeatureFlags.d & (1<<31)) ProcSupport |= PROCSUPPORT_AMD_3DNOW; } } } else if(VendorString.as_string() == "Geode by NSC") { // National Semiconductor if((ProcFamily > 5) || ((ProcFamily == 5) && (ProcModel >= 5))) { // >= Geode GX2 cpuid_result ExtendedVendorString = cpuid(0x80000000u); if(ExtendedVendorString.a >= 0x80000001u) { cpuid_result ExtendedFeatureFlags = cpuid(0x80000001u); if(ExtendedFeatureFlags.d & (1<<31)) ProcSupport |= PROCSUPPORT_AMD_3DNOW; } } } } else { ProcSupport |= PROCSUPPORT_FPU; // We assume FPU because we require it. } // We do not have to check if SSE got enabled by the OS because we only do // support Windows >= 98 SE which will always enable SSE if available. RealProcSupport = ProcSupport; } #else // !( MPT_COMPILER_MSVC && ENABLE_X86 ) void InitProcSupport() { ProcSupport = 0; } #endif // MPT_COMPILER_MSVC && ENABLE_X86 #endif // ENABLE_ASM #ifdef MODPLUG_TRACKER uint32 GetMinimumProcSupportFlags() { uint32 flags = 0; #ifdef ENABLE_ASM #if MPT_COMPILER_MSVC #if defined(_M_X64) flags |= PROCSUPPORT_AMD64; #elif defined(_M_IX86) #if defined(_M_IX86_FP) #if (_M_IX86_FP >= 2) flags |= PROCSUPPORT_x86_SSE2; #elif (_M_IX86_FP == 1) flags |= PROCSUPPORT_x86_SSE; #endif #else flags |= PROCSUPPORT_i586; #endif #endif #endif #endif // ENABLE_ASM return flags; } int GetMinimumSSEVersion() { int minimumSSEVersion = 0; #if MPT_COMPILER_MSVC #if defined(_M_X64) minimumSSEVersion = 2; #elif defined(_M_IX86) #if defined(_M_IX86_FP) #if (_M_IX86_FP >= 2) minimumSSEVersion = 2; #elif (_M_IX86_FP == 1) minimumSSEVersion = 1; #endif #endif #endif #endif return minimumSSEVersion; } int GetMinimumAVXVersion() { int minimumAVXVersion = 0; #if MPT_COMPILER_MSVC #if defined(_M_IX86_FP) #if defined(__AVX2__) minimumAVXVersion = 2; #elif defined(__AVX__) minimumAVXVersion = 1; #endif #endif #endif return minimumAVXVersion; } #endif #if !defined(MODPLUG_TRACKER) && !defined(ENABLE_ASM) MPT_MSVC_WORKAROUND_LNK4221(mptCPU) #endif OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/version.h0000644000372100037210000001122013147105157017404 00000000000000/* * version.h * --------- * Purpose: OpenMPT version handling. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "FlagSet.h" #include OPENMPT_NAMESPACE_BEGIN //Creates version number from version parts that appears in version string. //For example MAKE_VERSION_NUMERIC(1,17,02,28) gives version number of //version 1.17.02.28. #define MAKE_VERSION_NUMERIC_HELPER(prefix,v0,v1,v2,v3) ((prefix##v0 << 24) | (prefix##v1<<16) | (prefix##v2<<8) | (prefix##v3)) #define MAKE_VERSION_NUMERIC(v0,v1,v2,v3) (MptVersion::VersionNum(MAKE_VERSION_NUMERIC_HELPER(0x,v0,v1,v2,v3))) namespace MptVersion { typedef uint32 VersionNum; extern const VersionNum num; // e.g. 0x01170208 extern const char * const str; // e.g "1.17.02.08" // Return a OpenMPT version string suitable for file format tags std::string GetOpenMPTVersionStr(); // e.g. "OpenMPT 1.17.02.08" // Returns numerical version value from given version string. VersionNum ToNum(const std::string &s); // Returns version string from given numerical version value. std::string ToStr(const VersionNum v); mpt::ustring ToUString(const VersionNum v); // Return a version without build number (the last number in the version). // The current versioning scheme uses this number only for test builds, and it should be 00 for official builds, // So sometimes it might be wanted to do comparisons without the build number. VersionNum RemoveBuildNumber(const VersionNum num_); // Returns true if a given version number is from a test build, false if it's a release build. bool IsTestBuild(const VersionNum num_ = MptVersion::num); // Return true if this is a debug build with no optimizations bool IsDebugBuild(); struct SourceInfo { std::string Url; // svn repository url (or empty string) int Revision; // svn revision (or 0) bool IsDirty; // svn working copy is dirty (or false) bool HasMixedRevisions; // svn working copy has mixed revisions (or false) bool IsPackage; // source code originates from a packaged version of the source code std::string Date; // svn date (or empty string) SourceInfo() : Url(std::string()), Revision(0), IsDirty(false), HasMixedRevisions(false), IsPackage(false) { } public: std::string GetUrlWithRevision() const; // i.e. "https://source.openmpt.org/svn/openmpt/trunk/OpenMPT@1234" or empty string std::string GetStateString() const; // i.e. "+dirty" or "clean" }; SourceInfo GetSourceInfo(); // Returns either the URL to download release builds or the URL to download test builds, depending on the current build. mpt::ustring GetDownloadURL(); // Return a string decribing the time of the build process (if built from a svn working copy and tsvn was available during build, otherwise it returns the time version.cpp was last rebuild which could be unreliable as it does not get rebuild every time without tsvn) std::string GetBuildDateString(); // Return a string decribing some of the build features std::string GetBuildFeaturesString(); // e.g. " NO_VST NO_DSOUND" // Return a string describing the compiler version used for building. std::string GetBuildCompilerString(); // e.g. "Microsoft Compiler 15.00.20706.01" enum Strings { StringsNone = 0, StringVersion = 1<<0, // "1.23.35.45" StringRevision = 1<<2, // "-r1234+" StringBitness = 1<<3, // "32 bit" StringSourceInfo = 1<<4, // "https://source.openmpt.org/svn/openmpt/trunk/OpenMPT@1234 (2016-01-02) +dirty" StringBuildFlags = 1<<5, // "TEST DEBUG" StringBuildFeatures = 1<<6, // "NO_VST NO_DSOUND" }; MPT_DECLARE_ENUM(Strings) // Returns a versions string with the fields selected via @strings. std::string GetVersionString(FlagSet strings); // Returns a pure version string std::string GetVersionStringPure(); // e.g. "1.17.02.08-r1234+ 32 bit" // Returns a simple version string std::string GetVersionStringSimple(); // e.g. "1.17.02.08-r1234+ TEST" // Returns MptVersion::str if the build is a clean release build straight from the repository or an extended string otherwise (if built from a svn working copy and tsvn was available during build) std::string GetVersionStringExtended(); // e.g. "1.17.02.08-r1234+ 32 bit DEBUG" // Returns a URL for the respective keys. Supported keys: "website", "forum", "bugtracker", "updates", "top_picks" mpt::ustring GetURL(std::string key); // Returns a multi-line string containing the full credits for the code base mpt::ustring GetFullCreditsString(); // Returns the OpenMPT license text mpt::ustring GetLicenseString(); } //namespace MptVersion OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/mptCRC.h0000644000372100037210000001121412726225556017062 00000000000000/* * mptCRC.h * -------- * Purpose: generic CRC implementation * Notes : (currently none) * Authors: Joern Heusipp * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once OPENMPT_NAMESPACE_BEGIN namespace mpt { namespace checksum { template class crc { public: typedef crc self_type; typedef T value_type; typedef uint8 byte_type; static const std::size_t size_bytes = sizeof(value_type); static const std::size_t size_bits = sizeof(value_type) * 8; static const value_type top_bit = static_cast(1) << ((sizeof(value_type) * 8) - 1); private: template static inline Tint reverse(Tint value) { const std::size_t bits = sizeof(Tint) * 8; Tint result = 0; for(std::size_t i = 0; i < bits; ++i) { result <<= 1; result |= static_cast(value & 0x1); value >>= 1; } return result; } static inline value_type calculate_table_entry(byte_type pos) { value_type value = 0; value = (static_cast(reverseData ? reverse(pos) : pos) << (size_bits - 8)); for(std::size_t bit = 0; bit < 8; ++bit) { if(value & top_bit) { value = (value << 1) ^ polynomial; } else { value = (value << 1); } } value = (reverseData ? reverse(value) : value); return value; } private: static value_type table[256]; static inline void fill_table() { for(std::size_t i = 0; i < 256; ++i) { table[i] = calculate_table_entry(static_cast(i)); } } struct table_filler { inline table_filler() { self_type::fill_table(); } }; static inline void init() { static table_filler table_filler; } private: inline value_type read_table(byte_type pos) const { return table[pos]; } private: value_type value; public: crc() : value(initial) { init(); } inline void processByte(byte_type byte) { MPT_CONSTANT_IF(reverseData) { value = (value >> 8) ^ read_table(static_cast((value & 0xff) ^ byte)); } else { value = (value << 8) ^ read_table(static_cast(((value >> (size_bits - 8)) & 0xff) ^ byte)); } } inline value_type result() const { return (value ^ resultXOR); } public: inline operator value_type () const { return result(); } inline crc & process(char c) { processByte(static_cast(c)); return *this; } inline crc & process(signed char c) { processByte(static_cast(c)); return *this; } inline crc & process(unsigned char c) { processByte(static_cast(c)); return *this; } template crc & process(InputIt beg, InputIt end) { for(InputIt it = beg; it != end; ++it) { static_assert(sizeof(*it) == 1, "1 byte type required"); process(*it); } return *this; } template inline crc & process(const Container &data) { operator () (data.begin(), data.end()); return *this; } inline crc & operator () (char c) { processByte(static_cast(c)); return *this; } inline crc & operator () (signed char c) { processByte(static_cast(c)); return *this; } inline crc & operator () (unsigned char c) { processByte(static_cast(c)); return *this; } template crc & operator () (InputIt beg, InputIt end) { for(InputIt it = beg; it != end; ++it) { static_assert(sizeof(*it) == 1, "1 byte type required"); operator () (*it); } return *this; } template inline crc & operator () (const Container &data) { operator () (data.begin(), data.end()); return *this; } template crc(InputIt beg, InputIt end) : value(initial) { init(); for(InputIt it = beg; it != end; ++it) { static_assert(sizeof(*it) == 1, "1 byte type required"); process(*it); } } template inline crc(const Container &data) : value(initial) { init(); process(data.begin(), data.end()); } }; template typename crc::value_type crc::table[256]; typedef crc crc16; typedef crc crc32; typedef crc crc32_ogg; typedef crc crc32c; typedef crc crc64_jones; } // namespace checksum using mpt::checksum::crc32; using mpt::checksum::crc32_ogg; } // namespace mpt OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/FileReader.cpp0000644000372100037210000000664313161656666020305 00000000000000/* * FileReader.cpp * -------------- * Purpose: A basic class for transparent reading of memory-based files. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "FileReader.h" #if defined(MPT_ENABLE_TEMPFILE) && MPT_OS_WINDOWS #include #endif // MPT_ENABLE_TEMPFILE && MPT_OS_WINDOWS OPENMPT_NAMESPACE_BEGIN #if defined(MPT_ENABLE_TEMPFILE) && MPT_OS_WINDOWS OnDiskFileWrapper::OnDiskFileWrapper(FileReader &file, const mpt::PathString &fileNameExtension) : m_IsTempFile(false) { try { file.Rewind(); if(file.GetFileName().empty()) { const mpt::PathString tempName = mpt::CreateTempFileName(MPT_PATHSTRING("OpenMPT"), fileNameExtension); #if MPT_OS_WINDOWS && MPT_OS_WINDOWS_WINRT #if (_WIN32_WINNT < 0x0602) #define MPT_ONDISKFILEWRAPPER_NO_CREATEFILE #endif #endif #ifdef MPT_ONDISKFILEWRAPPER_NO_CREATEFILE FILE * f = _wfopen(tempName.AsNative().c_str(), L"wb"); if(!f) { throw std::runtime_error(""); } while(!file.EndOfFile()) { FileReader::PinnedRawDataView view = file.ReadPinnedRawDataView(mpt::IO::BUFFERSIZE_NORMAL); std::size_t towrite = view.size(); std::size_t written = 0; do { std::size_t chunkSize = mpt::saturate_cast(towrite); std::size_t chunkDone = 0; chunkDone = fwrite(view.data() + written, 1, chunkSize, f); if(chunkDone != chunkSize) { fclose(f); f = NULL; throw std::runtime_error(""); } towrite -= chunkDone; written += chunkDone; } while(towrite > 0); } fclose(f); f = NULL; #else // !MPT_ONDISKFILEWRAPPER_NO_CREATEFILE HANDLE hFile = NULL; #if MPT_OS_WINDOWS_WINRT hFile = CreateFile2(tempName.AsNative().c_str(), GENERIC_WRITE, FILE_SHARE_READ, CREATE_ALWAYS, NULL); #else hFile = CreateFileW(tempName.AsNative().c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, NULL); #endif if(hFile == NULL || hFile == INVALID_HANDLE_VALUE) { throw std::runtime_error(""); } while(!file.EndOfFile()) { FileReader::PinnedRawDataView view = file.ReadPinnedRawDataView(mpt::IO::BUFFERSIZE_NORMAL); std::size_t towrite = view.size(); std::size_t written = 0; do { DWORD chunkSize = mpt::saturate_cast(towrite); DWORD chunkDone = 0; WriteFile(hFile, view.data() + written, chunkSize, &chunkDone, NULL); if(chunkDone != chunkSize) { CloseHandle(hFile); hFile = NULL; throw std::runtime_error(""); } towrite -= chunkDone; written += chunkDone; } while(towrite > 0); } CloseHandle(hFile); hFile = NULL; #endif // MPT_ONDISKFILEWRAPPER_NO_CREATEFILE m_Filename = tempName; m_IsTempFile = true; } else { m_Filename = file.GetFileName(); } } catch (const std::runtime_error &) { m_IsTempFile = false; m_Filename = mpt::PathString(); } } OnDiskFileWrapper::~OnDiskFileWrapper() { if(m_IsTempFile) { DeleteFileW(m_Filename.AsNative().c_str()); m_IsTempFile = false; } m_Filename = mpt::PathString(); } bool OnDiskFileWrapper::IsValid() const { return !m_Filename.empty(); } mpt::PathString OnDiskFileWrapper::GetFilename() const { return m_Filename; } #else MPT_MSVC_WORKAROUND_LNK4221(FileReader) #endif // MPT_ENABLE_TEMPFILE && MPT_OS_WINDOWS OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/mptThread.h0000644000372100037210000002327513076367670017677 00000000000000/* * mptThread.h * ----------- * Purpose: Helper class for running threads, with a more or less platform-independent interface. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #if defined(MPT_ENABLE_THREAD) #include // some C++ header in order to have the C++ standard library version information available #if defined(MPT_QUIRK_NO_CPP_THREAD) #define MPT_STD_THREAD 0 #elif MPT_COMPILER_GENERIC #define MPT_STD_THREAD 1 #elif MPT_COMPILER_MSVC #define MPT_STD_THREAD 1 #elif MPT_COMPILER_GCC && !MPT_OS_WINDOWS #define MPT_STD_THREAD 1 #elif MPT_COMPILER_CLANG && defined(__GLIBCXX__) #define MPT_STD_THREAD 1 #elif (MPT_OS_MACOSX_OR_IOS || MPT_OS_FREEBSD) && MPT_COMPILER_CLANG #define MPT_STD_THREAD 1 #elif MPT_CLANG_AT_LEAST(3,6,0) && defined(_LIBCPP_VERSION) #define MPT_STD_THREAD 1 #else #define MPT_STD_THREAD 0 #endif #if MPT_STD_THREAD #include #else // !MPT_STD_THREAD #if MPT_OS_WINDOWS #include #else // !MPT_OS_WINDOWS #include #endif // MPT_OS_WINDOWS #endif // MPT_STD_THREAD #if defined(MODPLUG_TRACKER) #if MPT_OS_WINDOWS #include #endif // MPT_OS_WINDOWS #endif // MODPLUG_TRACKER #endif // MPT_ENABLE_THREAD OPENMPT_NAMESPACE_BEGIN #if defined(MPT_ENABLE_THREAD) namespace mpt { #if MPT_STD_THREAD typedef std::thread::native_handle_type native_handle_type; typedef std::thread thread; #else // !MPT_STD_THREAD #if MPT_OS_WINDOWS typedef HANDLE native_handle_type; // std::thread // NOTE: This implementation is not movable and prevents copying. // Therefore, it is not as versatile as a full C++11 std::thread implementation. // It is only a strict subset. class thread { private: thread(const thread &) = delete; thread & operator = (const thread &) = delete; private: class functor_helper_base { protected: functor_helper_base() {} public: virtual ~functor_helper_base() {} public: virtual void operator () () = 0; }; template class functor_helper : public functor_helper_base { private: Tfunc func; public: functor_helper(Tfunc func_) : func(func_) { return; } virtual ~functor_helper() { return; } virtual void operator () () { func(); } }; enum FunctionMode { FunctionModeNone = 0, FunctionModeParamNone = 1, FunctionModeParamPointer = 2, FunctionModeFunctor = 3, }; native_handle_type threadHandle; // Thread startup accesses members of mpt::thread. // If the mpt::thread instanced gets detached and destroyed directly after initialization, // there is a race between thread startup and detach/destroy. // startupDoneEvent protects against this race. HANDLE startupDoneEvent; FunctionMode functionMode; union { struct { void (*function)(void); } ModeParamNone; struct { void (*function)(void*); void * userdata; } ModeParamPointer; struct { functor_helper_base * pfunctor; } ModeFunctor; } modeState; private: uintptr_t ThreadFuntion() { switch(functionMode) { case FunctionModeNone: SetEvent(startupDoneEvent); return 0; break; case FunctionModeParamNone: { void (*f)(void) = modeState.ModeParamNone.function; SetEvent(startupDoneEvent); f(); } return 0; break; case FunctionModeParamPointer: { void (*f)(void*) = modeState.ModeParamPointer.function; void * d = modeState.ModeParamPointer.userdata; SetEvent(startupDoneEvent); f(d); } return 0; break; case FunctionModeFunctor: { functor_helper_base * pf = modeState.ModeFunctor.pfunctor; SetEvent(startupDoneEvent); (*pf)(); delete pf; } return 0; break; default: SetEvent(startupDoneEvent); return 0; break; } SetEvent(startupDoneEvent); return 0; } static DWORD WINAPI ThreadFunctionWrapper(LPVOID param) { reinterpret_cast(param)->ThreadFuntion(); return 0; } public: mpt::native_handle_type native_handle() { return threadHandle; } bool joinable() const { return (threadHandle != nullptr); } void join() { if(!joinable()) { throw std::invalid_argument("thread::joinable() == false"); } WaitForSingleObject(threadHandle, INFINITE); CloseHandle(threadHandle); threadHandle = nullptr; } void detach() { if(!joinable()) { throw std::invalid_argument("thread::joinable() == false"); } CloseHandle(threadHandle); threadHandle = nullptr; } void swap(thread & other) noexcept { using std::swap; swap(threadHandle, other.threadHandle); swap(startupDoneEvent, other.startupDoneEvent); swap(functionMode, other.functionMode); } friend void swap(thread & a, thread & b) noexcept { a.swap(b); } thread(thread && other) noexcept : threadHandle(nullptr) , startupDoneEvent(nullptr) , functionMode(FunctionModeNone) { swap(other); } thread & operator=(thread && other) noexcept { if(joinable()) { std::terminate(); } swap(other); return *this; } thread() : threadHandle(nullptr) , startupDoneEvent(nullptr) , functionMode(FunctionModeNone) { std::memset(&modeState, 0, sizeof(modeState)); } thread(void (*function)(void)) : threadHandle(nullptr) , startupDoneEvent(nullptr) , functionMode(FunctionModeParamNone) { std::memset(&modeState, 0, sizeof(modeState)); modeState.ModeParamNone.function = function; startupDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if(!startupDoneEvent) { throw std::runtime_error("unable to start thread"); } DWORD dummy = 0; // For Win9x threadHandle = CreateThread(NULL, 0, ThreadFunctionWrapper, this, 0, &dummy); if(threadHandle) { WaitForSingleObject(startupDoneEvent, INFINITE); } CloseHandle(startupDoneEvent); startupDoneEvent = nullptr; if(!threadHandle) { throw std::runtime_error("unable to start thread"); } } thread(void (*function)(void*), void * userdata) : threadHandle(nullptr) , startupDoneEvent(nullptr) , functionMode(FunctionModeParamPointer) { std::memset(&modeState, 0, sizeof(modeState)); modeState.ModeParamPointer.function = function; modeState.ModeParamPointer.userdata = userdata; startupDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if(!startupDoneEvent) { throw std::runtime_error("unable to start thread"); } DWORD dummy = 0; // For Win9x threadHandle = CreateThread(NULL, 0, ThreadFunctionWrapper, this, 0, &dummy); if(threadHandle) { WaitForSingleObject(startupDoneEvent, INFINITE); } CloseHandle(startupDoneEvent); startupDoneEvent = nullptr; if(!threadHandle) { throw std::runtime_error("unable to start thread"); } } template thread(Tfunctor functor) : threadHandle(nullptr) , startupDoneEvent(nullptr) , functionMode(FunctionModeFunctor) { std::memset(&modeState, 0, sizeof(modeState)); modeState.ModeFunctor.pfunctor = new functor_helper(functor); startupDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if(!startupDoneEvent) { throw std::runtime_error("unable to start thread"); } DWORD dummy = 0; // For Win9x threadHandle = CreateThread(NULL, 0, ThreadFunctionWrapper, this, 0, &dummy); if(threadHandle) { WaitForSingleObject(startupDoneEvent, INFINITE); } CloseHandle(startupDoneEvent); startupDoneEvent = nullptr; if(!threadHandle) { throw std::runtime_error("unable to start thread"); } } ~thread() { MPT_ASSERT(!joinable()); } public: static unsigned int hardware_concurrency() { SYSTEM_INFO sysInfo; GetSystemInfo(&sysInfo); return std::max(sysInfo.dwNumberOfProcessors, 1); } }; #endif // MPT_OS_WINDOWS #endif // MPT_STD_THREAD #if defined(MODPLUG_TRACKER) #if MPT_OS_WINDOWS enum ThreadPriority { ThreadPriorityLowest = THREAD_PRIORITY_LOWEST, ThreadPriorityLower = THREAD_PRIORITY_BELOW_NORMAL, ThreadPriorityNormal = THREAD_PRIORITY_NORMAL, ThreadPriorityHigh = THREAD_PRIORITY_ABOVE_NORMAL, ThreadPriorityHighest = THREAD_PRIORITY_HIGHEST }; inline void SetThreadPriority(mpt::thread &t, mpt::ThreadPriority priority) { ::SetThreadPriority(t.native_handle(), priority); } inline void SetCurrentThreadPriority(mpt::ThreadPriority priority) { ::SetThreadPriority(GetCurrentThread(), priority); } #else // !MPT_OS_WINDOWS enum ThreadPriority { ThreadPriorityLowest = -2, ThreadPriorityLower = -1, ThreadPriorityNormal = 0, ThreadPriorityHigh = 1, ThreadPriorityHighest = 2 }; inline void SetThreadPriority(mpt::thread & /*t*/ , mpt::ThreadPriority /*priority*/ ) { // nothing } inline void SetCurrentThreadPriority(mpt::ThreadPriority /*priority*/ ) { // nothing } #endif // MPT_OS_WINDOWS #endif // MODPLUG_TRACKER #if defined(MODPLUG_TRACKER) #if MPT_OS_WINDOWS // Default WinAPI thread class UnmanagedThread { protected: HANDLE threadHandle; public: operator HANDLE& () { return threadHandle; } operator bool () const { return threadHandle != nullptr; } UnmanagedThread() : threadHandle(nullptr) { } UnmanagedThread(LPTHREAD_START_ROUTINE function, void *userData = nullptr) { DWORD dummy = 0; // For Win9x threadHandle = CreateThread(NULL, 0, function, userData, 0, &dummy); } }; // Thread that operates on a member function template class UnmanagedThreadMember : public mpt::UnmanagedThread { protected: static DWORD WINAPI wrapperFunc(LPVOID param) { (static_cast(param)->*Fun)(); return 0; } public: UnmanagedThreadMember(T *instance) : mpt::UnmanagedThread(wrapperFunc, instance) { } }; inline void SetThreadPriority(mpt::UnmanagedThread &t, mpt::ThreadPriority priority) { ::SetThreadPriority(t, priority); } #endif // MPT_OS_WINDOWS #endif // MODPLUG_TRACKER } // namespace mpt #endif // MPT_ENABLE_THREAD OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/mptUUID.cpp0000644000372100037210000003535213161656666017571 00000000000000/* * mptUUID.cpp * ----------- * Purpose: UUID utility functions. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "mptUUID.h" #include "mptRandom.h" #include "mptStringFormat.h" #include "Endianness.h" #include #if MPT_OS_WINDOWS #include #include #if defined(MODPLUG_TRACKER) || !defined(NO_DMO) || MPT_OS_WINDOWS_WINRT #include #endif // MODPLUG_TRACKER || !NO_DMO || MPT_OS_WINDOWS_WINRT #endif // MPT_OS_WINDOWS OPENMPT_NAMESPACE_BEGIN #if MPT_OS_WINDOWS namespace Util { #if defined(MODPLUG_TRACKER) || !defined(NO_DMO) std::wstring CLSIDToString(CLSID clsid) { std::wstring str; LPOLESTR tmp = nullptr; switch(::StringFromCLSID(clsid, &tmp)) { case S_OK: break; case E_OUTOFMEMORY: if(tmp) { ::CoTaskMemFree(tmp); tmp = nullptr; } MPT_EXCEPTION_THROW_OUT_OF_MEMORY(); break; default: if(tmp) { ::CoTaskMemFree(tmp); tmp = nullptr; } throw std::logic_error("StringFromCLSID() failed."); break; } if(!tmp) { throw std::logic_error("StringFromCLSID() failed."); } try { str = tmp; } MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e) { ::CoTaskMemFree(tmp); tmp = nullptr; MPT_UNUSED_VARIABLE(e); MPT_EXCEPTION_RETHROW_OUT_OF_MEMORY(); } ::CoTaskMemFree(tmp); tmp = nullptr; return str; } CLSID StringToCLSID(const std::wstring &str) { CLSID clsid = CLSID(); std::vector tmp(str.c_str(), str.c_str() + str.length() + 1); switch(::CLSIDFromString(tmp.data(), &clsid)) { case NOERROR: // nothing break; case E_INVALIDARG: clsid = CLSID(); break; case CO_E_CLASSSTRING: clsid = CLSID(); break; case REGDB_E_CLASSNOTREG: clsid = CLSID(); break; case REGDB_E_READREGDB: clsid = CLSID(); throw std::runtime_error("CLSIDFromString() failed: REGDB_E_READREGDB."); break; default: clsid = CLSID(); throw std::logic_error("CLSIDFromString() failed."); break; } return clsid; } bool VerifyStringToCLSID(const std::wstring &str, CLSID &clsid) { bool result = false; clsid = CLSID(); std::vector tmp(str.c_str(), str.c_str() + str.length() + 1); switch(::CLSIDFromString(tmp.data(), &clsid)) { case NOERROR: result = true; break; case E_INVALIDARG: result = false; break; case CO_E_CLASSSTRING: result = false; break; case REGDB_E_CLASSNOTREG: result = false; break; case REGDB_E_READREGDB: throw std::runtime_error("CLSIDFromString() failed: REGDB_E_READREGDB."); break; default: throw std::logic_error("CLSIDFromString() failed."); break; } return result; } bool IsCLSID(const std::wstring &str) { bool result = false; CLSID clsid = CLSID(); std::vector tmp(str.c_str(), str.c_str() + str.length() + 1); switch(::CLSIDFromString(tmp.data(), &clsid)) { case NOERROR: result = true; break; case E_INVALIDARG: result = false; break; case CO_E_CLASSSTRING: result = false; break; case REGDB_E_CLASSNOTREG: result = false; break; case REGDB_E_READREGDB: result = false; throw std::runtime_error("CLSIDFromString() failed: REGDB_E_READREGDB."); break; default: result = false; throw std::logic_error("CLSIDFromString() failed."); break; } return result; } std::wstring IIDToString(IID iid) { std::wstring str; LPOLESTR tmp = nullptr; switch(::StringFromIID(iid, &tmp)) { case S_OK: break; case E_OUTOFMEMORY: if(tmp) { ::CoTaskMemFree(tmp); tmp = nullptr; } MPT_EXCEPTION_THROW_OUT_OF_MEMORY(); break; default: if(tmp) { ::CoTaskMemFree(tmp); tmp = nullptr; } throw std::logic_error("StringFromIID() failed."); break; } if(!tmp) { throw std::logic_error("StringFromIID() failed."); } try { str = tmp; } MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e) { ::CoTaskMemFree(tmp); tmp = nullptr; MPT_UNUSED_VARIABLE(e); MPT_EXCEPTION_RETHROW_OUT_OF_MEMORY(); } return str; } IID StringToIID(const std::wstring &str) { IID iid = IID(); std::vector tmp(str.c_str(), str.c_str() + str.length() + 1); switch(::IIDFromString(tmp.data(), &iid)) { case S_OK: // nothing break; case E_OUTOFMEMORY: iid = IID(); MPT_EXCEPTION_THROW_OUT_OF_MEMORY(); break; case E_INVALIDARG: iid = IID(); break; default: iid = IID(); throw std::logic_error("IIDFromString() failed."); break; } return iid; } std::wstring GUIDToString(GUID guid) { std::vector tmp(256); if(::StringFromGUID2(guid, tmp.data(), static_cast(tmp.size())) <= 0) { throw std::logic_error("StringFromGUID2() failed."); } return tmp.data(); } GUID StringToGUID(const std::wstring &str) { return StringToIID(str); } GUID CreateGUID() { GUID guid = GUID(); switch(::CoCreateGuid(&guid)) { case S_OK: // nothing break; default: guid = GUID(); throw std::runtime_error("CoCreateGuid() failed."); } return guid; } #if !MPT_OS_WINDOWS_WINRT UUID StringToUUID(const mpt::ustring &str) { UUID uuid = UUID(); std::wstring wstr = mpt::ToWide(str); std::vector tmp(wstr.c_str(), wstr.c_str() + wstr.length() + 1); switch(::UuidFromStringW((RPC_WSTR)(&(tmp[0])), &uuid)) { case RPC_S_OK: // nothing break; case RPC_S_INVALID_STRING_UUID: uuid = UUID(); break; default: throw std::logic_error("UuidFromStringW() failed."); break; } return uuid; } mpt::ustring UUIDToString(UUID uuid) { std::wstring wstr; RPC_WSTR tmp = nullptr; switch(::UuidToStringW(&uuid, &tmp)) { case RPC_S_OK: // nothing break; case RPC_S_OUT_OF_MEMORY: if(tmp) { ::RpcStringFreeW(&tmp); tmp = nullptr; } MPT_EXCEPTION_THROW_OUT_OF_MEMORY(); break; default: throw std::logic_error("UuidToStringW() failed."); break; } try { std::size_t len = 0; for(len = 0; tmp[len] != 0; ++len) { // nothing } wstr = std::wstring(tmp, tmp + len); } MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e) { ::RpcStringFreeW(&tmp); tmp = nullptr; MPT_UNUSED_VARIABLE(e); MPT_EXCEPTION_RETHROW_OUT_OF_MEMORY(); } return mpt::ToUnicode(wstr); } #endif // !MPT_OS_WINDOWS_WINRT bool IsValid(UUID uuid) { return false || uuid.Data1 != 0 || uuid.Data2 != 0 || uuid.Data3 != 0 || uuid.Data4[0] != 0 || uuid.Data4[1] != 0 || uuid.Data4[2] != 0 || uuid.Data4[3] != 0 || uuid.Data4[4] != 0 || uuid.Data4[5] != 0 || uuid.Data4[6] != 0 || uuid.Data4[7] != 0 ; } #endif // MODPLUG_TRACKER || !NO_DMO } // namespace Util #endif // MPT_OS_WINDOWS namespace mpt { #if MPT_OS_WINDOWS mpt::UUID UUIDFromWin32(::UUID uuid) { return mpt::UUID ( uuid.Data1 , uuid.Data2 , uuid.Data3 , (static_cast(0) | (static_cast(uuid.Data4[0]) << 56) | (static_cast(uuid.Data4[1]) << 48) | (static_cast(uuid.Data4[2]) << 40) | (static_cast(uuid.Data4[3]) << 32) | (static_cast(uuid.Data4[4]) << 24) | (static_cast(uuid.Data4[5]) << 16) | (static_cast(uuid.Data4[6]) << 8) | (static_cast(uuid.Data4[7]) << 0) ) ); } ::UUID UUIDToWin32(mpt::UUID uuid) { ::UUID result = ::UUID(); result.Data1 = uuid.GetData1(); result.Data2 = uuid.GetData2(); result.Data3 = uuid.GetData3(); result.Data4[0] = static_cast(uuid.GetData4() >> 56); result.Data4[1] = static_cast(uuid.GetData4() >> 48); result.Data4[2] = static_cast(uuid.GetData4() >> 40); result.Data4[3] = static_cast(uuid.GetData4() >> 32); result.Data4[4] = static_cast(uuid.GetData4() >> 24); result.Data4[5] = static_cast(uuid.GetData4() >> 16); result.Data4[6] = static_cast(uuid.GetData4() >> 8); result.Data4[7] = static_cast(uuid.GetData4() >> 0); return result; } #if defined(MODPLUG_TRACKER) || !defined(NO_DMO) UUID::UUID(::UUID uuid) { *this = UUIDFromWin32(uuid); } UUID::operator ::UUID () const { return UUIDToWin32(*this); } mpt::UUID UUID::FromGroups(uint32 group1, uint16 group2, uint16 group3, uint16 group4, uint64 group5) { MPT_ASSERT((group5 & 0xffff000000000000ull) == 0ull); return mpt::UUID ( group1 , group2 , group3 , (static_cast(group4) << 48) | group5 ); } #endif // MODPLUG_TRACKER || !NO_DMO #endif // MPT_OS_WINDOWS UUID UUID::Generate() { #if MPT_OS_WINDOWS && MPT_OS_WINDOWS_WINRT #if (_WIN32_WINNT >= 0x0602) ::GUID guid = ::GUID(); HRESULT result = CoCreateGuid(&guid); if(result != S_OK) { return mpt::UUID::RFC4122Random(); } return mpt::UUIDFromWin32(guid); #else return mpt::UUID::RFC4122Random(); #endif #elif MPT_OS_WINDOWS && !MPT_OS_WINDOWS_WINRT ::UUID uuid = ::UUID(); RPC_STATUS status = ::UuidCreate(&uuid); if(status != RPC_S_OK && status != RPC_S_UUID_LOCAL_ONLY) { return mpt::UUID::RFC4122Random(); } status = RPC_S_OK; if(UuidIsNil(&uuid, &status) != FALSE) { return mpt::UUID::RFC4122Random(); } if(status != RPC_S_OK) { return mpt::UUID::RFC4122Random(); } return mpt::UUIDFromWin32(uuid); #else return RFC4122Random(); #endif } UUID UUID::GenerateLocalUseOnly() { #if MPT_OS_WINDOWS && MPT_OS_WINDOWS_WINRT #if (_WIN32_WINNT >= 0x0602) ::GUID guid = ::GUID(); HRESULT result = CoCreateGuid(&guid); if(result != S_OK) { return mpt::UUID::RFC4122Random(); } return mpt::UUIDFromWin32(guid); #else return mpt::UUID::RFC4122Random(); #endif #elif MPT_OS_WINDOWS && !MPT_OS_WINDOWS_WINRT #if _WIN32_WINNT >= 0x0501 // Available since Win2000, but we check for WinXP in order to not use this // function in Win32old builds. It is not available on some non-fully // patched Win98SE installs in the wild. ::UUID uuid = ::UUID(); RPC_STATUS status = ::UuidCreateSequential(&uuid); if(status != RPC_S_OK && status != RPC_S_UUID_LOCAL_ONLY) { return Generate(); } status = RPC_S_OK; if(UuidIsNil(&uuid, &status) != FALSE) { return mpt::UUID::RFC4122Random(); } if(status != RPC_S_OK) { return mpt::UUID::RFC4122Random(); } return mpt::UUIDFromWin32(uuid); #else // Fallback to ::UuidCreate is safe as ::UuidCreateSequential is only a // tiny performance optimization. return Generate(); #endif #else return RFC4122Random(); #endif } UUID UUID::RFC4122Random() { UUID result; mpt::thread_safe_prng & prng = mpt::global_prng(); result.Data1 = mpt::random(prng); result.Data2 = mpt::random(prng); result.Data3 = mpt::random(prng); result.Data4 = mpt::random(prng); result.MakeRFC4122(4); return result; } uint32 UUID::GetData1() const { return Data1; } uint16 UUID::GetData2() const { return Data2; } uint16 UUID::GetData3() const { return Data3; } uint64 UUID::GetData4() const { return Data4; } bool UUID::IsNil() const { return (Data1 == 0) && (Data2 == 0) && (Data3 == 0) && (Data4 == 0); } bool UUID::IsValid() const { return (Data1 != 0) || (Data2 != 0) || (Data3 != 0) || (Data4 != 0); } uint8 UUID::Mm() const { return static_cast((Data3 >> 8) & 0xffu); } uint8 UUID::Nn() const { return static_cast((Data4 >> 56) & 0xffu); } uint8 UUID::Variant() const { return Nn() >> 4u; } uint8 UUID::Version() const { return Mm() >> 4u; } bool UUID::IsRFC4122() const { return (Variant() & 0xcu) == 0x8u; } void UUID::MakeRFC4122(uint8 version) { // variant uint8 Nn = static_cast((Data4 >> 56) & 0xffu); Data4 &= 0x00ffffffffffffffull; Nn &= ~(0xc0u); Nn |= 0x80u; Data4 |= static_cast(Nn) << 56; // version version &= 0x0fu; uint8 Mm = static_cast((Data3 >> 8) & 0xffu); Data3 &= 0x00ffu; Mm &= ~(0xf0u); Mm |= (version << 4u); Data3 |= static_cast(Mm) << 8; } UUID::UUID() { Data1 = 0; Data2 = 0; Data3 = 0; Data4 = 0; } UUID::UUID(uint32 Data1, uint16 Data2, uint16 Data3, uint64 Data4) { this->Data1 = Data1; this->Data2 = Data2; this->Data3 = Data3; this->Data4 = Data4; } bool operator==(const mpt::UUID & a, const mpt::UUID & b) { return (a.Data1 == b.Data1) && (a.Data2 == b.Data2) && (a.Data3 == b.Data3) && (a.Data4 == b.Data4); } bool operator!=(const mpt::UUID & a, const mpt::UUID & b) { return (a.Data1 != b.Data1) || (a.Data2 != b.Data2) || (a.Data3 != b.Data3) || (a.Data4 != b.Data4); } UUID UUID::FromString(const std::string &str) { std::vector segments = mpt::String::Split(str, std::string("-")); if(segments.size() != 5) { return UUID(); } if(segments[0].length() != 8) { return UUID(); } if(segments[1].length() != 4) { return UUID(); } if(segments[2].length() != 4) { return UUID(); } if(segments[3].length() != 4) { return UUID(); } if(segments[4].length() != 12) { return UUID(); } UUID result; result.Data1 = mpt::String::Parse::Hex(segments[0]); result.Data2 = mpt::String::Parse::Hex(segments[1]); result.Data3 = mpt::String::Parse::Hex(segments[2]); result.Data4 = mpt::String::Parse::Hex(segments[3] + segments[4]); return result; } UUID UUID::FromString(const mpt::ustring &str) { std::vector segments = mpt::String::Split(str, MPT_USTRING("-")); if(segments.size() != 5) { return UUID(); } if(segments[0].length() != 8) { return UUID(); } if(segments[1].length() != 4) { return UUID(); } if(segments[2].length() != 4) { return UUID(); } if(segments[3].length() != 4) { return UUID(); } if(segments[4].length() != 12) { return UUID(); } UUID result; result.Data1 = mpt::String::Parse::Hex(segments[0]); result.Data2 = mpt::String::Parse::Hex(segments[1]); result.Data3 = mpt::String::Parse::Hex(segments[2]); result.Data4 = mpt::String::Parse::Hex(segments[3] + segments[4]); return result; } std::string UUID::ToString() const { return std::string() + mpt::fmt::hex0<8>(GetData1()) + std::string("-") + mpt::fmt::hex0<4>(GetData2()) + std::string("-") + mpt::fmt::hex0<4>(GetData3()) + std::string("-") + mpt::fmt::hex0<4>(static_cast(GetData4() >> 48)) + std::string("-") + mpt::fmt::hex0<4>(static_cast(GetData4() >> 32)) + mpt::fmt::hex0<8>(static_cast(GetData4() >> 0)) ; } mpt::ustring UUID::ToUString() const { return mpt::ustring() + mpt::ufmt::hex0<8>(GetData1()) + MPT_USTRING("-") + mpt::ufmt::hex0<4>(GetData2()) + MPT_USTRING("-") + mpt::ufmt::hex0<4>(GetData3()) + MPT_USTRING("-") + mpt::ufmt::hex0<4>(static_cast(GetData4() >> 48)) + MPT_USTRING("-") + mpt::ufmt::hex0<4>(static_cast(GetData4() >> 32)) + mpt::ufmt::hex0<8>(static_cast(GetData4() >> 0)) ; } UUID::UUID(GUIDms guid) { Data1 = guid.Data1.get(); Data2 = guid.Data2.get(); Data3 = guid.Data3.get(); Data4 = guid.Data4.get(); } UUID::operator GUIDms() const { GUIDms result; result.Data1 = GetData1(); result.Data2 = GetData2(); result.Data3 = GetData3(); result.Data4 = GetData4(); return result; } } // namespace mpt OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/mptIO.h0000644000372100037210000005364213142633151016760 00000000000000/* * mptIO.h * ------- * Purpose: Basic functions for reading/writing binary and endian safe data to/from files/streams. * Notes : This is work-in-progress. * Some useful functions for reading and writing are still missing. * Authors: Joern Heusipp * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "../common/typedefs.h" #include "../common/mptTypeTraits.h" #include "../common/Endianness.h" #include #include #include #include #if defined(MPT_ENABLE_FILEIO_STDIO) #include #include #endif // MPT_ENABLE_FILEIO_STDIO OPENMPT_NAMESPACE_BEGIN namespace mpt { namespace IO { typedef int64 Offset; static const std::size_t BUFFERSIZE_TINY = 1 * 1024; // on stack usage static const std::size_t BUFFERSIZE_SMALL = 4 * 1024; // on heap static const std::size_t BUFFERSIZE_NORMAL = 64 * 1024; // FILE I/O static const std::size_t BUFFERSIZE_LARGE = 1024 * 1024; // Returns true iff 'off' fits into 'Toff'. template < typename Toff > inline bool OffsetFits(IO::Offset off) { return (static_cast(mpt::saturate_cast(off)) == off); } bool IsValid(std::ostream & f); bool IsValid(std::istream & f); bool IsValid(std::iostream & f); IO::Offset TellRead(std::istream & f); IO::Offset TellWrite(std::ostream & f); bool SeekBegin(std::ostream & f); bool SeekBegin(std::istream & f); bool SeekBegin(std::iostream & f); bool SeekEnd(std::ostream & f); bool SeekEnd(std::istream & f); bool SeekEnd(std::iostream & f); bool SeekAbsolute(std::ostream & f, IO::Offset pos); bool SeekAbsolute(std::istream & f, IO::Offset pos); bool SeekAbsolute(std::iostream & f, IO::Offset pos); bool SeekRelative(std::ostream & f, IO::Offset off); bool SeekRelative(std::istream & f, IO::Offset off); bool SeekRelative(std::iostream & f, IO::Offset off); IO::Offset ReadRawImpl(std::istream & f, mpt::byte * data, std::size_t size); bool WriteRawImpl(std::ostream & f, const mpt::byte * data, std::size_t size); bool IsEof(std::istream & f); bool Flush(std::ostream & f); #if defined(MPT_ENABLE_FILEIO_STDIO) bool IsValid(FILE* & f); IO::Offset TellRead(FILE* & f); IO::Offset TellWrite(FILE* & f); bool SeekBegin(FILE* & f); bool SeekEnd(FILE* & f); bool SeekAbsolute(FILE* & f, IO::Offset pos); bool SeekRelative(FILE* & f, IO::Offset off); IO::Offset ReadRawImpl(FILE * & f, mpt::byte * data, std::size_t size); bool WriteRawImpl(FILE* & f, const mpt::byte * data, std::size_t size); bool IsEof(FILE * & f); bool Flush(FILE* & f); #endif // MPT_ENABLE_FILEIO_STDIO template bool IsValid(std::pair, IO::Offset> & f) { return (f.second >= 0); } template IO::Offset TellRead(std::pair, IO::Offset> & f) { return f.second; } template IO::Offset TellWrite(std::pair, IO::Offset> & f) { return f.second; } template bool SeekBegin(std::pair, IO::Offset> & f) { f.second = 0; return true; } template bool SeekEnd(std::pair, IO::Offset> & f) { f.second = f.first.size(); return true; } template bool SeekAbsolute(std::pair, IO::Offset> & f, IO::Offset pos) { f.second = pos; return true; } template bool SeekRelative(std::pair, IO::Offset> & f, IO::Offset off) { if(f.second < 0) { return false; } f.second += off; return true; } template IO::Offset ReadRawImpl(std::pair, IO::Offset> & f, mpt::byte * data, std::size_t size) { if(f.second < 0) { return 0; } if(f.second >= static_cast(f.first.size())) { return 0; } std::size_t num = mpt::saturate_cast(std::min(f.first.size() - f.second, size)); std::copy(mpt::byte_cast(f.first.data() + f.second), mpt::byte_cast(f.first.data() + f.second + num), data); f.second += num; return num; } template bool WriteRawImpl(std::pair, IO::Offset> & f, const mpt::byte * data, std::size_t size) { if(f.second < 0) { return false; } if(f.second >= static_cast(f.first.size())) { return false; } std::size_t num = mpt::saturate_cast(std::min(f.first.size() - f.second, size)); if(num != size) { return false; } std::copy(data, data + num, mpt::byte_cast(f.first.data() + f.second)); f.second += num; return true; } template bool IsEof(std::pair, IO::Offset> & f) { return (f.second >= static_cast(f.first.size())); } template bool Flush(std::pair, IO::Offset> & f) { MPT_UNREFERENCED_PARAMTER(f); return true; } template inline IO::Offset ReadRaw(Tfile & f, Tbyte * data, std::size_t size) { return IO::ReadRawImpl(f, mpt::byte_cast(data), size); } template inline bool WriteRaw(Tfile & f, const Tbyte * data, std::size_t size) { return IO::WriteRawImpl(f, mpt::byte_cast(data), size); } template inline bool Read(Tfile & f, Tbinary & v) { return IO::ReadRaw(f, mpt::as_raw_memory(v), sizeof(Tbinary)) == sizeof(Tbinary); } template inline bool Write(Tfile & f, const Tbinary & v) { return IO::WriteRaw(f, mpt::as_raw_memory(v), sizeof(Tbinary)); } template inline bool WritePartial(Tfile & f, const T & v, size_t size = sizeof(T)) { MPT_ASSERT(size <= sizeof(T)); return IO::WriteRaw(f, mpt::as_raw_memory(v), size); } template inline bool ReadBinaryTruncatedLE(Tfile & f, T & v, std::size_t size) { bool result = false; MPT_STATIC_ASSERT(std::numeric_limits::is_integer); mpt::byte bytes[sizeof(T)]; std::memset(bytes, 0, sizeof(T)); const IO::Offset readResult = IO::ReadRaw(f, bytes, std::min(size, sizeof(T))); if(readResult < 0) { result = false; } else { result = (static_cast(readResult) == std::min(size, sizeof(T))); } #ifdef MPT_PLATFORM_BIG_ENDIAN std::reverse(bytes, bytes + sizeof(T)); #endif std::memcpy(&v, bytes, sizeof(T)); return result; } template inline bool ReadIntLE(Tfile & f, T & v) { bool result = false; STATIC_ASSERT(std::numeric_limits::is_integer); mpt::byte bytes[sizeof(T)]; std::memset(bytes, 0, sizeof(T)); const IO::Offset readResult = IO::ReadRaw(f, bytes, sizeof(T)); if(readResult < 0) { result = false; } else { result = (static_cast(readResult) == sizeof(T)); } T val = 0; std::memcpy(&val, bytes, sizeof(T)); v = SwapBytesLE(val); return result; } template inline bool ReadIntBE(Tfile & f, T & v) { bool result = false; STATIC_ASSERT(std::numeric_limits::is_integer); mpt::byte bytes[sizeof(T)]; std::memset(bytes, 0, sizeof(T)); const IO::Offset readResult = IO::ReadRaw(f, bytes, sizeof(T)); if(readResult < 0) { result = false; } else { result = (static_cast(readResult) == sizeof(T)); } T val = 0; std::memcpy(&val, bytes, sizeof(T)); v = SwapBytesBE(val); return result; } template inline bool ReadAdaptiveInt16LE(Tfile & f, uint16 & v) { bool result = true; mpt::byte byte = 0; std::size_t additionalBytes = 0; v = 0; byte = 0; if(!IO::ReadIntLE(f, byte)) result = false; additionalBytes = (byte & 0x01); v = byte >> 1; for(std::size_t i = 0; i < additionalBytes; ++i) { byte = 0; if(!IO::ReadIntLE(f, byte)) result = false; v |= (static_cast(byte) << (((i+1)*8) - 1)); } return result; } template inline bool ReadAdaptiveInt32LE(Tfile & f, uint32 & v) { bool result = true; mpt::byte byte = 0; std::size_t additionalBytes = 0; v = 0; byte = 0; if(!IO::ReadIntLE(f, byte)) result = false; additionalBytes = (byte & 0x03); v = byte >> 2; for(std::size_t i = 0; i < additionalBytes; ++i) { byte = 0; if(!IO::ReadIntLE(f, byte)) result = false; v |= (static_cast(byte) << (((i+1)*8) - 2)); } return result; } template inline bool ReadAdaptiveInt64LE(Tfile & f, uint64 & v) { bool result = true; mpt::byte byte = 0; std::size_t additionalBytes = 0; v = 0; byte = 0; if(!IO::ReadIntLE(f, byte)) result = false; additionalBytes = (1 << (byte & 0x03)) - 1; v = byte >> 2; for(std::size_t i = 0; i < additionalBytes; ++i) { byte = 0; if(!IO::ReadIntLE(f, byte)) result = false; v |= (static_cast(byte) << (((i+1)*8) - 2)); } return result; } template inline bool ReadSizedStringLE(Tfile & f, std::string & str, Tsize maxSize = std::numeric_limits::max()) { STATIC_ASSERT(std::numeric_limits::is_integer); str.clear(); Tsize size = 0; if(!mpt::IO::ReadIntLE(f, size)) { return false; } if(size > maxSize) { return false; } for(Tsize i = 0; i != size; ++i) { char c = '\0'; if(!mpt::IO::ReadIntLE(f, c)) { return false; } str.push_back(c); } return true; } template inline bool WriteIntLE(Tfile & f, const T v) { STATIC_ASSERT(std::numeric_limits::is_integer); const T val = SwapBytesLE(v); mpt::byte bytes[sizeof(T)]; std::memcpy(bytes, &val, sizeof(T)); return IO::WriteRaw(f, bytes, sizeof(T)); } template inline bool WriteIntBE(Tfile & f, const T v) { STATIC_ASSERT(std::numeric_limits::is_integer); const T val = SwapBytesBE(v); mpt::byte bytes[sizeof(T)]; std::memcpy(bytes, &val, sizeof(T)); return IO::WriteRaw(f, bytes, sizeof(T)); } template inline bool WriteAdaptiveInt16LE(Tfile & f, const uint16 v, std::size_t minSize = 0, std::size_t maxSize = 0) { MPT_ASSERT(minSize == 0 || minSize == 1 || minSize == 2); MPT_ASSERT(maxSize == 0 || maxSize == 1 || maxSize == 2); MPT_ASSERT(maxSize == 0 || maxSize >= minSize); if(v < 0x80 && minSize <= 1 && (1 <= maxSize || maxSize == 0)) { return IO::WriteIntLE(f, static_cast(v << 1) | 0x00); } else if(v < 0x8000 && minSize <= 2 && (2 <= maxSize || maxSize == 0)) { return IO::WriteIntLE(f, static_cast(v << 1) | 0x01); } else { MPT_ASSERT_NOTREACHED(); return false; } } template inline bool WriteAdaptiveInt32LE(Tfile & f, const uint32 v, std::size_t minSize = 0, std::size_t maxSize = 0) { MPT_ASSERT(minSize == 0 || minSize == 1 || minSize == 2 || minSize == 3 || minSize == 4); MPT_ASSERT(maxSize == 0 || maxSize == 1 || maxSize == 2 || maxSize == 3 || maxSize == 4); MPT_ASSERT(maxSize == 0 || maxSize >= minSize); if(v < 0x40 && minSize <= 1 && (1 <= maxSize || maxSize == 0)) { return IO::WriteIntLE(f, static_cast(v << 2) | 0x00); } else if(v < 0x4000 && minSize <= 2 && (2 <= maxSize || maxSize == 0)) { return IO::WriteIntLE(f, static_cast(v << 2) | 0x01); } else if(v < 0x400000 && minSize <= 3 && (3 <= maxSize || maxSize == 0)) { uint32 value = static_cast(v << 2) | 0x02; mpt::byte bytes[3]; bytes[0] = static_cast(value >> 0); bytes[1] = static_cast(value >> 8); bytes[2] = static_cast(value >> 16); return IO::WriteRaw(f, bytes, 3); } else if(v < 0x40000000 && minSize <= 4 && (4 <= maxSize || maxSize == 0)) { return IO::WriteIntLE(f, static_cast(v << 2) | 0x03); } else { MPT_ASSERT_NOTREACHED(); return false; } } template inline bool WriteAdaptiveInt64LE(Tfile & f, const uint64 v, std::size_t minSize = 0, std::size_t maxSize = 0) { MPT_ASSERT(minSize == 0 || minSize == 1 || minSize == 2 || minSize == 4 || minSize == 8); MPT_ASSERT(maxSize == 0 || maxSize == 1 || maxSize == 2 || maxSize == 4 || maxSize == 8); MPT_ASSERT(maxSize == 0 || maxSize >= minSize); if(v < 0x40 && minSize <= 1 && (1 <= maxSize || maxSize == 0)) { return IO::WriteIntLE(f, static_cast(v << 2) | 0x00); } else if(v < 0x4000 && minSize <= 2 && (2 <= maxSize || maxSize == 0)) { return IO::WriteIntLE(f, static_cast(v << 2) | 0x01); } else if(v < 0x40000000 && minSize <= 4 && (4 <= maxSize || maxSize == 0)) { return IO::WriteIntLE(f, static_cast(v << 2) | 0x02); } else if(v < 0x4000000000000000ull && minSize <= 8 && (8 <= maxSize || maxSize == 0)) { return IO::WriteIntLE(f, static_cast(v << 2) | 0x03); } else { MPT_ASSERT_NOTREACHED(); return false; } } // Write a variable-length integer, as found in MIDI files. The number of written bytes is placed in the bytesWritten parameter. template bool WriteVarInt(Tfile & f, const T v, size_t *bytesWritten = nullptr) { STATIC_ASSERT(std::numeric_limits::is_integer); STATIC_ASSERT(!std::numeric_limits::is_signed); mpt::byte out[(sizeof(T) * 8 + 6) / 7]; size_t numBytes = 0; for(uint32 n = (sizeof(T) * 8) / 7; n > 0; n--) { if(v >= (static_cast(1) << (n * 7u))) { out[numBytes++] = static_cast(((v >> (n * 7u)) & 0x7F) | 0x80); } } out[numBytes++] = static_cast(v & 0x7F); MPT_ASSERT(numBytes <= mpt::size(out)); if(bytesWritten != nullptr) *bytesWritten = numBytes; return mpt::IO::WriteRaw(f, out, numBytes); } template inline bool WriteSizedStringLE(Tfile & f, const std::string & str) { STATIC_ASSERT(std::numeric_limits::is_integer); if(str.size() > std::numeric_limits::max()) { return false; } Tsize size = static_cast(str.size()); if(!mpt::IO::WriteIntLE(f, size)) { return false; } if(!mpt::IO::WriteRaw(f, str.data(), str.size())) { return false; } return true; } template inline bool WriteText(Tfile &f, const std::string &s) { return mpt::IO::WriteRaw(f, s.data(), s.size()); } template inline bool WriteTextCRLF(Tfile &f) { return mpt::IO::WriteText(f, "\r\n"); } template inline bool WriteTextLF(Tfile &f) { return mpt::IO::WriteText(f, "\n"); } template inline bool WriteTextCRLF(Tfile &f, const std::string &s) { return mpt::IO::WriteText(f, s) && mpt::IO::WriteTextCRLF(f); } template inline bool WriteTextLF(Tfile &f, const std::string &s) { return mpt::IO::WriteText(f, s) && mpt::IO::WriteTextLF(f); } } // namespace IO } // namespace mpt #if defined(MPT_FILEREADER_STD_ISTREAM) class IFileDataContainer { public: typedef std::size_t off_t; protected: IFileDataContainer() { } public: virtual ~IFileDataContainer() { } public: virtual bool IsValid() const = 0; virtual bool HasFastGetLength() const = 0; virtual bool HasPinnedView() const = 0; virtual const mpt::byte *GetRawData() const = 0; virtual off_t GetLength() const = 0; virtual off_t Read(mpt::byte *dst, off_t pos, off_t count) const = 0; virtual bool CanRead(off_t pos, off_t length) const { off_t dataLength = GetLength(); if((pos == dataLength) && (length == 0)) { return true; } if(pos >= dataLength) { return false; } return length <= dataLength - pos; } virtual off_t GetReadableLength(off_t pos, off_t length) const { off_t dataLength = GetLength(); if(pos >= dataLength) { return 0; } return std::min(length, dataLength - pos); } }; class FileDataContainerDummy : public IFileDataContainer { public: FileDataContainerDummy() { } virtual ~FileDataContainerDummy() { } public: bool IsValid() const { return false; } bool HasFastGetLength() const { return true; } bool HasPinnedView() const { return true; } const mpt::byte *GetRawData() const { return nullptr; } off_t GetLength() const { return 0; } off_t Read(mpt::byte * /*dst*/, off_t /*pos*/, off_t /*count*/) const { return 0; } }; class FileDataContainerWindow : public IFileDataContainer { private: std::shared_ptr data; const off_t dataOffset; const off_t dataLength; public: FileDataContainerWindow(std::shared_ptr src, off_t off, off_t len) : data(src), dataOffset(off), dataLength(len) { } virtual ~FileDataContainerWindow() { } bool IsValid() const { return data->IsValid(); } bool HasFastGetLength() const { return data->HasFastGetLength(); } bool HasPinnedView() const { return data->HasPinnedView(); } const mpt::byte *GetRawData() const { return data->GetRawData() + dataOffset; } off_t GetLength() const { return dataLength; } off_t Read(mpt::byte *dst, off_t pos, off_t count) const { if(pos >= dataLength) { return 0; } return data->Read(dst, dataOffset + pos, std::min(count, dataLength - pos)); } bool CanRead(off_t pos, off_t length) const { if((pos == dataLength) && (length == 0)) { return true; } if(pos >= dataLength) { return false; } return (length <= dataLength - pos); } off_t GetReadableLength(off_t pos, off_t length) const { if(pos >= dataLength) { return 0; } return std::min(length, dataLength - pos); } }; class FileDataContainerSeekable : public IFileDataContainer { private: off_t streamLength; mutable bool cached; mutable std::vector cache; protected: FileDataContainerSeekable(off_t length); virtual ~FileDataContainerSeekable(); private: void CacheStream() const; public: bool IsValid() const; bool HasFastGetLength() const; bool HasPinnedView() const; const mpt::byte *GetRawData() const; off_t GetLength() const; off_t Read(mpt::byte *dst, off_t pos, off_t count) const; private: virtual off_t InternalRead(mpt::byte *dst, off_t pos, off_t count) const = 0; }; class FileDataContainerStdStreamSeekable : public FileDataContainerSeekable { private: std::istream *stream; public: FileDataContainerStdStreamSeekable(std::istream *s); virtual ~FileDataContainerStdStreamSeekable(); static bool IsSeekable(std::istream *stream); static off_t GetLength(std::istream *stream); private: off_t InternalRead(mpt::byte *dst, off_t pos, off_t count) const; }; class FileDataContainerUnseekable : public IFileDataContainer { private: mutable std::vector cache; mutable std::size_t cachesize; mutable bool streamFullyCached; protected: FileDataContainerUnseekable(); virtual ~FileDataContainerUnseekable(); private: static const std::size_t QUANTUM_SIZE = mpt::IO::BUFFERSIZE_SMALL; static const std::size_t BUFFER_SIZE = mpt::IO::BUFFERSIZE_NORMAL; void EnsureCacheBuffer(std::size_t requiredbuffersize) const; void CacheStream() const; void CacheStreamUpTo(off_t pos, off_t length) const; private: void ReadCached(mpt::byte *dst, off_t pos, off_t count) const; public: bool IsValid() const; bool HasFastGetLength() const; bool HasPinnedView() const; const mpt::byte *GetRawData() const; off_t GetLength() const; off_t Read(mpt::byte *dst, off_t pos, off_t count) const; bool CanRead(off_t pos, off_t length) const; off_t GetReadableLength(off_t pos, off_t length) const; private: virtual bool InternalEof() const = 0; virtual off_t InternalRead(mpt::byte *dst, off_t count) const = 0; }; class FileDataContainerStdStream : public FileDataContainerUnseekable { private: std::istream *stream; public: FileDataContainerStdStream(std::istream *s); virtual ~FileDataContainerStdStream(); private: bool InternalEof() const; off_t InternalRead(mpt::byte *dst, off_t count) const; }; #if defined(MPT_FILEREADER_CALLBACK_STREAM) struct CallbackStream { static const int SeekSet = 0; static const int SeekCur = 1; static const int SeekEnd = 2; void *stream; std::size_t (*read)( void * stream, void * dst, std::size_t bytes ); int (*seek)( void * stream, int64 offset, int whence ); int64 (*tell)( void * stream ); }; class FileDataContainerCallbackStreamSeekable : public FileDataContainerSeekable { private: CallbackStream stream; public: static bool IsSeekable(CallbackStream stream); static off_t GetLength(CallbackStream stream); FileDataContainerCallbackStreamSeekable(CallbackStream s); virtual ~FileDataContainerCallbackStreamSeekable(); private: off_t InternalRead(mpt::byte *dst, off_t pos, off_t count) const; }; class FileDataContainerCallbackStream : public FileDataContainerUnseekable { private: CallbackStream stream; mutable bool eof_reached; public: FileDataContainerCallbackStream(CallbackStream s); virtual ~FileDataContainerCallbackStream(); private: bool InternalEof() const; off_t InternalRead(mpt::byte *dst, off_t count) const; }; #endif // MPT_FILEREADER_CALLBACK_STREAM #endif class FileDataContainerMemory #if defined(MPT_FILEREADER_STD_ISTREAM) : public IFileDataContainer #endif { #if !defined(MPT_FILEREADER_STD_ISTREAM) public: typedef std::size_t off_t; #endif private: const mpt::byte *streamData; // Pointer to memory-mapped file off_t streamLength; // Size of memory-mapped file in bytes public: FileDataContainerMemory() : streamData(nullptr), streamLength(0) { } FileDataContainerMemory(mpt::const_byte_span data) : streamData(data.data()), streamLength(data.size()) { } #if defined(MPT_FILEREADER_STD_ISTREAM) virtual #endif ~FileDataContainerMemory() { } public: bool IsValid() const { return streamData != nullptr; } bool HasFastGetLength() const { return true; } bool HasPinnedView() const { return true; } const mpt::byte *GetRawData() const { return streamData; } off_t GetLength() const { return streamLength; } off_t Read(mpt::byte *dst, off_t pos, off_t count) const { if(pos >= streamLength) { return 0; } off_t avail = std::min(streamLength - pos, count); std::copy(streamData + pos, streamData + pos + avail, dst); return avail; } bool CanRead(off_t pos, off_t length) const { if((pos == streamLength) && (length == 0)) { return true; } if(pos >= streamLength) { return false; } return (length <= streamLength - pos); } off_t GetReadableLength(off_t pos, off_t length) const { if(pos >= streamLength) { return 0; } return std::min(length, streamLength - pos); } }; OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/common/mptString.h0000644000372100037210000005266513161656666017744 00000000000000/* * mptString.h * ---------- * Purpose: Small string-related utilities, number and message formatting. * Notes : Currently none. * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "mptTypeTraits.h" #include #include #include #include OPENMPT_NAMESPACE_BEGIN namespace mpt { namespace String { template struct Traits { static const char * GetDefaultWhitespace() { return " \n\r\t"; } }; template <> struct Traits { static const char * GetDefaultWhitespace() { return " \n\r\t"; } }; template <> struct Traits { static const wchar_t * GetDefaultWhitespace() { return L" \n\r\t"; } }; // Remove whitespace at start of string template inline Tstring LTrim(Tstring str, const Tstring &whitespace = Tstring(mpt::String::Traits::GetDefaultWhitespace())) { typename Tstring::size_type pos = str.find_first_not_of(whitespace); if(pos != Tstring::npos) { str.erase(str.begin(), str.begin() + pos); } else if(pos == Tstring::npos && str.length() > 0 && str.find_last_of(whitespace) == str.length() - 1) { return Tstring(); } return str; } // Remove whitespace at end of string template inline Tstring RTrim(Tstring str, const Tstring &whitespace = Tstring(mpt::String::Traits::GetDefaultWhitespace())) { typename Tstring::size_type pos = str.find_last_not_of(whitespace); if(pos != Tstring::npos) { str.erase(str.begin() + pos + 1, str.end()); } else if(pos == Tstring::npos && str.length() > 0 && str.find_first_of(whitespace) == 0) { return Tstring(); } return str; } // Remove whitespace at start and end of string template inline Tstring Trim(Tstring str, const Tstring &whitespace = Tstring(mpt::String::Traits::GetDefaultWhitespace())) { return RTrim(LTrim(str, whitespace), whitespace); } template inline Tstring Replace(Tstring str, const Tstring2 &oldStr_, const Tstring3 &newStr_) { std::size_t pos = 0; const Tstring oldStr = oldStr_; const Tstring newStr = newStr_; while((pos = str.find(oldStr, pos)) != Tstring::npos) { str.replace(pos, oldStr.length(), newStr); pos += newStr.length(); } return str; } } // namespace String static inline std::size_t strnlen(const char *str, std::size_t n) { #if MPT_COMPILER_MSVC return ::strnlen(str, n); #else if(n >= std::numeric_limits::max()) { return std::strlen(str); } for(std::size_t i = 0; i < n; ++i) { if(str[i] == '\0') { return i; } } return n; #endif } enum Charset { #if defined(MPT_ENABLE_CHARSET_LOCALE) CharsetLocale, // CP_ACP on windows, current C locale otherwise #endif CharsetUTF8, CharsetASCII, // strictly 7-bit ASCII CharsetISO8859_1, CharsetISO8859_15, CharsetCP437, CharsetCP437AMS, CharsetCP437AMS2, CharsetWindows1252, }; // Locale in tracker builds, UTF8 in non-locale-aware libopenmpt builds. #if defined(MPT_ENABLE_CHARSET_LOCALE) const Charset CharsetLocaleOrUTF8 = CharsetLocale; #else const Charset CharsetLocaleOrUTF8 = CharsetUTF8; #endif // Checks if the std::string represents an UTF8 string. // This is currently implemented as converting to std::wstring and back assuming UTF8 both ways, // and comparing the result to the original string. // Caveats: // - can give false negatives because of possible unicode normalization during conversion // - can give false positives if the 8bit encoding contains high-ascii only in valid utf8 groups // - slow because of double conversion bool IsUTF8(const std::string &str); #define MPT_CHAR_TYPE char #define MPT_CHAR(x) x #define MPT_LITERAL(x) x #define MPT_STRING(x) std::string( x ) #define MPT_WCHAR_TYPE wchar_t #define MPT_WCHAR(x) L ## x #define MPT_WLITERAL(x) L ## x #define MPT_WSTRING(x) std::wstring( L ## x ) #if MPT_ENABLE_U8STRING template struct charset_char_traits : std::char_traits { static mpt::Charset charset() { return charset_tag; } }; #define MPT_ENCODED_STRING_TYPE(charset) std::basic_string< char, mpt::charset_char_traits< charset > > typedef MPT_ENCODED_STRING_TYPE(mpt::CharsetUTF8) u8string; #define MPT_U8CHAR_TYPE char #define MPT_U8CHAR(x) x #define MPT_U8LITERAL(x) x #define MPT_U8STRING(x) mpt::u8string( x ) // mpt::u8string is a moderately type-safe string that is meant to contain // UTF-8 encoded char bytes. // // mpt::u8string is not implicitely convertible to/from std::string, but // it is convertible to/from C strings the same way as std::string is. // // The implementation of mpt::u8string is a compromise of compatibilty // with implementation-defined STL details, efficiency, source code size, // executable bloat, type-safety and simplicity. // // mpt::u8string is not meant to be used directly though. // mpt::u8string is meant as an alternative implementaion to std::wstring // for implementing the unicode string type mpt::ustring. #endif // MPT_ENABLE_U8STRING #if MPT_WSTRING_CONVERT // Convert to a wide character string. // The wide encoding is UTF-16 or UTF-32, based on sizeof(wchar_t). // If str does not contain any invalid characters, this conversion is lossless. // Invalid source bytes will be replaced by some replacement character or string. static inline std::wstring ToWide(const std::wstring &str) { return str; } static inline std::wstring ToWide(const wchar_t * str) { return (str ? std::wstring(str) : std::wstring()); } std::wstring ToWide(Charset from, const std::string &str); static inline std::wstring ToWide(Charset from, const char * str) { return ToWide(from, str ? std::string(str) : std::string()); } #endif // Convert to a string encoded in the 'to'-specified character set. // If str does not contain any invalid characters, // this conversion will be lossless iff, and only iff, // 'to' is UTF8. // Invalid source bytes or characters that are not representable in the // destination charset will be replaced by some replacement character or string. #if MPT_WSTRING_CONVERT std::string ToCharset(Charset to, const std::wstring &str); static inline std::string ToCharset(Charset to, const wchar_t * str) { return ToCharset(to, str ? std::wstring(str) : std::wstring()); } #endif std::string ToCharset(Charset to, Charset from, const std::string &str); static inline std::string ToCharset(Charset to, Charset from, const char * str) { return ToCharset(to, from, str ? std::string(str) : std::string()); } #if defined(_MFC_VER) #if !(MPT_WSTRING_CONVERT) #error "MFC depends on MPT_WSTRING_CONVERT)" #endif // Convert to a MFC CString. The CString encoding depends on UNICODE. // This should also be used when converting to TCHAR strings. // If UNICODE is defined, this is a completely lossless operation. static inline CString ToCString(const CString &str) { return str; } CString ToCString(const std::wstring &str); static inline CString ToCString(const wchar_t * str) { return ToCString(str ? std::wstring(str) : std::wstring()); } CString ToCString(Charset from, const std::string &str); static inline CString ToCString(Charset from, const char * str) { return ToCString(from, str ? std::string(str) : std::string()); } // Convert from a MFC CString. The CString encoding depends on UNICODE. // This should also be used when converting from TCHAR strings. // If UNICODE is defined, this is a completely lossless operation. std::wstring ToWide(const CString &str); std::string ToCharset(Charset to, const CString &str); #ifdef UNICODE MPT_DEPRECATED static inline CString ToCStringW(const CString &str) { return ToCString(str); } MPT_DEPRECATED static inline CString ToCStringW(const std::wstring &str) { return ToCString(str); } MPT_DEPRECATED static inline CString ToCStringW(Charset from, const std::string &str) { return ToCString(from, str); } MPT_DEPRECATED static inline CString ToCStringW(Charset from, const char * str) { return ToCString(from, str ? std::string(str) : std::string()); } #else // !UNICODE CStringW ToCStringW(const CString &str); CStringW ToCStringW(const std::wstring &str); CStringW ToCStringW(Charset from, const std::string &str); static inline CStringW ToCStringW(Charset from, const char * str) { return ToCStringW(from, str ? std::string(str) : std::string()); } CStringW ToCStringW(const CStringW &str); std::wstring ToWide(const CStringW &str); std::string ToCharset(Charset to, const CStringW &str); CString ToCString(const CStringW &str); #endif // UNICODE #endif // MFC // mpt::ustring // // mpt::ustring is a string type that can hold unicode strings. // It is implemented as a std::basic_string either based on wchar_t (i.e. the // same as std::wstring) or a custom-defined char_traits class that is derived // from std::char_traits. // The selection of the underlying implementation is done at compile-time. // MPT_UCHAR, MPT_ULITERAL and MPT_USTRING are macros that ease construction // of ustring char literals, ustring char array literals and ustring objects // from ustring char literals that work consistently in both modes. // Note that these are not supported for non-ASCII characters appearing in // the macro argument. // Also note that, as both UTF8 and UTF16 (it is less of an issue for UTF32) // are variable-length encodings and mpt::ustring is implemented as a // std::basic_string, all member functions that require individual character // access will not work consistently or even at all in a meaningful way. // This in particular affects operator[], at(), find() and substr(). // The code makes no effort in preventing these or generating warnings when // these are used on mpt::ustring objects. However, compiling in the // respectively other mpt::ustring mode will catch most of these anyway. #if MPT_USTRING_MODE_WIDE #if MPT_USTRING_MODE_UTF8 #error "MPT_USTRING_MODE_WIDE and MPT_USTRING_MODE_UTF8 are mutually exclusive." #endif typedef std::wstring ustring; #define MPT_UCHAR_TYPE wchar_t #define MPT_UCHAR(x) L ## x #define MPT_ULITERAL(x) L ## x #define MPT_USTRING(x) std::wstring( L ## x ) #endif // MPT_USTRING_MODE_WIDE #if MPT_USTRING_MODE_UTF8 #if MPT_USTRING_MODE_WIDE #error "MPT_USTRING_MODE_WIDE and MPT_USTRING_MODE_UTF8 are mutually exclusive." #endif typedef mpt::u8string ustring; #define MPT_UCHAR_TYPE char #define MPT_UCHAR(x) x #define MPT_ULITERAL(x) x #define MPT_USTRING(x) mpt::ustring( x ) #endif // MPT_USTRING_MODE_UTF8 #if MPT_USTRING_MODE_WIDE #if !(MPT_WSTRING_CONVERT) #error "MPT_USTRING_MODE_WIDE depends on MPT_WSTRING_CONVERT)" #endif static inline mpt::ustring ToUnicode(const std::wstring &str) { return str; } static inline mpt::ustring ToUnicode(const wchar_t * str) { return (str ? std::wstring(str) : std::wstring()); } static inline mpt::ustring ToUnicode(Charset from, const std::string &str) { return ToWide(from, str); } static inline mpt::ustring ToUnicode(Charset from, const char * str) { return ToUnicode(from, str ? std::string(str) : std::string()); } #if defined(_MFC_VER) static inline mpt::ustring ToUnicode(const CString &str) { return ToWide(str); } #ifndef UNICODE static inline mpt::ustring ToUnicode(const CStringW &str) { return ToWide(str); } #endif // !UNICODE #endif // MFC #else // !MPT_USTRING_MODE_WIDE static inline mpt::ustring ToUnicode(const mpt::ustring &str) { return str; } #if MPT_WSTRING_CONVERT mpt::ustring ToUnicode(const std::wstring &str); static inline mpt::ustring ToUnicode(const wchar_t * str) { return ToUnicode(str ? std::wstring(str) : std::wstring()); } #endif mpt::ustring ToUnicode(Charset from, const std::string &str); static inline mpt::ustring ToUnicode(Charset from, const char * str) { return ToUnicode(from, str ? std::string(str) : std::string()); } #if defined(_MFC_VER) mpt::ustring ToUnicode(const CString &str); #ifndef UNICODE mpt::ustring ToUnicode(const CStringW &str); #endif // !UNICODE #endif // MFC #endif // MPT_USTRING_MODE_WIDE #if MPT_USTRING_MODE_WIDE #if !(MPT_WSTRING_CONVERT) #error "MPT_USTRING_MODE_WIDE depends on MPT_WSTRING_CONVERT)" #endif // nothing, std::wstring overloads will catch all stuff #else // !MPT_USTRING_MODE_WIDE #if MPT_WSTRING_CONVERT std::wstring ToWide(const mpt::ustring &str); #endif std::string ToCharset(Charset to, const mpt::ustring &str); #if defined(_MFC_VER) CString ToCString(const mpt::ustring &str); #ifdef UNICODE MPT_DEPRECATED static inline CString ToCStringW(const mpt::ustring &str) { return ToCString(str); } #else // !UNICODE static inline CStringW ToCStringW(const mpt::ustring &str) { return ToCStringW(ToWide(str)); } #endif // UNICODE #endif // MFC #endif // MPT_USTRING_MODE_WIDE // The MPT_UTF8 allows specifying UTF8 char arrays. // The resulting type is mpt::ustring and the construction might require runtime translation, // i.e. it is NOT generally available at compile time. // Use explicit UTF8 encoding, // i.e. U+00FC (LATIN SMALL LETTER U WITH DIAERESIS) would be written as "\xC3\xBC". #define MPT_UTF8(x) mpt::ToUnicode(mpt::CharsetUTF8, x ) #ifdef MODPLUG_TRACKER #if MPT_OS_WINDOWS namespace String { namespace detail { template inline mpt::ustring StringFromBuffer(const char (&buf)[size]) { STATIC_ASSERT(size > 0); std::size_t len = std::find(buf, buf + size, '\0') - buf; // terminate at \0 return mpt::ToUnicode(charset, std::string(buf, buf + len)); } template inline mpt::ustring StringFromBuffer(const wchar_t (&buf)[size]) { STATIC_ASSERT(size > 0); std::size_t len = std::find(buf, buf + size, L'\0') - buf; // terminate at \0 return mpt::ToUnicode(std::wstring(buf, buf + len)); } template inline bool StringToBuffer(char (&buf)[size], const mpt::ustring &str) { STATIC_ASSERT(size > 0); MemsetZero(buf); std::string encoded = mpt::ToCharset(charset, str); std::copy(encoded.data(), encoded.data() + std::min(encoded.length(), size - 1), buf); buf[size - 1] = '\0'; return (encoded.length() <= size - 1); } template inline bool StringToBuffer(wchar_t (&buf)[size], const mpt::ustring &str) { STATIC_ASSERT(size > 0); MemsetZero(buf); std::wstring encoded = mpt::ToWide(str); std::copy(encoded.data(), encoded.data() + std::min(encoded.length(), size - 1), buf); buf[size - 1] = L'\0'; return (encoded.length() <= size - 1); } } } // namespace String::detail // mpt::FromTcharBuf // A lot of expecially older WinAPI functions return strings by filling in // fixed-width TCHAR arrays inside some struct. // mpt::FromTcharBuf converts these string to mpt::ustring regardless of whether // in ANSI or UNICODE build and properly handles potentially missing NULL // termination. template inline mpt::ustring FromTcharBuf(const Tchar (&buf)[size]) { return mpt::String::detail::StringFromBuffer(buf); } // mpt::FromTcharStr // Converts TCHAR strings to mpt::ustring in both ANSI and UNICODE builds. // Useful when going through CString is not appropriate. template mpt::ustring FromTcharStr(const Tchar *str); template <> inline mpt::ustring FromTcharStr(const char *str) { if(!str) { return mpt::ustring(); } return mpt::ToUnicode(mpt::CharsetLocale, std::string(str)); } template <> inline mpt::ustring FromTcharStr(const wchar_t *str) { if(!str) { return mpt::ustring(); } return mpt::ToUnicode(std::wstring(str)); } // mpt::ToTcharBuf // The inverse of mpt::FromTcharBuf. // Always NULL-terminates the buffer. // Return false if the string has been truncated to fit. template inline bool ToTcharBuf(Tchar (&buf)[size], const mpt::ustring &str) { return mpt::String::detail::StringToBuffer(buf, str); } // mpt::ToTcharStr // Converts mpt::ustring to std::basic_stringy, // which is usable in both ANSI and UNICODE builds. // Useful when going through CString is not appropriate. template std::basic_string ToTcharStrImpl(const mpt::ustring &str); template <> inline std::string ToTcharStrImpl(const mpt::ustring &str) { return mpt::ToCharset(mpt::CharsetLocale, str); } template <> inline std::wstring ToTcharStrImpl(const mpt::ustring &str) { return mpt::ToWide(str); } inline std::basic_string ToTcharStr(const mpt::ustring &str) { return ToTcharStrImpl(str); } #if defined(_MFC_VER) template inline CString CStringFromBuffer(const TCHAR (&buf)[size]) { MPT_STATIC_ASSERT(size > 0); std::size_t len = std::find(buf, buf + size, _T('\0')) - buf; // terminate at \0 return CString(buf, len); } template inline void CopyCStringToBuffer(TCHAR (&buf)[size], const CString &str) { MPT_STATIC_ASSERT(size > 0); MemsetZero(buf); std::copy(str.GetString(), str.GetString() + std::min(static_cast(str.GetLength()), size - 1), buf); buf[size - 1] = _T('\0'); } #endif // _MFC_VER #endif // MPT_OS_WINDOWS #endif // MODPLUG_TRACKER char ToLowerCaseAscii(char c); char ToUpperCaseAscii(char c); std::string ToLowerCaseAscii(std::string s); std::string ToUpperCaseAscii(std::string s); int CompareNoCaseAscii(const char *a, const char *b, std::size_t n); int CompareNoCaseAscii(const std::string &a, const std::string &b); #if defined(MODPLUG_TRACKER) mpt::ustring ToLowerCase(const mpt::ustring &s); mpt::ustring ToUpperCase(const mpt::ustring &s); #endif // MODPLUG_TRACKER } // namespace mpt // The AnyString types are meant to be used as function argument types only, // and only during the transition phase to all-unicode strings in the whole codebase. // Using an AnyString type as function argument avoids the need to overload a function for all the // different string types that we currently have. // Warning: These types will silently do charset conversions. Only use them when this can be tolerated. // BasicAnyString is convertable to mpt::ustring and constructable from any string at all. template class BasicAnyString : public mpt::ustring { private: static mpt::ustring From8bit(const std::string &str) { if(charset == mpt::CharsetUTF8) { return mpt::ToUnicode(mpt::CharsetUTF8, str); } // auto utf8 detection if(tryUTF8 && mpt::IsUTF8(str)) { return mpt::ToUnicode(mpt::CharsetUTF8, str); } else { return mpt::ToUnicode(charset, str); } } public: // 8 bit BasicAnyString(const char *str) : mpt::ustring(str ? mpt::ToUnicode(charset, str) : mpt::ustring()) { } BasicAnyString(const std::string str) : mpt::ustring(mpt::ToUnicode(charset, str)) { } // unicode BasicAnyString(const mpt::ustring &str) : mpt::ustring(str) { } BasicAnyString(mpt::ustring &&str) : mpt::ustring(std::move(str)) { } #if MPT_USTRING_MODE_UTF8 && MPT_WSTRING_CONVERT BasicAnyString(const std::wstring &str) : mpt::ustring(mpt::ToUnicode(str)) { } #endif #if MPT_WSTRING_CONVERT BasicAnyString(const wchar_t *str) : mpt::ustring(str ? mpt::ToUnicode(str) : mpt::ustring()) { } #endif // mfc #if defined(_MFC_VER) BasicAnyString(const CString &str) : mpt::ustring(mpt::ToUnicode(str)) { } #ifndef UNICODE BasicAnyString(const CStringW &str) : mpt::ustring(mpt::ToUnicode(str)) { } #endif #endif // fallback for custom string types template BasicAnyString(const Tstring &str) : mpt::ustring(mpt::ToUnicode(str)) { } template BasicAnyString(Tstring &&str) : mpt::ustring(mpt::ToUnicode(std::forward(str))) { } }; // AnyUnicodeString is convertable to mpt::ustring and constructable from any unicode string, class AnyUnicodeString : public mpt::ustring { public: // unicode AnyUnicodeString(const mpt::ustring &str) : mpt::ustring(str) { } AnyUnicodeString(mpt::ustring &&str) : mpt::ustring(std::move(str)) { } #if MPT_USTRING_MODE_UTF8 && MPT_WSTRING_CONVERT AnyUnicodeString(const std::wstring &str) : mpt::ustring(mpt::ToUnicode(str)) { } #endif #if MPT_WSTRING_CONVERT AnyUnicodeString(const wchar_t *str) : mpt::ustring(str ? mpt::ToUnicode(str) : mpt::ustring()) { } #endif // mfc #if defined(_MFC_VER) AnyUnicodeString(const CString &str) : mpt::ustring(mpt::ToUnicode(str)) { } #ifndef UNICODE AnyUnicodeString(const CStringW &str) : mpt::ustring(mpt::ToUnicode(str)) { } #endif #endif // fallback for custom string types template AnyUnicodeString(const Tstring &str) : mpt::ustring(mpt::ToUnicode(str)) { } template AnyUnicodeString(Tstring &&str) : mpt::ustring(mpt::ToUnicode(std::forward(str))) { } }; // AnyString // Try to do the smartest auto-magic we can do. #if defined(MPT_ENABLE_CHARSET_LOCALE) typedef BasicAnyString AnyString; #elif MPT_OS_WINDOWS typedef BasicAnyString AnyString; #else typedef BasicAnyString AnyString; #endif // AnyStringLocale // char-based strings are assumed to be in locale encoding. #if defined(MPT_ENABLE_CHARSET_LOCALE) typedef BasicAnyString AnyStringLocale; #else typedef BasicAnyString AnyStringLocale; #endif // AnyStringUTF8orLocale // char-based strings are tried in UTF8 first, if this fails, locale is used. #if defined(MPT_ENABLE_CHARSET_LOCALE) typedef BasicAnyString AnyStringUTF8orLocale; #else typedef BasicAnyString AnyStringUTF8orLocale; #endif // AnyStringUTF8 // char-based strings are assumed to be in UTF8. typedef BasicAnyString AnyStringUTF8; OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/aclocal.m40000644000372100037210000012704513235362215016131 00000000000000# generated automatically by aclocal 1.15 -*- Autoconf -*- # Copyright (C) 1996-2014 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, [m4_warning([this file was generated for autoconf 2.69. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) # Copyright (C) 2002-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.15' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.15], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.15])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # Copyright (C) 2011-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_AR([ACT-IF-FAIL]) # ------------------------- # Try to determine the archiver interface, and trigger the ar-lib wrapper # if it is needed. If the detection of archiver interface fails, run # ACT-IF-FAIL (default is to abort configure with a proper error message). AC_DEFUN([AM_PROG_AR], [AC_BEFORE([$0], [LT_INIT])dnl AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([ar-lib])dnl AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false]) : ${AR=ar} AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface], [AC_LANG_PUSH([C]) am_cv_ar_interface=ar AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])], [am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([am_ar_try]) if test "$ac_status" -eq 0; then am_cv_ar_interface=ar else am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([am_ar_try]) if test "$ac_status" -eq 0; then am_cv_ar_interface=lib else am_cv_ar_interface=unknown fi fi rm -f conftest.lib libconftest.a ]) AC_LANG_POP([C])]) case $am_cv_ar_interface in ar) ;; lib) # Microsoft lib, so override with the ar-lib wrapper script. # FIXME: It is wrong to rewrite AR. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__AR in this case, # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something # similar. AR="$am_aux_dir/ar-lib $AR" ;; unknown) m4_default([$1], [AC_MSG_ERROR([could not determine $AR interface])]) ;; esac AC_SUBST([AR])dnl ]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to # '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ([2.52])dnl m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], [$1], [CXX], [depcc="$CXX" am_compiler_list=], [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], [$1], [UPC], [depcc="$UPC" am_compiler_list=], [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES. AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE([dependency-tracking], [dnl AS_HELP_STRING( [--enable-dependency-tracking], [do not reject slow dependency extractors]) AS_HELP_STRING( [--disable-dependency-tracking], [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl AC_SUBST([am__nodep])dnl _AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each '.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC]) [_AM_PROG_CC_C_O ]) # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.65])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], [$0: two- and three-arguments forms are deprecated.]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) AM_MISSING_PROG([AUTOCONF], [autoconf]) AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) AM_MISSING_PROG([AUTOHEADER], [autoheader]) AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) AC_REQUIRE([AM_SILENT_RULES])dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) fi fi dnl The trailing newline in this macro's definition is deliberate, for dnl backward compatibility and to allow trailing 'dnl'-style comments dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. ]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST([install_sh])]) # Copyright (C) 2003-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it is modern enough. # If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) fi ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_CC_C_O # --------------- # Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC # to automatically call this. AC_DEFUN([_AM_PROG_CC_C_O], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([compile])dnl AC_LANG_PUSH([C])dnl AC_CACHE_CHECK( [whether $CC understands -c and -o together], [am_cv_prog_cc_c_o], [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i]) if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_RUN_LOG(COMMAND) # ------------------- # Run COMMAND, save the exit status in ac_status, and log it. # (This has been adapted from Autoconf's _AC_RUN_LOG macro.) AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD (exit $ac_status); }]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi if test "$[2]" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT([yes]) # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi AC_CONFIG_COMMANDS_PRE( [AC_MSG_CHECKING([that generated files are newer than configure]) if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi AC_MSG_RESULT([done])]) rm -f conftest.file ]) # Copyright (C) 2009-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT # ("yes" being less verbose, "no" or empty being verbose). AC_DEFUN([AM_SILENT_RULES], [AC_ARG_ENABLE([silent-rules], [dnl AS_HELP_STRING( [--enable-silent-rules], [less verbose build output (undo: "make V=1")]) AS_HELP_STRING( [--disable-silent-rules], [verbose build output (undo: "make V=0")])dnl ]) case $enable_silent_rules in @%:@ ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} AC_CACHE_CHECK([whether $am_make supports nested variables], [am_cv_make_support_nested_variables], [if AS_ECHO([['TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then dnl Using '$V' instead of '$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar # AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar], [# The POSIX 1988 'ustar' format is defined with fixed-size fields. # There is notably a 21 bits limit for the UID and the GID. In fact, # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 # and bug#13588). am_max_uid=2097151 # 2^21 - 1 am_max_gid=$am_max_uid # The $UID and $GID variables are not portable, so we need to resort # to the POSIX-mandated id(1) utility. Errors in the 'id' calls # below are definitely unexpected, so allow the users to see them # (that is, avoid stderr redirection). am_uid=`id -u || echo unknown` am_gid=`id -g || echo unknown` AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) if test $am_uid -le $am_max_uid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) if test $am_gid -le $am_max_gid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi], [pax], [], [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Go ahead even if we have the value already cached. We do so because we # need to set the values for the 'am__tar' and 'am__untar' variables. _am_tools=${am_cv_prog_tar_$1-$_am_tools} for _am_tool in $_am_tools; do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works. rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([m4/ax_append_flag.m4]) m4_include([m4/ax_cflags_warn_all.m4]) m4_include([m4/ax_check_compile_flag.m4]) m4_include([m4/ax_cxx_compile_stdcxx.m4]) m4_include([m4/ax_cxx_compile_stdcxx_11.m4]) m4_include([m4/ax_prog_doxygen.m4]) m4_include([m4/ax_require_defined.m4]) m4_include([m4/libtool.m4]) m4_include([m4/ltoptions.m4]) m4_include([m4/ltsugar.m4]) m4_include([m4/ltversion.m4]) m4_include([m4/lt~obsolete.m4]) m4_include([m4/pkg.m4]) libopenmpt-0.3.6+release.autotools/libmodplug/0000755000372100037210000000000013235362225016477 500000000000000libopenmpt-0.3.6+release.autotools/libmodplug/libmodplug.pc.in0000644000372100037210000000045013056067317021512 00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=${prefix}/include Name: libmodplug Description: The ModPlug mod file playing library (emulated via libopenmpt). Version: 0.8.8.5 Requires.private: libopenmpt Libs: -L${libdir} -lmodplug Libs.private: Cflags: -I${includedir} libopenmpt-0.3.6+release.autotools/libmodplug/modplug.h0000644000372100037210000001522412153146113020235 00000000000000/* * This source code is public domain. * * Authors: Kenton Varda (C interface wrapper) */ #ifndef MODPLUG_H__INCLUDED #define MODPLUG_H__INCLUDED #ifdef __cplusplus extern "C" { #endif struct _ModPlugFile; typedef struct _ModPlugFile ModPlugFile; struct _ModPlugNote { unsigned char Note; unsigned char Instrument; unsigned char VolumeEffect; unsigned char Effect; unsigned char Volume; unsigned char Parameter; }; typedef struct _ModPlugNote ModPlugNote; typedef void (*ModPlugMixerProc)(int*, unsigned long, unsigned long); /* Load a mod file. [data] should point to a block of memory containing the complete * file, and [size] should be the size of that block. * Return the loaded mod file on success, or NULL on failure. */ ModPlugFile* ModPlug_Load(const void* data, int size); /* Unload a mod file. */ void ModPlug_Unload(ModPlugFile* file); /* Read sample data into the buffer. Returns the number of bytes read. If the end * of the mod has been reached, zero is returned. */ int ModPlug_Read(ModPlugFile* file, void* buffer, int size); /* Get the name of the mod. The returned buffer is stored within the ModPlugFile * structure and will remain valid until you unload the file. */ const char* ModPlug_GetName(ModPlugFile* file); /* Get the length of the mod, in milliseconds. Note that this result is not always * accurate, especially in the case of mods with loops. */ int ModPlug_GetLength(ModPlugFile* file); /* Seek to a particular position in the song. Note that seeking and MODs don't mix very * well. Some mods will be missing instruments for a short time after a seek, as ModPlug * does not scan the sequence backwards to find out which instruments were supposed to be * playing at that time. (Doing so would be difficult and not very reliable.) Also, * note that seeking is not very exact in some mods -- especially those for which * ModPlug_GetLength() does not report the full length. */ void ModPlug_Seek(ModPlugFile* file, int millisecond); enum _ModPlug_Flags { MODPLUG_ENABLE_OVERSAMPLING = 1 << 0, /* Enable oversampling (*highly* recommended) */ MODPLUG_ENABLE_NOISE_REDUCTION = 1 << 1, /* Enable noise reduction */ MODPLUG_ENABLE_REVERB = 1 << 2, /* Enable reverb */ MODPLUG_ENABLE_MEGABASS = 1 << 3, /* Enable megabass */ MODPLUG_ENABLE_SURROUND = 1 << 4 /* Enable surround sound. */ }; enum _ModPlug_ResamplingMode { MODPLUG_RESAMPLE_NEAREST = 0, /* No interpolation (very fast, extremely bad sound quality) */ MODPLUG_RESAMPLE_LINEAR = 1, /* Linear interpolation (fast, good quality) */ MODPLUG_RESAMPLE_SPLINE = 2, /* Cubic spline interpolation (high quality) */ MODPLUG_RESAMPLE_FIR = 3 /* 8-tap fir filter (extremely high quality) */ }; typedef struct _ModPlug_Settings { int mFlags; /* One or more of the MODPLUG_ENABLE_* flags above, bitwise-OR'ed */ /* Note that ModPlug always decodes sound at 44100kHz, 32 bit, stereo and then * down-mixes to the settings you choose. */ int mChannels; /* Number of channels - 1 for mono or 2 for stereo */ int mBits; /* Bits per sample - 8, 16, or 32 */ int mFrequency; /* Sampling rate - 11025, 22050, or 44100 */ int mResamplingMode; /* One of MODPLUG_RESAMPLE_*, above */ int mStereoSeparation; /* Stereo separation, 1 - 256 */ int mMaxMixChannels; /* Maximum number of mixing channels (polyphony), 32 - 256 */ int mReverbDepth; /* Reverb level 0(quiet)-100(loud) */ int mReverbDelay; /* Reverb delay in ms, usually 40-200ms */ int mBassAmount; /* XBass level 0(quiet)-100(loud) */ int mBassRange; /* XBass cutoff in Hz 10-100 */ int mSurroundDepth; /* Surround level 0(quiet)-100(heavy) */ int mSurroundDelay; /* Surround delay in ms, usually 5-40ms */ int mLoopCount; /* Number of times to loop. Zero prevents looping. -1 loops forever. */ } ModPlug_Settings; /* Get and set the mod decoder settings. All options, except for channels, bits-per-sample, * sampling rate, and loop count, will take effect immediately. Those options which don't * take effect immediately will take effect the next time you load a mod. */ void ModPlug_GetSettings(ModPlug_Settings* settings); void ModPlug_SetSettings(const ModPlug_Settings* settings); /* New ModPlug API Functions */ /* NOTE: Master Volume (1-512) */ unsigned int ModPlug_GetMasterVolume(ModPlugFile* file) ; void ModPlug_SetMasterVolume(ModPlugFile* file,unsigned int cvol) ; int ModPlug_GetCurrentSpeed(ModPlugFile* file); int ModPlug_GetCurrentTempo(ModPlugFile* file); int ModPlug_GetCurrentOrder(ModPlugFile* file); int ModPlug_GetCurrentPattern(ModPlugFile* file); int ModPlug_GetCurrentRow(ModPlugFile* file); int ModPlug_GetPlayingChannels(ModPlugFile* file); void ModPlug_SeekOrder(ModPlugFile* file,int order); int ModPlug_GetModuleType(ModPlugFile* file); char* ModPlug_GetMessage(ModPlugFile* file); #ifndef MODPLUG_NO_FILESAVE /* * EXPERIMENTAL Export Functions */ /*Export to a Scream Tracker 3 S3M module. EXPERIMENTAL (only works on Little-Endian platforms)*/ char ModPlug_ExportS3M(ModPlugFile* file, const char* filepath); /*Export to a Extended Module (XM). EXPERIMENTAL (only works on Little-Endian platforms)*/ char ModPlug_ExportXM(ModPlugFile* file, const char* filepath); /*Export to a Amiga MOD file. EXPERIMENTAL.*/ char ModPlug_ExportMOD(ModPlugFile* file, const char* filepath); /*Export to a Impulse Tracker IT file. Should work OK in Little-Endian & Big-Endian platforms :-) */ char ModPlug_ExportIT(ModPlugFile* file, const char* filepath); #endif // MODPLUG_NO_FILESAVE unsigned int ModPlug_NumInstruments(ModPlugFile* file); unsigned int ModPlug_NumSamples(ModPlugFile* file); unsigned int ModPlug_NumPatterns(ModPlugFile* file); unsigned int ModPlug_NumChannels(ModPlugFile* file); unsigned int ModPlug_SampleName(ModPlugFile* file, unsigned int qual, char* buff); unsigned int ModPlug_InstrumentName(ModPlugFile* file, unsigned int qual, char* buff); /* * Retrieve pattern note-data */ ModPlugNote* ModPlug_GetPattern(ModPlugFile* file, int pattern, unsigned int* numrows); /* * ================= * Mixer callback * ================= * * Use this callback if you want to 'modify' the mixed data of LibModPlug. * * void proc(int* buffer,unsigned long channels,unsigned long nsamples) ; * * 'buffer': A buffer of mixed samples * 'channels': N. of channels in the buffer * 'nsamples': N. of samples in the buffeer (without taking care of n.channels) * * (Samples are signed 32-bit integers) */ void ModPlug_InitMixerCallback(ModPlugFile* file,ModPlugMixerProc proc) ; void ModPlug_UnloadMixerCallback(ModPlugFile* file) ; #ifdef __cplusplus } /* extern "C" */ #endif #endif libopenmpt-0.3.6+release.autotools/libmodplug/stdafx.h0000644000372100037210000000456212251446160020066 00000000000000/* * This source code is public domain. * * Authors: Rani Assaf , * Olivier Lapicque , * Adam Goode (endian and char fixes for PPC) */ #ifndef _STDAFX_H_ #define _STDAFX_H_ /* Autoconf detection of stdint/inttypes */ #if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) # include "config.h" # define CONFIG_H_INCLUDED 1 #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef _WIN32 #ifdef MSC_VER #pragma warning (disable:4201) #pragma warning (disable:4514) #endif #define WIN32_LEAN_AND_MEAN #include #include #include #include #include #include #define srandom(_seed) srand(_seed) #define random() rand() #define sleep(_ms) Sleep(_ms) inline void ProcessPlugins(int n) {} #define strncasecmp(a,b,c) strncmp(a,b,c) #define strcasecmp(a,b) strcmp(a,b) #define strnicmp(a,b,c) strncasecmp(a,b,c) #define HAVE_SINF 1 #else #include #include #include #ifdef HAVE_MALLOC_H #include #endif typedef int8_t CHAR; typedef uint8_t UCHAR; typedef uint8_t* PUCHAR; typedef uint16_t USHORT; typedef uint32_t ULONG; typedef uint32_t UINT; typedef uint32_t DWORD; typedef int32_t LONG; typedef int64_t LONGLONG; typedef int32_t* LPLONG; typedef uint32_t* LPDWORD; typedef uint16_t WORD; typedef uint8_t BYTE; typedef uint8_t* LPBYTE; typedef bool BOOL; typedef char* LPSTR; typedef void* LPVOID; typedef uint16_t* LPWORD; typedef const char* LPCSTR; typedef void* PVOID; typedef void VOID; inline LONG MulDiv (long a, long b, long c) { // if (!c) return 0; return ((uint64_t) a * (uint64_t) b ) / c; } #define MODPLUG_NO_FILESAVE #define NO_AGC #define LPCTSTR LPCSTR #define lstrcpyn strncpy #define lstrcpy strcpy #define lstrcmp strcmp #define WAVE_FORMAT_PCM 1 //#define ENABLE_EQ #define GHND 0 inline int8_t * GlobalAllocPtr(unsigned int, size_t size) { int8_t * p = (int8_t *) malloc(size); if (p != NULL) memset(p, 0, size); return p; } inline void ProcessPlugins(int /* n */ ) {} #define GlobalFreePtr(p) free((void *)(p)) #define strnicmp(a,b,c) strncasecmp(a,b,c) #define wsprintf sprintf #ifndef FALSE #define FALSE false #endif #ifndef TRUE #define TRUE true #endif #endif // _WIN32 #endif libopenmpt-0.3.6+release.autotools/libmodplug/sndfile.h0000644000372100037210000007562112153146113020221 00000000000000/* * This source code is public domain. * * Authors: Olivier Lapicque , * Adam Goode (endian and char fixes for PPC) */ #if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) #include "config.h" #define CONFIG_H_INCLUDED 1 #endif #ifndef __SNDFILE_H #define __SNDFILE_H #ifdef UNDER_CE int _strnicmp(const char *str1,const char *str2, int n); #endif #ifndef LPCBYTE typedef const BYTE * LPCBYTE; #endif #define MOD_AMIGAC2 0x1AB #define MAX_SAMPLE_LENGTH 16000000 #define MAX_SAMPLE_RATE 192000 #define MAX_ORDERS 256 #define MAX_PATTERNS 240 #define MAX_SAMPLES 240 #define MAX_INSTRUMENTS MAX_SAMPLES #ifdef MODPLUG_FASTSOUNDLIB #define MAX_CHANNELS 80 #else #define MAX_CHANNELS 128 #endif #define MAX_BASECHANNELS 64 #define MAX_ENVPOINTS 32 #define MIN_PERIOD 0x0020 #define MAX_PERIOD 0xFFFF #define MAX_PATTERNNAME 32 #define MAX_CHANNELNAME 20 #define MAX_INFONAME 80 #define MAX_EQ_BANDS 6 #define MAX_MIXPLUGINS 8 #define MOD_TYPE_NONE 0x00 #define MOD_TYPE_MOD 0x01 #define MOD_TYPE_S3M 0x02 #define MOD_TYPE_XM 0x04 #define MOD_TYPE_MED 0x08 #define MOD_TYPE_MTM 0x10 #define MOD_TYPE_IT 0x20 #define MOD_TYPE_669 0x40 #define MOD_TYPE_ULT 0x80 #define MOD_TYPE_STM 0x100 #define MOD_TYPE_FAR 0x200 #define MOD_TYPE_WAV 0x400 #define MOD_TYPE_AMF 0x800 #define MOD_TYPE_AMS 0x1000 #define MOD_TYPE_DSM 0x2000 #define MOD_TYPE_MDL 0x4000 #define MOD_TYPE_OKT 0x8000 #define MOD_TYPE_MID 0x10000 #define MOD_TYPE_DMF 0x20000 #define MOD_TYPE_PTM 0x40000 #define MOD_TYPE_DBM 0x80000 #define MOD_TYPE_MT2 0x100000 #define MOD_TYPE_AMF0 0x200000 #define MOD_TYPE_PSM 0x400000 #define MOD_TYPE_J2B 0x800000 #define MOD_TYPE_ABC 0x1000000 #define MOD_TYPE_PAT 0x2000000 #define MOD_TYPE_UMX 0x80000000 // Fake type #define MAX_MODTYPE 24 // Channel flags: // Bits 0-7: Sample Flags #define CHN_16BIT 0x01 #define CHN_LOOP 0x02 #define CHN_PINGPONGLOOP 0x04 #define CHN_SUSTAINLOOP 0x08 #define CHN_PINGPONGSUSTAIN 0x10 #define CHN_PANNING 0x20 #define CHN_STEREO 0x40 #define CHN_PINGPONGFLAG 0x80 // Bits 8-31: Channel Flags #define CHN_MUTE 0x100 #define CHN_KEYOFF 0x200 #define CHN_NOTEFADE 0x400 #define CHN_SURROUND 0x800 #define CHN_NOIDO 0x1000 #define CHN_HQSRC 0x2000 #define CHN_FILTER 0x4000 #define CHN_VOLUMERAMP 0x8000 #define CHN_VIBRATO 0x10000 #define CHN_TREMOLO 0x20000 #define CHN_PANBRELLO 0x40000 #define CHN_PORTAMENTO 0x80000 #define CHN_GLISSANDO 0x100000 #define CHN_VOLENV 0x200000 #define CHN_PANENV 0x400000 #define CHN_PITCHENV 0x800000 #define CHN_FASTVOLRAMP 0x1000000 #define CHN_EXTRALOUD 0x2000000 #define CHN_REVERB 0x4000000 #define CHN_NOREVERB 0x8000000 #define ENV_VOLUME 0x0001 #define ENV_VOLSUSTAIN 0x0002 #define ENV_VOLLOOP 0x0004 #define ENV_PANNING 0x0008 #define ENV_PANSUSTAIN 0x0010 #define ENV_PANLOOP 0x0020 #define ENV_PITCH 0x0040 #define ENV_PITCHSUSTAIN 0x0080 #define ENV_PITCHLOOP 0x0100 #define ENV_SETPANNING 0x0200 #define ENV_FILTER 0x0400 #define ENV_VOLCARRY 0x0800 #define ENV_PANCARRY 0x1000 #define ENV_PITCHCARRY 0x2000 #define CMD_NONE 0 #define CMD_ARPEGGIO 1 #define CMD_PORTAMENTOUP 2 #define CMD_PORTAMENTODOWN 3 #define CMD_TONEPORTAMENTO 4 #define CMD_VIBRATO 5 #define CMD_TONEPORTAVOL 6 #define CMD_VIBRATOVOL 7 #define CMD_TREMOLO 8 #define CMD_PANNING8 9 #define CMD_OFFSET 10 #define CMD_VOLUMESLIDE 11 #define CMD_POSITIONJUMP 12 #define CMD_VOLUME 13 #define CMD_PATTERNBREAK 14 #define CMD_RETRIG 15 #define CMD_SPEED 16 #define CMD_TEMPO 17 #define CMD_TREMOR 18 #define CMD_MODCMDEX 19 #define CMD_S3MCMDEX 20 #define CMD_CHANNELVOLUME 21 #define CMD_CHANNELVOLSLIDE 22 #define CMD_GLOBALVOLUME 23 #define CMD_GLOBALVOLSLIDE 24 #define CMD_KEYOFF 25 #define CMD_FINEVIBRATO 26 #define CMD_PANBRELLO 27 #define CMD_XFINEPORTAUPDOWN 28 #define CMD_PANNINGSLIDE 29 #define CMD_SETENVPOSITION 30 #define CMD_MIDI 31 // Volume Column commands #define VOLCMD_VOLUME 1 #define VOLCMD_PANNING 2 #define VOLCMD_VOLSLIDEUP 3 #define VOLCMD_VOLSLIDEDOWN 4 #define VOLCMD_FINEVOLUP 5 #define VOLCMD_FINEVOLDOWN 6 #define VOLCMD_VIBRATOSPEED 7 #define VOLCMD_VIBRATO 8 #define VOLCMD_PANSLIDELEFT 9 #define VOLCMD_PANSLIDERIGHT 10 #define VOLCMD_TONEPORTAMENTO 11 #define VOLCMD_PORTAUP 12 #define VOLCMD_PORTADOWN 13 #define RSF_16BIT 0x04 #define RSF_STEREO 0x08 #define RS_PCM8S 0 // 8-bit signed #define RS_PCM8U 1 // 8-bit unsigned #define RS_PCM8D 2 // 8-bit delta values #define RS_ADPCM4 3 // 4-bit ADPCM-packed #define RS_PCM16D 4 // 16-bit delta values #define RS_PCM16S 5 // 16-bit signed #define RS_PCM16U 6 // 16-bit unsigned #define RS_PCM16M 7 // 16-bit motorola order #define RS_STPCM8S (RS_PCM8S|RSF_STEREO) // stereo 8-bit signed #define RS_STPCM8U (RS_PCM8U|RSF_STEREO) // stereo 8-bit unsigned #define RS_STPCM8D (RS_PCM8D|RSF_STEREO) // stereo 8-bit delta values #define RS_STPCM16S (RS_PCM16S|RSF_STEREO) // stereo 16-bit signed #define RS_STPCM16U (RS_PCM16U|RSF_STEREO) // stereo 16-bit unsigned #define RS_STPCM16D (RS_PCM16D|RSF_STEREO) // stereo 16-bit delta values #define RS_STPCM16M (RS_PCM16M|RSF_STEREO) // stereo 16-bit signed big endian // IT 2.14 compressed samples #define RS_IT2148 0x10 #define RS_IT21416 0x14 #define RS_IT2158 0x12 #define RS_IT21516 0x16 // AMS Packed Samples #define RS_AMS8 0x11 #define RS_AMS16 0x15 // DMF Huffman compression #define RS_DMF8 0x13 #define RS_DMF16 0x17 // MDL Huffman compression #define RS_MDL8 0x20 #define RS_MDL16 0x24 #define RS_PTM8DTO16 0x25 // Stereo Interleaved Samples #define RS_STIPCM8S (RS_PCM8S|0x40|RSF_STEREO) // stereo 8-bit signed #define RS_STIPCM8U (RS_PCM8U|0x40|RSF_STEREO) // stereo 8-bit unsigned #define RS_STIPCM16S (RS_PCM16S|0x40|RSF_STEREO) // stereo 16-bit signed #define RS_STIPCM16U (RS_PCM16U|0x40|RSF_STEREO) // stereo 16-bit unsigned #define RS_STIPCM16M (RS_PCM16M|0x40|RSF_STEREO) // stereo 16-bit signed big endian // 24-bit signed #define RS_PCM24S (RS_PCM16S|0x80) // mono 24-bit signed #define RS_STIPCM24S (RS_PCM16S|0x80|RSF_STEREO) // stereo 24-bit signed #define RS_PCM32S (RS_PCM16S|0xC0) // mono 24-bit signed #define RS_STIPCM32S (RS_PCM16S|0xC0|RSF_STEREO) // stereo 24-bit signed // NNA types #define NNA_NOTECUT 0 #define NNA_CONTINUE 1 #define NNA_NOTEOFF 2 #define NNA_NOTEFADE 3 // DCT types #define DCT_NONE 0 #define DCT_NOTE 1 #define DCT_SAMPLE 2 #define DCT_INSTRUMENT 3 // DNA types #define DNA_NOTECUT 0 #define DNA_NOTEOFF 1 #define DNA_NOTEFADE 2 // Mixer Hardware-Dependent features #define SYSMIX_ENABLEMMX 0x01 #define SYSMIX_WINDOWSNT 0x02 #define SYSMIX_SLOWCPU 0x04 #define SYSMIX_FASTCPU 0x08 // Module flags #define SONG_EMBEDMIDICFG 0x0001 #define SONG_FASTVOLSLIDES 0x0002 #define SONG_ITOLDEFFECTS 0x0004 #define SONG_ITCOMPATMODE 0x0008 #define SONG_LINEARSLIDES 0x0010 #define SONG_PATTERNLOOP 0x0020 #define SONG_STEP 0x0040 #define SONG_PAUSED 0x0080 #define SONG_FADINGSONG 0x0100 #define SONG_ENDREACHED 0x0200 #define SONG_GLOBALFADE 0x0400 #define SONG_CPUVERYHIGH 0x0800 #define SONG_FIRSTTICK 0x1000 #define SONG_MPTFILTERMODE 0x2000 #define SONG_SURROUNDPAN 0x4000 #define SONG_EXFILTERRANGE 0x8000 #define SONG_AMIGALIMITS 0x10000 // Global Options (Renderer) #define SNDMIX_REVERSESTEREO 0x0001 #define SNDMIX_NOISEREDUCTION 0x0002 #define SNDMIX_AGC 0x0004 #define SNDMIX_NORESAMPLING 0x0008 #define SNDMIX_HQRESAMPLER 0x0010 #define SNDMIX_MEGABASS 0x0020 #define SNDMIX_SURROUND 0x0040 #define SNDMIX_REVERB 0x0080 #define SNDMIX_EQ 0x0100 #define SNDMIX_SOFTPANNING 0x0200 #define SNDMIX_ULTRAHQSRCMODE 0x0400 // Misc Flags (can safely be turned on or off) #define SNDMIX_DIRECTTODISK 0x10000 #define SNDMIX_ENABLEMMX 0x20000 #define SNDMIX_NOBACKWARDJUMPS 0x40000 #define SNDMIX_MAXDEFAULTPAN 0x80000 // Used by the MOD loader // Reverb Types (GM2 Presets) enum { REVERBTYPE_SMALLROOM, REVERBTYPE_MEDIUMROOM, REVERBTYPE_LARGEROOM, REVERBTYPE_SMALLHALL, REVERBTYPE_MEDIUMHALL, REVERBTYPE_LARGEHALL, NUM_REVERBTYPES }; enum { SRCMODE_NEAREST, SRCMODE_LINEAR, SRCMODE_SPLINE, SRCMODE_POLYPHASE, NUM_SRC_MODES }; // Sample Struct typedef struct _MODINSTRUMENT { UINT nLength,nLoopStart,nLoopEnd; UINT nSustainStart, nSustainEnd; signed char *pSample; UINT nC4Speed; WORD nPan; WORD nVolume; WORD nGlobalVol; WORD uFlags; signed char RelativeTone; signed char nFineTune; BYTE nVibType; BYTE nVibSweep; BYTE nVibDepth; BYTE nVibRate; CHAR name[22]; } MODINSTRUMENT; // Instrument Struct typedef struct _INSTRUMENTHEADER { UINT nFadeOut; DWORD dwFlags; WORD nGlobalVol; WORD nPan; WORD VolPoints[MAX_ENVPOINTS]; WORD PanPoints[MAX_ENVPOINTS]; WORD PitchPoints[MAX_ENVPOINTS]; BYTE VolEnv[MAX_ENVPOINTS]; BYTE PanEnv[MAX_ENVPOINTS]; BYTE PitchEnv[MAX_ENVPOINTS]; BYTE Keyboard[128]; BYTE NoteMap[128]; BYTE nVolEnv; BYTE nPanEnv; BYTE nPitchEnv; BYTE nVolLoopStart; BYTE nVolLoopEnd; BYTE nVolSustainBegin; BYTE nVolSustainEnd; BYTE nPanLoopStart; BYTE nPanLoopEnd; BYTE nPanSustainBegin; BYTE nPanSustainEnd; BYTE nPitchLoopStart; BYTE nPitchLoopEnd; BYTE nPitchSustainBegin; BYTE nPitchSustainEnd; BYTE nNNA; BYTE nDCT; BYTE nDNA; BYTE nPanSwing; BYTE nVolSwing; BYTE nIFC; BYTE nIFR; WORD wMidiBank; BYTE nMidiProgram; BYTE nMidiChannel; BYTE nMidiDrumKey; signed char nPPS; unsigned char nPPC; CHAR name[32]; CHAR filename[12]; } INSTRUMENTHEADER; // Channel Struct typedef struct _MODCHANNEL { // First 32-bytes: Most used mixing information: don't change it signed char * pCurrentSample; DWORD nPos; DWORD nPosLo; // actually 16-bit LONG nInc; // 16.16 LONG nRightVol; LONG nLeftVol; LONG nRightRamp; LONG nLeftRamp; // 2nd cache line DWORD nLength; DWORD dwFlags; DWORD nLoopStart; DWORD nLoopEnd; LONG nRampRightVol; LONG nRampLeftVol; LONG nFilter_Y1, nFilter_Y2, nFilter_Y3, nFilter_Y4; LONG nFilter_A0, nFilter_B0, nFilter_B1; LONG nROfs, nLOfs; LONG nRampLength; // Information not used in the mixer signed char * pSample; LONG nNewRightVol, nNewLeftVol; LONG nRealVolume, nRealPan; LONG nVolume, nPan, nFadeOutVol; LONG nPeriod, nC4Speed, nPortamentoDest; INSTRUMENTHEADER *pHeader; MODINSTRUMENT *pInstrument; DWORD nVolEnvPosition, nPanEnvPosition, nPitchEnvPosition; DWORD nMasterChn, nVUMeter; LONG nGlobalVol, nInsVol; LONG nFineTune, nTranspose; LONG nPortamentoSlide, nAutoVibDepth; UINT nAutoVibPos, nVibratoPos, nTremoloPos, nPanbrelloPos; // 16-bit members signed short nVolSwing, nPanSwing; // 8-bit members BYTE nNote, nNNA; BYTE nNewNote, nNewIns, nCommand, nArpeggio; BYTE nOldVolumeSlide, nOldFineVolUpDown; BYTE nOldPortaUpDown, nOldFinePortaUpDown; BYTE nOldPanSlide, nOldChnVolSlide; BYTE nVibratoType, nVibratoSpeed, nVibratoDepth; BYTE nTremoloType, nTremoloSpeed, nTremoloDepth; BYTE nPanbrelloType, nPanbrelloSpeed, nPanbrelloDepth; BYTE nOldCmdEx, nOldVolParam, nOldTempo; BYTE nOldOffset, nOldHiOffset; BYTE nCutOff, nResonance; BYTE nRetrigCount, nRetrigParam; BYTE nTremorCount, nTremorParam; BYTE nPatternLoop, nPatternLoopCount; BYTE nRowNote, nRowInstr; BYTE nRowVolCmd, nRowVolume; BYTE nRowCommand, nRowParam; BYTE nLeftVU, nRightVU; BYTE nActiveMacro, nPadding; } MODCHANNEL; typedef struct _MODCHANNELSETTINGS { UINT nPan; UINT nVolume; DWORD dwFlags; UINT nMixPlugin; char szName[MAX_CHANNELNAME]; // changed from CHAR } MODCHANNELSETTINGS; typedef struct _MODCOMMAND { BYTE note; BYTE instr; BYTE volcmd; BYTE command; BYTE vol; BYTE param; } MODCOMMAND, *LPMODCOMMAND; //////////////////////////////////////////////////////////////////// // Mix Plugins #define MIXPLUG_MIXREADY 0x01 // Set when cleared class IMixPlugin { public: virtual ~IMixPlugin(); virtual int AddRef() = 0; virtual int Release() = 0; virtual void SaveAllParameters() = 0; virtual void RestoreAllParameters() = 0; virtual void Process(float *pOutL, float *pOutR, unsigned long nSamples) = 0; virtual void Init(unsigned long nFreq, int bReset) = 0; virtual void MidiSend(DWORD dwMidiCode) = 0; virtual void MidiCommand(UINT nMidiCh, UINT nMidiProg, UINT note, UINT vol) = 0; }; #define MIXPLUG_INPUTF_MASTEREFFECT 0x01 // Apply to master mix #define MIXPLUG_INPUTF_BYPASS 0x02 // Bypass effect #define MIXPLUG_INPUTF_WETMIX 0x04 // Wet Mix (dry added) typedef struct _SNDMIXPLUGINSTATE { DWORD dwFlags; // MIXPLUG_XXXX LONG nVolDecayL, nVolDecayR; // Buffer click removal int *pMixBuffer; // Stereo effect send buffer float *pOutBufferL; // Temp storage for int -> float conversion float *pOutBufferR; } SNDMIXPLUGINSTATE, *PSNDMIXPLUGINSTATE; typedef struct _SNDMIXPLUGININFO { DWORD dwPluginId1; DWORD dwPluginId2; DWORD dwInputRouting; // MIXPLUG_INPUTF_XXXX DWORD dwOutputRouting; // 0=mix 0x80+=fx DWORD dwReserved[4]; // Reserved for routing info CHAR szName[32]; CHAR szLibraryName[64]; // original DLL name } SNDMIXPLUGININFO, *PSNDMIXPLUGININFO; // Size should be 128 typedef struct _SNDMIXPLUGIN { IMixPlugin *pMixPlugin; PSNDMIXPLUGINSTATE pMixState; ULONG nPluginDataSize; PVOID pPluginData; SNDMIXPLUGININFO Info; } SNDMIXPLUGIN, *PSNDMIXPLUGIN; typedef BOOL (*PMIXPLUGINCREATEPROC)(PSNDMIXPLUGIN); //////////////////////////////////////////////////////////////////// enum { MIDIOUT_START=0, MIDIOUT_STOP, MIDIOUT_TICK, MIDIOUT_NOTEON, MIDIOUT_NOTEOFF, MIDIOUT_VOLUME, MIDIOUT_PAN, MIDIOUT_BANKSEL, MIDIOUT_PROGRAM, }; typedef struct MODMIDICFG { char szMidiGlb[9*32]; // changed from CHAR char szMidiSFXExt[16*32]; // changed from CHAR char szMidiZXXExt[128*32]; // changed from CHAR } MODMIDICFG, *LPMODMIDICFG; #define NOTE_MAX 120 //Defines maximum notevalue as well as maximum number of notes. typedef VOID (* LPSNDMIXHOOKPROC)(int *, unsigned long, unsigned long); // buffer, samples, channels //============== class CSoundFile //============== { public: // Static Members static UINT m_nXBassDepth, m_nXBassRange; static UINT m_nReverbDepth, m_nReverbDelay, gnReverbType; static UINT m_nProLogicDepth, m_nProLogicDelay; static UINT m_nStereoSeparation; static UINT m_nMaxMixChannels; static LONG m_nStreamVolume; static DWORD gdwSysInfo, gdwSoundSetup, gdwMixingFreq, gnBitsPerSample, gnChannels; static UINT gnAGC, gnVolumeRampSamples, gnVUMeter, gnCPUUsage; static LPSNDMIXHOOKPROC gpSndMixHook; static PMIXPLUGINCREATEPROC gpMixPluginCreateProc; public: // for Editing MODCHANNEL Chn[MAX_CHANNELS]; // Channels UINT ChnMix[MAX_CHANNELS]; // Channels to be mixed MODINSTRUMENT Ins[MAX_SAMPLES]; // Instruments INSTRUMENTHEADER *Headers[MAX_INSTRUMENTS]; // Instrument Headers MODCHANNELSETTINGS ChnSettings[MAX_BASECHANNELS]; // Channels settings MODCOMMAND *Patterns[MAX_PATTERNS]; // Patterns WORD PatternSize[MAX_PATTERNS]; // Patterns Lengths BYTE Order[MAX_ORDERS]; // Pattern Orders MODMIDICFG m_MidiCfg; // Midi macro config table SNDMIXPLUGIN m_MixPlugins[MAX_MIXPLUGINS]; // Mix plugins UINT m_nDefaultSpeed, m_nDefaultTempo, m_nDefaultGlobalVolume; DWORD m_dwSongFlags; // Song flags SONG_XXXX UINT m_nChannels, m_nMixChannels, m_nMixStat, m_nBufferCount; UINT m_nType, m_nSamples, m_nInstruments; UINT m_nTickCount, m_nTotalCount, m_nPatternDelay, m_nFrameDelay; UINT m_nMusicSpeed, m_nMusicTempo; UINT m_nNextRow, m_nRow; UINT m_nPattern,m_nCurrentPattern,m_nNextPattern,m_nRestartPos; UINT m_nMasterVolume, m_nGlobalVolume, m_nSongPreAmp; UINT m_nFreqFactor, m_nTempoFactor, m_nOldGlbVolSlide; LONG m_nMinPeriod, m_nMaxPeriod, m_nRepeatCount, m_nInitialRepeatCount; DWORD m_nGlobalFadeSamples, m_nGlobalFadeMaxSamples; UINT m_nMaxOrderPosition; UINT m_nPatternNames; LPSTR m_lpszSongComments, m_lpszPatternNames; char m_szNames[MAX_INSTRUMENTS][32]; // changed from CHAR CHAR CompressionTable[16]; public: CSoundFile(); ~CSoundFile(); public: BOOL Create(LPCBYTE lpStream, DWORD dwMemLength=0); BOOL Destroy(); UINT GetType() const { return m_nType; } UINT GetNumChannels() const; UINT GetLogicalChannels() const { return m_nChannels; } BOOL SetMasterVolume(UINT vol, BOOL bAdjustAGC=FALSE); UINT GetMasterVolume() const { return m_nMasterVolume; } UINT GetNumPatterns() const; UINT GetNumInstruments() const; UINT GetNumSamples() const { return m_nSamples; } UINT GetCurrentPos() const; UINT GetCurrentPattern() const { return m_nPattern; } UINT GetCurrentOrder() const { return m_nCurrentPattern; } UINT GetSongComments(LPSTR s, UINT cbsize, UINT linesize=32); UINT GetRawSongComments(LPSTR s, UINT cbsize, UINT linesize=32); UINT GetMaxPosition() const; void SetCurrentPos(UINT nPos); void SetCurrentOrder(UINT nOrder); void GetTitle(LPSTR s) const { lstrcpyn(s,m_szNames[0],32); } LPCSTR GetTitle() const { return m_szNames[0]; } UINT GetSampleName(UINT nSample,LPSTR s=NULL) const; UINT GetInstrumentName(UINT nInstr,LPSTR s=NULL) const; UINT GetMusicSpeed() const { return m_nMusicSpeed; } UINT GetMusicTempo() const { return m_nMusicTempo; } DWORD GetLength(BOOL bAdjust, BOOL bTotal=FALSE); DWORD GetSongTime() { return GetLength(FALSE, TRUE); } void SetRepeatCount(int n) { m_nRepeatCount = n; m_nInitialRepeatCount = n; } int GetRepeatCount() const { return m_nRepeatCount; } BOOL IsPaused() const { return (m_dwSongFlags & SONG_PAUSED) ? TRUE : FALSE; } void LoopPattern(int nPat, int nRow=0); void CheckCPUUsage(UINT nCPU); BOOL SetPatternName(UINT nPat, LPCSTR lpszName); BOOL GetPatternName(UINT nPat, LPSTR lpszName, UINT cbSize=MAX_PATTERNNAME) const; // Module Loaders BOOL ReadXM(LPCBYTE lpStream, DWORD dwMemLength); BOOL ReadS3M(LPCBYTE lpStream, DWORD dwMemLength); BOOL ReadMod(LPCBYTE lpStream, DWORD dwMemLength); BOOL ReadMed(LPCBYTE lpStream, DWORD dwMemLength); BOOL ReadMTM(LPCBYTE lpStream, DWORD dwMemLength); BOOL ReadSTM(LPCBYTE lpStream, DWORD dwMemLength); BOOL ReadIT(LPCBYTE lpStream, DWORD dwMemLength); BOOL Read669(LPCBYTE lpStream, DWORD dwMemLength); BOOL ReadUlt(LPCBYTE lpStream, DWORD dwMemLength); BOOL ReadWav(LPCBYTE lpStream, DWORD dwMemLength); BOOL ReadDSM(LPCBYTE lpStream, DWORD dwMemLength); BOOL ReadFAR(LPCBYTE lpStream, DWORD dwMemLength); BOOL ReadAMS(LPCBYTE lpStream, DWORD dwMemLength); BOOL ReadAMS2(LPCBYTE lpStream, DWORD dwMemLength); BOOL ReadMDL(LPCBYTE lpStream, DWORD dwMemLength); BOOL ReadOKT(LPCBYTE lpStream, DWORD dwMemLength); BOOL ReadDMF(LPCBYTE lpStream, DWORD dwMemLength); BOOL ReadPTM(LPCBYTE lpStream, DWORD dwMemLength); BOOL ReadDBM(LPCBYTE lpStream, DWORD dwMemLength); BOOL ReadAMF(LPCBYTE lpStream, DWORD dwMemLength); BOOL ReadMT2(LPCBYTE lpStream, DWORD dwMemLength); BOOL ReadPSM(LPCBYTE lpStream, DWORD dwMemLength); BOOL ReadJ2B(LPCBYTE lpStream, DWORD dwMemLength); BOOL ReadUMX(LPCBYTE lpStream, DWORD dwMemLength); BOOL ReadABC(LPCBYTE lpStream, DWORD dwMemLength); BOOL TestABC(LPCBYTE lpStream, DWORD dwMemLength); BOOL ReadMID(LPCBYTE lpStream, DWORD dwMemLength); BOOL TestMID(LPCBYTE lpStream, DWORD dwMemLength); BOOL ReadPAT(LPCBYTE lpStream, DWORD dwMemLength); BOOL TestPAT(LPCBYTE lpStream, DWORD dwMemLength); // Save Functions #ifndef MODPLUG_NO_FILESAVE UINT WriteSample(FILE *f, MODINSTRUMENT *pins, UINT nFlags, UINT nMaxLen=0); BOOL SaveXM(LPCSTR lpszFileName, UINT nPacking=0); BOOL SaveS3M(LPCSTR lpszFileName, UINT nPacking=0); BOOL SaveMod(LPCSTR lpszFileName, UINT nPacking=0); BOOL SaveIT(LPCSTR lpszFileName, UINT nPacking=0); #endif // MODPLUG_NO_FILESAVE // MOD Convert function UINT GetBestSaveFormat() const; UINT GetSaveFormats() const; void ConvertModCommand(MODCOMMAND *) const; void S3MConvert(MODCOMMAND *m, BOOL bIT) const; void S3MSaveConvert(UINT *pcmd, UINT *pprm, BOOL bIT) const; WORD ModSaveCommand(const MODCOMMAND *m, BOOL bXM) const; public: // Real-time sound functions VOID ResetChannels(); UINT Read(LPVOID lpBuffer, UINT cbBuffer); UINT CreateStereoMix(int count); BOOL FadeSong(UINT msec); BOOL GlobalFadeSong(UINT msec); UINT GetTotalTickCount() const { return m_nTotalCount; } VOID ResetTotalTickCount() { m_nTotalCount = 0; } public: // Mixer Config static BOOL InitPlayer(BOOL bReset=FALSE); static BOOL SetMixConfig(UINT nStereoSeparation, UINT nMaxMixChannels); static BOOL SetWaveConfig(UINT nRate,UINT nBits,UINT nChannels,BOOL bMMX=FALSE); static BOOL SetResamplingMode(UINT nMode); // SRCMODE_XXXX static BOOL IsStereo() { return (gnChannels > 1) ? TRUE : FALSE; } static DWORD GetSampleRate() { return gdwMixingFreq; } static DWORD GetBitsPerSample() { return gnBitsPerSample; } static DWORD InitSysInfo(); static DWORD GetSysInfo() { return gdwSysInfo; } // AGC static BOOL GetAGC() { return (gdwSoundSetup & SNDMIX_AGC) ? TRUE : FALSE; } static void SetAGC(BOOL b); static void ResetAGC(); static void ProcessAGC(int count); //GCCFIX -- added these functions back in! static BOOL SetWaveConfigEx(BOOL bSurround,BOOL bNoOverSampling,BOOL bReverb,BOOL hqido,BOOL bMegaBass,BOOL bNR,BOOL bEQ); // DSP Effects static void InitializeDSP(BOOL bReset); static void ProcessStereoDSP(int count); static void ProcessMonoDSP(int count); // [Reverb level 0(quiet)-100(loud)], [delay in ms, usually 40-200ms] static BOOL SetReverbParameters(UINT nDepth, UINT nDelay); // [XBass level 0(quiet)-100(loud)], [cutoff in Hz 10-100] static BOOL SetXBassParameters(UINT nDepth, UINT nRange); // [Surround level 0(quiet)-100(heavy)] [delay in ms, usually 5-40ms] static BOOL SetSurroundParameters(UINT nDepth, UINT nDelay); public: BOOL ReadNote(); BOOL ProcessRow(); BOOL ProcessEffects(); UINT GetNNAChannel(UINT nChn) const; void CheckNNA(UINT nChn, UINT instr, int note, BOOL bForceCut); void NoteChange(UINT nChn, int note, BOOL bPorta=FALSE, BOOL bResetEnv=TRUE); void InstrumentChange(MODCHANNEL *pChn, UINT instr, BOOL bPorta=FALSE,BOOL bUpdVol=TRUE,BOOL bResetEnv=TRUE); // Channel Effects void PortamentoUp(MODCHANNEL *pChn, UINT param); void PortamentoDown(MODCHANNEL *pChn, UINT param); void FinePortamentoUp(MODCHANNEL *pChn, UINT param); void FinePortamentoDown(MODCHANNEL *pChn, UINT param); void ExtraFinePortamentoUp(MODCHANNEL *pChn, UINT param); void ExtraFinePortamentoDown(MODCHANNEL *pChn, UINT param); void TonePortamento(MODCHANNEL *pChn, UINT param); void Vibrato(MODCHANNEL *pChn, UINT param); void FineVibrato(MODCHANNEL *pChn, UINT param); void VolumeSlide(MODCHANNEL *pChn, UINT param); void PanningSlide(MODCHANNEL *pChn, UINT param); void ChannelVolSlide(MODCHANNEL *pChn, UINT param); void FineVolumeUp(MODCHANNEL *pChn, UINT param); void FineVolumeDown(MODCHANNEL *pChn, UINT param); void Tremolo(MODCHANNEL *pChn, UINT param); void Panbrello(MODCHANNEL *pChn, UINT param); void RetrigNote(UINT nChn, UINT param); void NoteCut(UINT nChn, UINT nTick); void KeyOff(UINT nChn); int PatternLoop(MODCHANNEL *, UINT param); void ExtendedMODCommands(UINT nChn, UINT param); void ExtendedS3MCommands(UINT nChn, UINT param); void ExtendedChannelEffect(MODCHANNEL *, UINT param); void ProcessMidiMacro(UINT nChn, LPCSTR pszMidiMacro, UINT param=0); void SetupChannelFilter(MODCHANNEL *pChn, BOOL bReset, int flt_modifier=256) const; // Low-Level effect processing void DoFreqSlide(MODCHANNEL *pChn, LONG nFreqSlide); // Global Effects void SetTempo(UINT param); void SetSpeed(UINT param); void GlobalVolSlide(UINT param); DWORD IsSongFinished(UINT nOrder, UINT nRow) const; BOOL IsValidBackwardJump(UINT nStartOrder, UINT nStartRow, UINT nJumpOrder, UINT nJumpRow) const; // Read/Write sample functions signed char GetDeltaValue(signed char prev, UINT n) const { return (signed char)(prev + CompressionTable[n & 0x0F]); } UINT PackSample(int &sample, int next); BOOL CanPackSample(LPSTR pSample, UINT nLen, UINT nPacking, BYTE *result=NULL); UINT ReadSample(MODINSTRUMENT *pIns, UINT nFlags, LPCSTR pMemFile, DWORD dwMemLength); BOOL DestroySample(UINT nSample); BOOL DestroyInstrument(UINT nInstr); BOOL IsSampleUsed(UINT nSample); BOOL IsInstrumentUsed(UINT nInstr); BOOL RemoveInstrumentSamples(UINT nInstr); UINT DetectUnusedSamples(BOOL *); BOOL RemoveSelectedSamples(BOOL *); void AdjustSampleLoop(MODINSTRUMENT *pIns); // I/O from another sound file BOOL ReadInstrumentFromSong(UINT nInstr, CSoundFile *, UINT nSrcInstrument); BOOL ReadSampleFromSong(UINT nSample, CSoundFile *, UINT nSrcSample); // Period/Note functions UINT GetNoteFromPeriod(UINT period) const; UINT GetPeriodFromNote(UINT note, int nFineTune, UINT nC4Speed) const; UINT GetFreqFromPeriod(UINT period, UINT nC4Speed, int nPeriodFrac=0) const; // Misc functions MODINSTRUMENT *GetSample(UINT n) { return Ins+n; } void ResetMidiCfg(); UINT MapMidiInstrument(DWORD dwProgram, UINT nChannel, UINT nNote); BOOL ITInstrToMPT(const void *p, INSTRUMENTHEADER *penv, UINT trkvers); UINT SaveMixPlugins(FILE *f=NULL, BOOL bUpdate=TRUE); UINT LoadMixPlugins(const void *pData, UINT nLen); #ifndef NO_FILTER DWORD CutOffToFrequency(UINT nCutOff, int flt_modifier=256) const; // [0-255] => [1-10KHz] #endif // Static helper functions public: static DWORD TransposeToFrequency(int transp, int ftune=0); static int FrequencyToTranspose(DWORD freq); static void FrequencyToTranspose(MODINSTRUMENT *psmp); // System-Dependant functions public: static MODCOMMAND *AllocatePattern(UINT rows, UINT nchns); static signed char* AllocateSample(UINT nbytes); static void FreePattern(LPVOID pat); static void FreeSample(LPVOID p); static UINT Normalize24BitBuffer(LPBYTE pbuffer, UINT cbsizebytes, DWORD lmax24, DWORD dwByteInc); }; // inline DWORD BigEndian(DWORD x) { return ((x & 0xFF) << 24) | ((x & 0xFF00) << 8) | ((x & 0xFF0000) >> 8) | ((x & 0xFF000000) >> 24); } // inline WORD BigEndianW(WORD x) { return (WORD)(((x >> 8) & 0xFF) | ((x << 8) & 0xFF00)); } ////////////////////////////////////////////////////////// // WAVE format information #pragma pack(1) // Standard IFF chunks IDs #define IFFID_FORM 0x4d524f46 #define IFFID_RIFF 0x46464952 #define IFFID_WAVE 0x45564157 #define IFFID_LIST 0x5453494C #define IFFID_INFO 0x4F464E49 // IFF Info fields #define IFFID_ICOP 0x504F4349 #define IFFID_IART 0x54524149 #define IFFID_IPRD 0x44525049 #define IFFID_INAM 0x4D414E49 #define IFFID_ICMT 0x544D4349 #define IFFID_IENG 0x474E4549 #define IFFID_ISFT 0x54465349 #define IFFID_ISBJ 0x4A425349 #define IFFID_IGNR 0x524E4749 #define IFFID_ICRD 0x44524349 // Wave IFF chunks IDs #define IFFID_wave 0x65766177 #define IFFID_fmt 0x20746D66 #define IFFID_wsmp 0x706D7377 #define IFFID_pcm 0x206d6370 #define IFFID_data 0x61746164 #define IFFID_smpl 0x6C706D73 #define IFFID_xtra 0x61727478 typedef struct WAVEFILEHEADER { DWORD id_RIFF; // "RIFF" DWORD filesize; // file length-8 DWORD id_WAVE; } WAVEFILEHEADER; typedef struct WAVEFORMATHEADER { DWORD id_fmt; // "fmt " DWORD hdrlen; // 16 WORD format; // 1 WORD channels; // 1:mono, 2:stereo DWORD freqHz; // sampling freq DWORD bytessec; // bytes/sec=freqHz*samplesize WORD samplesize; // sizeof(sample) WORD bitspersample; // bits per sample (8/16) } WAVEFORMATHEADER; typedef struct WAVEDATAHEADER { DWORD id_data; // "data" DWORD length; // length of data } WAVEDATAHEADER; typedef struct WAVESMPLHEADER { // SMPL DWORD smpl_id; // "smpl" -> 0x6C706D73 DWORD smpl_len; // length of smpl: 3Ch (54h with sustain loop) DWORD dwManufacturer; DWORD dwProduct; DWORD dwSamplePeriod; // 1000000000/freqHz DWORD dwBaseNote; // 3Ch = C-4 -> 60 + RelativeTone DWORD dwPitchFraction; DWORD dwSMPTEFormat; DWORD dwSMPTEOffset; DWORD dwSampleLoops; // number of loops DWORD cbSamplerData; } WAVESMPLHEADER; typedef struct SAMPLELOOPSTRUCT { DWORD dwIdentifier; DWORD dwLoopType; // 0=normal, 1=bidi DWORD dwLoopStart; DWORD dwLoopEnd; // Byte offset ? DWORD dwFraction; DWORD dwPlayCount; // Loop Count, 0=infinite } SAMPLELOOPSTRUCT; typedef struct WAVESAMPLERINFO { WAVESMPLHEADER wsiHdr; SAMPLELOOPSTRUCT wsiLoops[2]; } WAVESAMPLERINFO; typedef struct WAVELISTHEADER { DWORD list_id; // "LIST" -> 0x5453494C DWORD list_len; DWORD info; // "INFO" } WAVELISTHEADER; typedef struct WAVEEXTRAHEADER { DWORD xtra_id; // "xtra" -> 0x61727478 DWORD xtra_len; DWORD dwFlags; WORD wPan; WORD wVolume; WORD wGlobalVol; WORD wReserved; BYTE nVibType; BYTE nVibSweep; BYTE nVibDepth; BYTE nVibRate; } WAVEEXTRAHEADER; #pragma pack() /////////////////////////////////////////////////////////// // Low-level Mixing functions #define MIXBUFFERSIZE 512 #define MIXING_ATTENUATION 4 #define MIXING_CLIPMIN (-0x08000000) #define MIXING_CLIPMAX (0x07FFFFFF) #define VOLUMERAMPPRECISION 12 #define FADESONGDELAY 100 #define EQ_BUFFERSIZE (MIXBUFFERSIZE) #define AGC_PRECISION 9 #define AGC_UNITY (1 << AGC_PRECISION) // Calling conventions #ifdef MSC_VER #define MPPASMCALL __cdecl #define MPPFASTCALL __fastcall #else #define MPPASMCALL #define MPPFASTCALL #endif #define MOD2XMFineTune(k) ((int)( (signed char)((k)<<4) )) #define XM2MODFineTune(k) ((int)( (k>>4)&0x0f )) int _muldiv(long a, long b, long c); int _muldivr(long a, long b, long c); // Byte swapping functions from the GNU C Library and libsdl /* Swap bytes in 16 bit value. */ #ifdef __GNUC__ # define bswap_16(x) \ (__extension__ \ ({ unsigned short int __bsx = (x); \ ((((__bsx) >> 8) & 0xff) | (((__bsx) & 0xff) << 8)); })) #else static __inline unsigned short int bswap_16 (unsigned short int __bsx) { return ((((__bsx) >> 8) & 0xff) | (((__bsx) & 0xff) << 8)); } #endif /* Swap bytes in 32 bit value. */ #ifdef __GNUC__ # define bswap_32(x) \ (__extension__ \ ({ unsigned int __bsx = (x); \ ((((__bsx) & 0xff000000) >> 24) | (((__bsx) & 0x00ff0000) >> 8) | \ (((__bsx) & 0x0000ff00) << 8) | (((__bsx) & 0x000000ff) << 24)); })) #else static __inline unsigned int bswap_32 (unsigned int __bsx) { return ((((__bsx) & 0xff000000) >> 24) | (((__bsx) & 0x00ff0000) >> 8) | (((__bsx) & 0x0000ff00) << 8) | (((__bsx) & 0x000000ff) << 24)); } #endif #if (defined ARM) && (defined _WIN32_WCE) static __inline unsigned short int ARM_get16(const void *data) { unsigned short int s; memcpy(&s,data,sizeof(s)); return s; } static __inline unsigned int ARM_get32(const void *data) { unsigned int s; memcpy(&s,data,sizeof(s)); return s; } #define bswapLE16(X) ARM_get16(&X) #define bswapLE32(X) ARM_get32(&X) #define bswapBE16(X) bswap_16(ARM_get16(&X)) #define bswapBE32(X) bswap_32(ARM_get32(&X)) // From libsdl #elif defined(WORDS_BIGENDIAN) && WORDS_BIGENDIAN #define bswapLE16(X) bswap_16(X) #define bswapLE32(X) bswap_32(X) #define bswapBE16(X) (X) #define bswapBE32(X) (X) #else #define bswapLE16(X) (X) #define bswapLE32(X) (X) #define bswapBE16(X) bswap_16(X) #define bswapBE32(X) bswap_32(X) #endif #endif libopenmpt-0.3.6+release.autotools/openmpt123/0000755000372100037210000000000013235362226016252 500000000000000libopenmpt-0.3.6+release.autotools/openmpt123/openmpt123.cpp0000644000372100037210000024201513222361677020617 00000000000000/* * openmpt123.cpp * -------------- * Purpose: libopenmpt command line player * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ static const char * const license = "The OpenMPT code is licensed under the BSD license." "\n" "" "\n" "Copyright (c) 2004-2018, OpenMPT contributors" "\n" "Copyright (c) 1997-2003, Olivier Lapicque" "\n" "All rights reserved." "\n" "" "\n" "Redistribution and use in source and binary forms, with or without" "\n" "modification, are permitted provided that the following conditions are met:" "\n" " * Redistributions of source code must retain the above copyright" "\n" " notice, this list of conditions and the following disclaimer." "\n" " * Redistributions in binary form must reproduce the above copyright" "\n" " notice, this list of conditions and the following disclaimer in the" "\n" " documentation and/or other materials provided with the distribution." "\n" " * Neither the name of the OpenMPT project nor the" "\n" " names of its contributors may be used to endorse or promote products" "\n" " derived from this software without specific prior written permission." "\n" "" "\n" "THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY" "\n" "EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED" "\n" "WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE" "\n" "DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY" "\n" "DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES" "\n" "(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;" "\n" "LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND" "\n" "ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT" "\n" "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS" "\n" "SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." "\n" ; #include "openmpt123_config.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(WIN32) #include #include #include #include #include #include #include #include #else #if defined(MPT_NEEDS_THREADS) #include #endif #include #include #include #include #include #include #endif #include #include "openmpt123.hpp" #include "openmpt123_flac.hpp" #include "openmpt123_mmio.hpp" #include "openmpt123_sndfile.hpp" #include "openmpt123_raw.hpp" #include "openmpt123_stdout.hpp" #include "openmpt123_portaudio.hpp" #include "openmpt123_pulseaudio.hpp" #include "openmpt123_sdl.hpp" #include "openmpt123_sdl2.hpp" #include "openmpt123_waveout.hpp" namespace openmpt123 { struct silent_exit_exception : public std::exception { silent_exit_exception() throw() { } }; struct show_license_exception : public std::exception { show_license_exception() throw() { } }; struct show_credits_exception : public std::exception { show_credits_exception() throw() { } }; struct show_man_version_exception : public std::exception { show_man_version_exception() throw() { } }; struct show_man_help_exception : public std::exception { show_man_help_exception() throw() { } }; struct show_short_version_number_exception : public std::exception { show_short_version_number_exception() throw() { } }; struct show_version_number_exception : public std::exception { show_version_number_exception() throw() { } }; struct show_long_version_number_exception : public std::exception { show_long_version_number_exception() throw() { } }; bool IsTerminal( int fd ) { #if defined( WIN32 ) return true && ( _isatty( fd ) ? true : false ) && GetConsoleWindow() != NULL ; #else return isatty( fd ) ? true : false; #endif } #if !defined( WIN32 ) static termios saved_attributes; static void reset_input_mode() { tcsetattr( STDIN_FILENO, TCSANOW, &saved_attributes ); } static void set_input_mode() { termios tattr; if ( !isatty( STDIN_FILENO ) ) { return; } tcgetattr( STDIN_FILENO, &saved_attributes ); atexit( reset_input_mode ); tcgetattr( STDIN_FILENO, &tattr ); tattr.c_lflag &= ~( ICANON | ECHO ); tattr.c_cc[VMIN] = 1; tattr.c_cc[VTIME] = 0; tcsetattr( STDIN_FILENO, TCSAFLUSH, &tattr ); } #endif class file_audio_stream_raii : public file_audio_stream_base { private: file_audio_stream_base * impl; public: file_audio_stream_raii( const commandlineflags & flags, const std::string & filename, std::ostream & log ) : impl(0) { if ( !flags.force_overwrite ) { std::ifstream testfile( filename, std::ios::binary ); if ( testfile ) { throw exception( "file already exists" ); } } if ( false ) { // nothing } else if ( flags.output_extension == "raw" ) { impl = new raw_stream_raii( filename, flags, log ); #ifdef MPT_WITH_MMIO } else if ( flags.output_extension == "wav" ) { impl = new mmio_stream_raii( filename, flags, log ); #endif #ifdef MPT_WITH_FLAC } else if ( flags.output_extension == "flac" ) { impl = new flac_stream_raii( filename, flags, log ); #endif #ifdef MPT_WITH_SNDFILE } else { impl = new sndfile_stream_raii( filename, flags, log ); #endif } if ( !impl ) { throw exception( "file format handler '" + flags.output_extension + "' not found" ); } } virtual ~file_audio_stream_raii() { if ( impl ) { delete impl; impl = 0; } } virtual void write_metadata( std::map metadata ) { impl->write_metadata( metadata ); } virtual void write_updated_metadata( std::map metadata ) { impl->write_updated_metadata( metadata ); } virtual void write( const std::vector buffers, std::size_t frames ) { impl->write( buffers, frames ); } virtual void write( const std::vector buffers, std::size_t frames ) { impl->write( buffers, frames ); } }; static std::string ctls_to_string( const std::map & ctls ) { std::string result; for ( std::map::const_iterator it = ctls.begin(); it != ctls.end(); ++it ) { if ( !result.empty() ) { result += "; "; } result += it->first + "=" + it->second; } return result; } static double tempo_flag_to_double( std::int32_t tempo ) { return std::pow( 2.0, tempo / 24.0 ); } static double pitch_flag_to_double( std::int32_t pitch ) { return std::pow( 2.0, pitch / 24.0 ); } static double my_round( double val ) { if ( val >= 0.0 ) { return std::floor( val + 0.5 ); } else { return std::ceil( val - 0.5 ); } } static std::int32_t double_to_tempo_flag( double factor ) { return static_cast( my_round( std::log( factor ) / std::log( 2.0 ) * 24.0 ) ); } static std::int32_t double_to_pitch_flag( double factor ) { return static_cast( my_round( std::log( factor ) / std::log( 2.0 ) * 24.0 ) ); } static std::ostream & operator << ( std::ostream & s, const commandlineflags & flags ) { s << "Quiet: " << flags.quiet << std::endl; s << "Verbose: " << flags.verbose << std::endl; s << "Mode : " << mode_to_string( flags.mode ) << std::endl; s << "Show progress: " << flags.show_progress << std::endl; s << "Show peak meters: " << flags.show_meters << std::endl; s << "Show channel peak meters: " << flags.show_channel_meters << std::endl; s << "Show details: " << flags.show_details << std::endl; s << "Show message: " << flags.show_message << std::endl; s << "Update: " << flags.ui_redraw_interval << "ms" << std::endl; s << "Device: " << flags.device << std::endl; s << "Buffer: " << flags.buffer << "ms" << std::endl; s << "Period: " << flags.period << "ms" << std::endl; s << "Samplerate: " << flags.samplerate << std::endl; s << "Channels: " << flags.channels << std::endl; s << "Float: " << flags.use_float << std::endl; s << "Gain: " << flags.gain / 100.0 << std::endl; s << "Stereo separation: " << flags.separation << std::endl; s << "Interpolation filter taps: " << flags.filtertaps << std::endl; s << "Volume ramping strength: " << flags.ramping << std::endl; s << "Tempo: " << tempo_flag_to_double( flags.tempo ) << std::endl; s << "Pitch: " << pitch_flag_to_double( flags.pitch ) << std::endl; s << "Output dithering: " << flags.dither << std::endl; s << "Repeat count: " << flags.repeatcount << std::endl; s << "Seek target: " << flags.seek_target << std::endl; s << "End time: " << flags.end_time << std::endl; s << "Standard output: " << flags.use_stdout << std::endl; s << "Output filename: " << flags.output_filename << std::endl; s << "Force overwrite output file: " << flags.force_overwrite << std::endl; s << "Ctls: " << ctls_to_string( flags.ctls ) << std::endl; s << std::endl; s << "Files: " << std::endl; for ( std::vector::const_iterator filename = flags.filenames.begin(); filename != flags.filenames.end(); ++filename ) { s << " " << *filename << std::endl; } s << std::endl; return s; } static std::string replace( std::string str, const std::string & oldstr, const std::string & newstr ) { std::size_t pos = 0; while ( ( pos = str.find( oldstr, pos ) ) != std::string::npos ) { str.replace( pos, oldstr.length(), newstr ); pos += newstr.length(); } return str; } static bool begins_with( const std::string & str, const std::string & match ) { return ( str.find( match ) == 0 ); } static bool ends_with( const std::string & str, const std::string & match ) { return ( str.rfind( match ) == ( str.length() - match.length() ) ); } static std::string trim_left(std::string str, const std::string &whitespace = std::string()) { std::string::size_type pos = str.find_first_not_of(whitespace); if(pos != std::string::npos) { str.erase(str.begin(), str.begin() + pos); } else if(pos == std::string::npos && str.length() > 0 && str.find_last_of(whitespace) == str.length() - 1) { return std::string(); } return str; } static std::string trim_right(std::string str, const std::string &whitespace = std::string()) { std::string::size_type pos = str.find_last_not_of(whitespace); if(pos != std::string::npos) { str.erase(str.begin() + pos + 1, str.end()); } else if(pos == std::string::npos && str.length() > 0 && str.find_first_of(whitespace) == 0) { return std::string(); } return str; } static std::string trim(std::string str, const std::string &whitespace = std::string()) { return trim_right(trim_left(str, whitespace), whitespace); } static std::string trim_eol( const std::string & str ) { return trim( str, "\r\n" ); } static std::string default_path_separator() { #if defined(WIN32) return "\\"; #else return "/"; #endif } static std::string path_separators() { #if defined(WIN32) return "\\/"; #else return "/"; #endif } static bool is_path_separator( char c ) { #if defined(WIN32) return ( c == '\\' ) || ( c == '/' ); #else return c == '/'; #endif } static std::string get_basepath( std::string filename ) { std::string::size_type pos = filename.find_last_of( path_separators() ); if ( pos == std::string::npos ) { return std::string(); } return filename.substr( 0, pos ) + default_path_separator(); } static bool is_absolute( std::string filename ) { #if defined(WIN32) if ( begins_with( filename, "\\\\?\\UNC\\" ) ) { return true; } if ( begins_with( filename, "\\\\?\\" ) ) { return true; } if ( begins_with( filename, "\\\\" ) ) { return true; // UNC } if ( begins_with( filename, "//" ) ) { return true; // UNC } return ( filename.length() ) >= 3 && ( filename[1] == ':' ) && is_path_separator( filename[2] ); #else return ( filename.length() >= 1 ) && is_path_separator( filename[0] ); #endif } static std::string get_filename( const std::string & filepath ) { if ( filepath.find_last_of( path_separators() ) == std::string::npos ) { return filepath; } return filepath.substr( filepath.find_last_of( path_separators() ) + 1 ); } static std::string prepend_lines( std::string str, const std::string & prefix ) { if ( str.empty() ) { return str; } if ( str.substr( str.length() - 1, 1 ) == std::string("\n") ) { str = str.substr( 0, str.length() - 1 ); } return replace( str, std::string("\n"), std::string("\n") + prefix ); } static std::string bytes_to_string( std::uint64_t bytes ) { static const char * const suffixes[] = { "B", "kB", "MB", "GB", "TB", "PB" }; int offset = 0; while ( bytes > 9999 ) { bytes /= 1000; offset += 1; if ( offset == 5 ) { break; } } std::ostringstream result; result << bytes << suffixes[offset]; return result.str(); } static std::string seconds_to_string( double time ) { std::int64_t time_ms = static_cast( time * 1000 ); std::int64_t milliseconds = time_ms % 1000; std::int64_t seconds = ( time_ms / 1000 ) % 60; std::int64_t minutes = ( time_ms / ( 1000 * 60 ) ) % 60; std::int64_t hours = ( time_ms / ( 1000 * 60 * 60 ) ); std::ostringstream str; if ( hours > 0 ) { str << hours << ":"; } str << std::setfill('0') << std::setw(2) << minutes; str << ":"; str << std::setfill('0') << std::setw(2) << seconds; str << "."; str << std::setfill('0') << std::setw(3) << milliseconds; return str.str(); } static void show_info( std::ostream & log, bool verbose ) { log << "openmpt123" << " v" << OPENMPT123_VERSION_STRING << ", libopenmpt " << openmpt::string::get( "library_version" ) << " (" << "OpenMPT " << openmpt::string::get( "core_version" ) << ")" << std::endl; log << "Copyright (c) 2013-2018 OpenMPT developers " << std::endl; if ( !verbose ) { log << std::endl; return; } log << " libopenmpt source..: " << openmpt::string::get( "source_url" ) << std::endl; log << " libopenmpt date....: " << openmpt::string::get( "source_date" ) << std::endl; log << " libopenmpt srcinfo.: "; { std::vector fields; if ( openmpt::string::get( "source_is_package" ) == "1" ) { fields.push_back( "package" ); } if ( openmpt::string::get( "source_is_release" ) == "1" ) { fields.push_back( "release" ); } if ( ( !openmpt::string::get( "source_revision" ).empty() ) && ( openmpt::string::get( "source_revision" ) != "0" ) ) { std::string field = "rev" + openmpt::string::get( "source_revision" ); if ( openmpt::string::get( "source_has_mixed_revisions" ) == "1" ) { field += "+mixed"; } if ( openmpt::string::get( "source_is_modified" ) == "1" ) { field += "+modified"; } fields.push_back( field ); } bool first = true; for ( std::vector::const_iterator it = fields.begin(); it != fields.end(); ++it ) { if ( first ) { first = false; } else { log << ", "; } log << (*it); } } log << std::endl; log << " libopenmpt compiler: " << openmpt::string::get( "build_compiler" ) << std::endl; log << " libopenmpt features: " << openmpt::string::get( "library_features" ) << std::endl; #ifdef MPT_WITH_SDL2 log << " libSDL2 "; SDL_version sdlver; std::memset( &sdlver, 0, sizeof( SDL_version ) ); SDL_GetVersion( &sdlver ); log << static_cast( sdlver.major ) << "." << static_cast( sdlver.minor ) << "." << static_cast( sdlver.patch ) << "." << SDL_GetRevisionNumber(); const char * revision = SDL_GetRevision(); if ( revision ) { log << " (" << revision << ")"; } log << ", "; std::memset( &sdlver, 0, sizeof( SDL_version ) ); SDL_VERSION( &sdlver ); log << "API: " << static_cast( sdlver.major ) << "." << static_cast( sdlver.minor ) << "." << static_cast( sdlver.patch ) << ""; log << " " << std::endl; #endif #ifdef MPT_WITH_SDL const SDL_version * linked_sdlver = SDL_Linked_Version(); log << " libSDL "; if ( linked_sdlver ) { log << static_cast( linked_sdlver->major ) << "." << static_cast( linked_sdlver->minor ) << "." << static_cast( linked_sdlver->patch ) << " "; } SDL_version sdlver; std::memset( &sdlver, 0, sizeof( SDL_version ) ); SDL_VERSION( &sdlver ); log << "(API: " << static_cast( sdlver.major ) << "." << static_cast( sdlver.minor ) << "." << static_cast( sdlver.patch ) << ")"; log << " " << std::endl; #endif #ifdef MPT_WITH_PULSEAUDIO log << " " << "libpulse, libpulse-simple" << " (headers " << pa_get_headers_version() << ", API " << PA_API_VERSION << ", PROTOCOL " << PA_PROTOCOL_VERSION << ", library " << ( pa_get_library_version() ? pa_get_library_version() : "unknown" ) << ") " << std::endl; #endif #ifdef MPT_WITH_PORTAUDIO log << " " << Pa_GetVersionText() << " (" << Pa_GetVersion() << ") " << std::endl; #endif #ifdef MPT_WITH_FLAC log << " FLAC " << FLAC__VERSION_STRING << ", " << FLAC__VENDOR_STRING << ", API " << FLAC_API_VERSION_CURRENT << "." << FLAC_API_VERSION_REVISION << "." << FLAC_API_VERSION_AGE << " " << std::endl; #endif #ifdef MPT_WITH_SNDFILE char sndfile_info[128]; std::memset( sndfile_info, 0, sizeof( sndfile_info ) ); sf_command( 0, SFC_GET_LIB_VERSION, sndfile_info, sizeof( sndfile_info ) ); sndfile_info[127] = '\0'; log << " libsndfile " << sndfile_info << " " << std::endl; #endif log << std::endl; } static void show_man_version( textout & log ) { log << "openmpt123" << " v" << OPENMPT123_VERSION_STRING << std::endl; log << std::endl; log << "Copyright (c) 2013-2018 OpenMPT developers " << std::endl; } static void show_short_version( textout & log ) { log << OPENMPT123_VERSION_STRING << " / " << openmpt::string::get( "library_version" ) << " / " << openmpt::string::get( "core_version" ) << std::endl; log.writeout(); } static void show_version( textout & log ) { show_info( log, false ); log.writeout(); } static void show_long_version( textout & log ) { show_info( log, true ); log.writeout(); } static void show_credits( textout & log ) { show_info( log, false ); log << openmpt::string::get( "contact" ) << std::endl; log << std::endl; log << openmpt::string::get( "credits" ) << std::endl; log.writeout(); } static void show_license( textout & log ) { show_info( log, false ); log << license << std::endl; log.writeout(); } static std::string get_driver_string( const std::string & driver ) { if ( driver.empty() ) { return "default"; } return driver; } static std::string get_device_string( const std::string & device ) { if ( device.empty() ) { return "default"; } return device; } static void show_help( textout & log, bool with_info = true, bool longhelp = false, bool man_version = false, const std::string & message = std::string() ) { if ( with_info ) { show_info( log, false ); } { log << "Usage: openmpt123 [options] [--] file1 [file2] ..." << std::endl; log << std::endl; if ( man_version ) { log << "openmpt123 plays module music files." << std::endl; log << std::endl; } if ( man_version ) { log << "Options:" << std::endl; } log << " -h, --help Show help" << std::endl; log << " --help-keyboard Show keyboard hotkeys in ui mode" << std::endl; log << " -q, --quiet Suppress non-error screen output" << std::endl; log << " -v, --verbose Show more screen output" << std::endl; log << " --version Show version information and exit" << std::endl; log << " --short-version Show version number and nothing else" << std::endl; log << " --long-version Show long version information and exit" << std::endl; log << " --credits Show elaborate contributors list" << std::endl; log << " --license Show license" << std::endl; log << std::endl; log << " --probe Probe each file whether it is a supported file format" << std::endl; log << " --info Display information about each file" << std::endl; log << " --ui Interactively play each file" << std::endl; log << " --batch Play each file" << std::endl; log << " --render Render each file to individual PCM data files" << std::endl; if ( !longhelp ) { log << std::endl; log.writeout(); return; } log << std::endl; log << " --terminal-width n Assume terminal is n characters wide [default: " << commandlineflags().terminal_width << "]" << std::endl; log << " --terminal-height n Assume terminal is n characters high [default: " << commandlineflags().terminal_height << "]" << std::endl; log << std::endl; log << " --[no-]progress Show playback progress [default: " << commandlineflags().show_progress << "]" << std::endl; log << " --[no-]meters Show peak meters [default: " << commandlineflags().show_meters << "]" << std::endl; log << " --[no-]channel-meters Show channel peak meters (EXPERIMENTAL) [default: " << commandlineflags().show_channel_meters << "]" << std::endl; log << " --[no-]pattern Show pattern (EXPERIMENTAL) [default: " << commandlineflags().show_pattern << "]" << std::endl; log << std::endl; log << " --[no-]details Show song details [default: " << commandlineflags().show_details << "]" << std::endl; log << " --[no-]message Show song message [default: " << commandlineflags().show_message << "]" << std::endl; log << std::endl; log << " --update n Set output update interval to n ms [default: " << commandlineflags().ui_redraw_interval << "]" << std::endl; log << std::endl; log << " --samplerate n Set samplerate to n Hz [default: " << commandlineflags().samplerate << "]" << std::endl; log << " --channels n use n [1,2,4] output channels [default: " << commandlineflags().channels << "]" << std::endl; log << " --[no-]float Output 32bit floating point instead of 16bit integer [default: " << commandlineflags().use_float << "]" << std::endl; log << std::endl; log << " --gain n Set output gain to n dB [default: " << commandlineflags().gain / 100.0 << "]" << std::endl; log << " --stereo n Set stereo separation to n % [default: " << commandlineflags().separation << "]" << std::endl; log << " --filter n Set interpolation filter taps to n [1,2,4,8] [default: " << commandlineflags().filtertaps << "]" << std::endl; log << " --ramping n Set volume ramping strength n [0..5] [default: " << commandlineflags().ramping << "]" << std::endl; log << " --tempo f Set tempo factor f [default: " << tempo_flag_to_double( commandlineflags().tempo ) << "]" << std::endl; log << " --pitch f Set pitch factor f [default: " << pitch_flag_to_double( commandlineflags().pitch ) << "]" << std::endl; log << " --dither n Dither type to use (if applicable for selected output format): [0=off,1=auto,2=0.5bit,3=1bit] [default: " << commandlineflags().dither << "]" << std::endl; log << std::endl; log << " --playlist file Load playlist from file" << std::endl; log << " --[no-]randomize Randomize playlist [default: " << commandlineflags().randomize << "]" << std::endl; log << " --[no-]shuffle Shuffle through playlist [default: " << commandlineflags().shuffle << "]" << std::endl; log << " --[no-]restart Restart playlist when finished [default: " << commandlineflags().restart << "]" << std::endl; log << std::endl; log << " --subsong n Select subsong n (-1 means play all subsongs consecutively) [default: " << commandlineflags().subsong << "]" << std::endl; log << " --repeat n Repeat song n times (-1 means forever) [default: " << commandlineflags().repeatcount << "]" << std::endl; log << " --seek n Seek to n seconds on start [default: " << commandlineflags().seek_target << "]" << std::endl; log << " --end-time n Play until position is n seconds (0 means until the end) [default: " << commandlineflags().end_time << "]" << std::endl; log << std::endl; log << " --ctl c=v Set libopenmpt ctl c to value v" << std::endl; log << std::endl; log << " --driver n Set output driver [default: " << get_driver_string( commandlineflags().driver ) << "]," << std::endl; log << " --device n Set output device [default: " << get_device_string( commandlineflags().device ) << "]," << std::endl; log << " use --device help to show available devices" << std::endl; log << " --buffer n Set output buffer size to n ms [default: " << commandlineflags().buffer << "]" << std::endl; log << " --period n Set output period size to n ms [default: " << commandlineflags().period << "]" << std::endl; log << " --stdout Write raw audio data to stdout [default: " << commandlineflags().use_stdout << "]" << std::endl; log << " --output-type t Use output format t when writing to a individual PCM files (only applies to --render mode) [default: " << commandlineflags().output_extension << "]" << std::endl; log << " -o, --output f Write PCM output to file f instead of streaming to audio device (only applies to --ui and --batch modes) [default: " << commandlineflags().output_filename << "]" << std::endl; log << " --force Force overwriting of output file [default: " << commandlineflags().force_overwrite << "]" << std::endl; log << std::endl; log << " -- Interpret further arguments as filenames" << std::endl; log << std::endl; if ( !man_version ) { log << " Supported file formats: " << std::endl; log << " "; std::vector extensions = openmpt::get_supported_extensions(); bool first = true; for ( std::vector::iterator i = extensions.begin(); i != extensions.end(); ++i ) { if ( first ) { first = false; } else { log << ", "; } log << *i; } log << std::endl; } } log << std::endl; if ( message.size() > 0 ) { log << message; log << std::endl; } log.writeout(); } static void show_help_keyboard( textout & log ) { show_info( log, false ); log << "Keyboard hotkeys (use 'openmpt123 --ui'):" << std::endl; log << std::endl; log << " [q] quit" << std::endl; log << " [ ] pause / unpause" << std::endl; log << " [N] skip 10 files backward" << std::endl; log << " [n] prev file" << std::endl; log << " [m] next file" << std::endl; log << " [M] skip 10 files forward" << std::endl; log << " [h] seek 10 seconds backward" << std::endl; log << " [j] seek 1 seconds backward" << std::endl; log << " [k] seek 1 seconds forward" << std::endl; log << " [l] seek 10 seconds forward" << std::endl; log << " [u]|[i] +/- tempo" << std::endl; log << " [o]|[p] +/- pitch" << std::endl; log << " [3]|[4] +/- gain" << std::endl; log << " [5]|[6] +/- stereo separation" << std::endl; log << " [7]|[8] +/- filter taps" << std::endl; log << " [9]|[0] +/- volume ramping" << std::endl; log << std::endl; log.writeout(); } template < typename T, typename Tmod > T ctl_get( Tmod & mod, const std::string & ctl ) { T result = T(); try { std::istringstream str; str.imbue( std::locale::classic() ); str.str( mod.ctl_get( ctl ) ); str >> std::fixed >> std::setprecision(16) >> result; } catch ( const openmpt::exception & ) { // ignore } return result; } template < typename T, typename Tmod > void ctl_set( Tmod & mod, const std::string & ctl, const T & val ) { try { std::ostringstream str; str.imbue( std::locale::classic() ); str << std::fixed << std::setprecision(16) << val; mod.ctl_set( ctl, str.str() ); } catch ( const openmpt::exception & ) { // ignore } return; } template < typename Tmod > static void apply_mod_settings( commandlineflags & flags, Tmod & mod ) { flags.separation = std::max( flags.separation, 0 ); flags.filtertaps = std::max( flags.filtertaps, 1 ); flags.filtertaps = std::min( flags.filtertaps, 8 ); flags.ramping = std::max( flags.ramping, -1 ); flags.ramping = std::min( flags.ramping, 10 ); flags.tempo = std::max( flags.tempo, -48 ); flags.tempo = std::min( flags.tempo, 48 ); flags.pitch = std::max( flags.pitch, -48 ); flags.pitch = std::min( flags.pitch, 48 ); mod.set_render_param( openmpt::module::RENDER_MASTERGAIN_MILLIBEL, flags.gain ); mod.set_render_param( openmpt::module::RENDER_STEREOSEPARATION_PERCENT, flags.separation ); mod.set_render_param( openmpt::module::RENDER_INTERPOLATIONFILTER_LENGTH, flags.filtertaps ); mod.set_render_param( openmpt::module::RENDER_VOLUMERAMPING_STRENGTH, flags.ramping ); ctl_set( mod, "play.tempo_factor", tempo_flag_to_double( flags.tempo ) ); ctl_set( mod, "play.pitch_factor", pitch_flag_to_double( flags.pitch ) ); std::ostringstream dither_str; dither_str.imbue( std::locale::classic() ); dither_str << flags.dither; mod.ctl_set( "dither", dither_str.str() ); } struct prev_file { int count; prev_file( int c ) : count(c) { } }; struct next_file { int count; next_file( int c ) : count(c) { } }; template < typename Tmod > static bool handle_keypress( int c, commandlineflags & flags, Tmod & mod, write_buffers_interface & audio_stream ) { switch ( c ) { case 'q': throw silent_exit_exception(); break; case 'N': throw prev_file(10); break; case 'n': throw prev_file(1); break; case ' ': if ( !flags.paused ) { flags.paused = audio_stream.pause(); } else { flags.paused = false; audio_stream.unpause(); } break; case 'h': mod.set_position_seconds( mod.get_position_seconds() - 10.0 ); break; case 'j': mod.set_position_seconds( mod.get_position_seconds() - 1.0 ); break; case 'k': mod.set_position_seconds( mod.get_position_seconds() + 1.0 ); break; case 'l': mod.set_position_seconds( mod.get_position_seconds() + 10.0 ); break; case 'H': mod.set_position_order_row( mod.get_current_order() - 1, 0 ); break; case 'J': mod.set_position_order_row( mod.get_current_order(), mod.get_current_row() - 1 ); break; case 'K': mod.set_position_order_row( mod.get_current_order(), mod.get_current_row() + 1 ); break; case 'L': mod.set_position_order_row( mod.get_current_order() + 1, 0 ); break; case 'm': throw next_file(1); break; case 'M': throw next_file(10); break; case 'u': flags.tempo -= 1; apply_mod_settings( flags, mod ); break; case 'i': flags.tempo += 1; apply_mod_settings( flags, mod ); break; case 'o': flags.pitch -= 1; apply_mod_settings( flags, mod ); break; case 'p': flags.pitch += 1; apply_mod_settings( flags, mod ); break; case '3': flags.gain -=100; apply_mod_settings( flags, mod ); break; case '4': flags.gain +=100; apply_mod_settings( flags, mod ); break; case '5': flags.separation -= 5; apply_mod_settings( flags, mod ); break; case '6': flags.separation += 5; apply_mod_settings( flags, mod ); break; case '7': flags.filtertaps /= 2; apply_mod_settings( flags, mod ); break; case '8': flags.filtertaps *= 2; apply_mod_settings( flags, mod ); break; case '9': flags.ramping -= 1; apply_mod_settings( flags, mod ); break; case '0': flags.ramping += 1; apply_mod_settings( flags, mod ); break; } return true; } struct meter_channel { float peak; float clip; float hold; float hold_age; meter_channel() : peak(0.0f) , clip(0.0f) , hold(0.0f) , hold_age(0.0f) { return; } }; struct meter_type { meter_channel channels[4]; }; static const float falloff_rate = 20.0f / 1.7f; static void update_meter( meter_type & meter, const commandlineflags & flags, std::size_t count, const std::int16_t * const * buffers ) { float falloff_factor = std::pow( 10.0f, -falloff_rate / flags.samplerate / 20.0f ); for ( int channel = 0; channel < flags.channels; ++channel ) { meter.channels[channel].peak = 0.0f; for ( std::size_t frame = 0; frame < count; ++frame ) { if ( meter.channels[channel].clip != 0.0f ) { meter.channels[channel].clip -= ( 1.0f / 2.0f ) * 1.0f / static_cast( flags.samplerate ); if ( meter.channels[channel].clip <= 0.0f ) { meter.channels[channel].clip = 0.0f; } } float val = std::fabs( buffers[channel][frame] / 32768.0f ); if ( val >= 1.0f ) { meter.channels[channel].clip = 1.0f; } if ( val > meter.channels[channel].peak ) { meter.channels[channel].peak = val; } meter.channels[channel].hold *= falloff_factor; if ( val > meter.channels[channel].hold ) { meter.channels[channel].hold = val; meter.channels[channel].hold_age = 0.0f; } else { meter.channels[channel].hold_age += 1.0f / static_cast( flags.samplerate ); } } } } static void update_meter( meter_type & meter, const commandlineflags & flags, std::size_t count, const float * const * buffers ) { float falloff_factor = std::pow( 10.0f, -falloff_rate / flags.samplerate / 20.0f ); for ( int channel = 0; channel < flags.channels; ++channel ) { if ( !count ) { meter = meter_type(); } meter.channels[channel].peak = 0.0f; for ( std::size_t frame = 0; frame < count; ++frame ) { if ( meter.channels[channel].clip != 0.0f ) { meter.channels[channel].clip -= ( 1.0f / 2.0f ) * 1.0f / static_cast( flags.samplerate ); if ( meter.channels[channel].clip <= 0.0f ) { meter.channels[channel].clip = 0.0f; } } float val = std::fabs( buffers[channel][frame] ); if ( val >= 1.0f ) { meter.channels[channel].clip = 1.0f; } if ( val > meter.channels[channel].peak ) { meter.channels[channel].peak = val; } meter.channels[channel].hold *= falloff_factor; if ( val > meter.channels[channel].hold ) { meter.channels[channel].hold = val; meter.channels[channel].hold_age = 0.0f; } else { meter.channels[channel].hold_age += 1.0f / static_cast( flags.samplerate ); } } } } static const char * const channel_tags[4][4] = { { " C", " ", " ", " " }, { " L", " R", " ", " " }, { "FL", "FR", "RC", " " }, { "FL", "FR", "RL", "RR" }, }; static std::string channel_to_string( int channels, int channel, const meter_channel & meter, bool tiny = false ) { float db = 20.0f * std::log10( meter.peak ); float db_hold = 20.0f * std::log10( meter.hold ); int val = static_cast( db + 48.0f ); int hold_pos = static_cast( db_hold + 48.0f ); if ( val < 0 ) { val = 0; } int headroom = val; if ( val > 48 ) { val = 48; } headroom -= val; if ( headroom < 0 ) { headroom = 0; } if ( headroom > 12 ) { headroom = 12; } headroom -= 1; // clip indicator if ( headroom < 0 ) { headroom = 0; } if ( tiny ) { if ( meter.clip != 0.0f || db >= 0.0f ) { return "#"; } else if ( db > -6.0f ) { return "O"; } else if ( db > -12.0f ) { return "o"; } else if ( db > -18.0f ) { return "."; } else { return " "; } } else { std::ostringstream res1; std::ostringstream res2; res1 << " " << channel_tags[channels-1][channel] << " : " ; res2 << std::string(val,'>') << std::string(48-val,' ') << ( ( meter.clip != 0.0f ) ? "#" : ":" ) << std::string(headroom,'>') << std::string(12-headroom,' ') ; std::string tmp = res2.str(); if ( 0 <= hold_pos && hold_pos <= 60 ) { if ( hold_pos == 48 ) { tmp[hold_pos] = '#'; } else { tmp[hold_pos] = ':'; } } return res1.str() + tmp; } } static char peak_to_char( float peak ) { if ( peak >= 1.0f ) { return '#'; } else if ( peak >= 0.5f ) { return 'O'; } else if ( peak >= 0.25f ) { return 'o'; } else if ( peak >= 0.125f ) { return '.'; } else { return ' '; } } static std::string peak_to_string_left( float peak, int width ) { std::string result; float thresh = 1.0f; while ( width-- ) { if ( peak >= thresh ) { if ( thresh == 1.0f ) { result.push_back( '#' ); } else { result.push_back( '<' ); } } else { result.push_back( ' ' ); } thresh *= 0.5f; } return result; } static std::string peak_to_string_right( float peak, int width ) { std::string result; float thresh = 1.0f; while ( width-- ) { if ( peak >= thresh ) { if ( thresh == 1.0f ) { result.push_back( '#' ); } else { result.push_back( '>' ); } } else { result.push_back( ' ' ); } thresh *= 0.5f; } std::reverse( result.begin(), result.end() ); return result; } static void draw_meters( std::ostream & log, const meter_type & meter, const commandlineflags & flags ) { for ( int channel = 0; channel < flags.channels; ++channel ) { log << channel_to_string( flags.channels, channel, meter.channels[channel] ) << std::endl; } } static void draw_meters_tiny( std::ostream & log, const meter_type & meter, const commandlineflags & flags ) { for ( int channel = 0; channel < flags.channels; ++channel ) { log << channel_to_string( flags.channels, channel, meter.channels[channel], true ); } } static void draw_channel_meters_tiny( std::ostream & log, float peak ) { log << peak_to_char( peak ); } static void draw_channel_meters_tiny( std::ostream & log, float peak_left, float peak_right ) { log << peak_to_char( peak_left ) << peak_to_char( peak_right ); } static void draw_channel_meters( std::ostream & log, float peak_left, float peak_right, int width ) { if ( width >= 8 + 1 + 8 ) { width = 8 + 1 + 8; } log << peak_to_string_left( peak_left, width / 2 ) << ( width % 2 == 1 ? ":" : "" ) << peak_to_string_right( peak_right, width / 2 ); } template < typename Tsample, typename Tmod > void render_loop( commandlineflags & flags, Tmod & mod, double & duration, textout & log, write_buffers_interface & audio_stream ) { log.writeout(); std::size_t bufsize; if ( flags.mode == ModeUI ) { bufsize = std::min( flags.ui_redraw_interval, flags.period ) * flags.samplerate / 1000; } else if ( flags.mode == ModeBatch ) { bufsize = flags.period * flags.samplerate / 1000; } else { bufsize = 1024; } std::int64_t last_redraw_frame = 0 - flags.ui_redraw_interval; std::int64_t rendered_frames = 0; std::vector left( bufsize ); std::vector right( bufsize ); std::vector rear_left( bufsize ); std::vector rear_right( bufsize ); std::vector buffers( 4 ) ; buffers[0] = left.data(); buffers[1] = right.data(); buffers[2] = rear_left.data(); buffers[3] = rear_right.data(); buffers.resize( flags.channels ); meter_type meter; const bool multiline = flags.show_ui; int lines = 0; int pattern_lines = 0; if ( multiline ) { lines += 1; if ( flags.show_ui ) { lines += 1; } if ( flags.show_meters ) { for ( int channel = 0; channel < flags.channels; ++channel ) { lines += 1; } } if ( flags.show_channel_meters ) { lines += 1; } if ( flags.show_details ) { lines += 1; if ( flags.show_progress ) { lines += 1; } } if ( flags.show_progress ) { lines += 1; } if ( flags.show_pattern ) { pattern_lines = flags.terminal_height - lines - 1; lines = flags.terminal_height - 1; } } else if ( flags.show_ui || flags.show_details || flags.show_progress ) { log << std::endl; } for ( int line = 0; line < lines; ++line ) { log << std::endl; } log.writeout(); #if defined( WIN32 ) HANDLE hStdErr = NULL; COORD coord_cursor = COORD(); if ( multiline ) { log.flush(); hStdErr = GetStdHandle( STD_ERROR_HANDLE ); if ( hStdErr ) { CONSOLE_SCREEN_BUFFER_INFO csbi; ZeroMemory( &csbi, sizeof( CONSOLE_SCREEN_BUFFER_INFO ) ); GetConsoleScreenBufferInfo( hStdErr, &csbi ); coord_cursor = csbi.dwCursorPosition; coord_cursor.X = 1; coord_cursor.Y -= lines; } } #endif double cpu_smooth = 0.0; while ( true ) { if ( flags.mode == ModeUI ) { #if defined( WIN32 ) while ( _kbhit() ) { int c = _getch(); if ( !handle_keypress( c, flags, mod, audio_stream ) ) { return; } } #else while ( true ) { pollfd pollfds; pollfds.fd = STDIN_FILENO; pollfds.events = POLLIN; poll(&pollfds, 1, 0); if ( !( pollfds.revents & POLLIN ) ) { break; } char c = 0; if ( read( STDIN_FILENO, &c, 1 ) != 1 ) { break; } if ( !handle_keypress( c, flags, mod, audio_stream ) ) { return; } } #endif if ( flags.paused ) { audio_stream.sleep( flags.ui_redraw_interval ); continue; } } std::clock_t cpu_beg = 0; std::clock_t cpu_end = 0; if ( flags.show_details ) { cpu_beg = std::clock(); } std::size_t count = 0; switch ( flags.channels ) { case 1: count = mod.read( flags.samplerate, bufsize, left.data() ); break; case 2: count = mod.read( flags.samplerate, bufsize, left.data(), right.data() ); break; case 4: count = mod.read( flags.samplerate, bufsize, left.data(), right.data(), rear_left.data(), rear_right.data() ); break; } char cpu_str[64] = ""; if ( flags.show_details ) { cpu_end = std::clock(); if ( count > 0 ) { double cpu = 1.0; cpu *= ( static_cast( cpu_end ) - static_cast( cpu_beg ) ) / static_cast( CLOCKS_PER_SEC ); cpu /= ( static_cast( count ) ) / static_cast( flags.samplerate ); double mix = ( static_cast( count ) ) / static_cast( flags.samplerate ); cpu_smooth = ( 1.0 - mix ) * cpu_smooth + mix * cpu; sprintf( cpu_str, "%.2f%%", cpu_smooth * 100.0 ); } } if ( flags.show_meters ) { update_meter( meter, flags, count, buffers.data() ); } if ( count > 0 ) { audio_stream.write( buffers, count ); } if ( count > 0 ) { rendered_frames += count; if ( rendered_frames >= last_redraw_frame + ( flags.ui_redraw_interval * flags.samplerate / 1000 ) ) { last_redraw_frame = rendered_frames; } else { continue; } } if ( multiline ) { #if defined( WIN32 ) log.flush(); if ( hStdErr ) { SetConsoleCursorPosition( hStdErr, coord_cursor ); } #else for ( int line = 0; line < lines; ++line ) { log << "\x1b[1A"; } #endif log << std::endl; if ( flags.show_meters ) { draw_meters( log, meter, flags ); } if ( flags.show_channel_meters ) { int width = ( flags.terminal_width - 3 ) / mod.get_num_channels(); if ( width > 11 ) { width = 11; } log << " "; for ( std::int32_t channel = 0; channel < mod.get_num_channels(); ++channel ) { if ( width >= 3 ) { log << ":"; } if ( width == 1 ) { draw_channel_meters_tiny( log, ( mod.get_current_channel_vu_left( channel ) + mod.get_current_channel_vu_right( channel ) ) * (1.0f/std::sqrt(2.0f)) ); } else if ( width <= 4 ) { draw_channel_meters_tiny( log, mod.get_current_channel_vu_left( channel ), mod.get_current_channel_vu_right( channel ) ); } else { draw_channel_meters( log, mod.get_current_channel_vu_left( channel ), mod.get_current_channel_vu_right( channel ), width - 1 ); } } if ( width >= 3 ) { log << ":"; } log << std::endl; } if ( flags.show_pattern ) { int width = ( flags.terminal_width - 3 ) / mod.get_num_channels(); if ( width > 13 + 1 ) { width = 13 + 1; } for ( std::int32_t line = 0; line < pattern_lines; ++line ) { std::int32_t row = mod.get_current_row() - ( pattern_lines / 2 ) + line; if ( row == mod.get_current_row() ) { log << ">"; } else { log << " "; } if ( row < 0 || row >= mod.get_pattern_num_rows( mod.get_current_pattern() ) ) { for ( std::int32_t channel = 0; channel < mod.get_num_channels(); ++channel ) { if ( width >= 3 ) { log << ":"; } log << std::string( width >= 3 ? width - 1 : width, ' ' ); } } else { for ( std::int32_t channel = 0; channel < mod.get_num_channels(); ++channel ) { if ( width >= 3 ) { if ( row == mod.get_current_row() ) { log << "+"; } else { log << ":"; } } log << mod.format_pattern_row_channel( mod.get_current_pattern(), row, channel, width >= 3 ? width - 1 : width ); } } if ( width >= 3 ) { log << ":"; } log << std::endl; } } if ( flags.show_ui ) { log << "Settings...: "; log << "Gain: " << flags.gain * 0.01f << " dB" << " "; log << "Stereo: " << flags.separation << " %" << " "; log << "Filter: " << flags.filtertaps << " taps" << " "; log << "Ramping: " << flags.ramping << " "; log << std::endl; } if ( flags.show_details ) { log << "Mixer......: "; log << "CPU:" << std::setw(6) << std::setfill(':') << cpu_str; log << " "; log << "Chn:" << std::setw(3) << std::setfill(':') << mod.get_current_playing_channels(); log << " "; log << std::endl; if ( flags.show_progress ) { log << "Player.....: "; log << "Ord:" << std::setw(3) << std::setfill(':') << mod.get_current_order() << "/" << std::setw(3) << std::setfill(':') << mod.get_num_orders(); log << " "; log << "Pat:" << std::setw(3) << std::setfill(':') << mod.get_current_pattern(); log << " "; log << "Row:" << std::setw(3) << std::setfill(':') << mod.get_current_row(); log << " "; log << "Spd:" << std::setw(2) << std::setfill(':') << mod.get_current_speed(); log << " "; log << "Tmp:" << std::setw(3) << std::setfill(':') << mod.get_current_tempo(); log << " "; log << std::endl; } } if ( flags.show_progress ) { log << "Position...: " << seconds_to_string( mod.get_position_seconds() ) << " / " << seconds_to_string( duration ) << " " << std::endl; } } else if ( flags.show_channel_meters ) { if ( flags.show_ui || flags.show_details || flags.show_progress ) { int width = ( flags.terminal_width - 3 ) / mod.get_num_channels(); log << " "; for ( std::int32_t channel = 0; channel < mod.get_num_channels(); ++channel ) { if ( width >= 3 ) { log << ":"; } if ( width == 1 ) { draw_channel_meters_tiny( log, ( mod.get_current_channel_vu_left( channel ) + mod.get_current_channel_vu_right( channel ) ) * (1.0f/std::sqrt(2.0f)) ); } else if ( width <= 4 ) { draw_channel_meters_tiny( log, mod.get_current_channel_vu_left( channel ), mod.get_current_channel_vu_right( channel ) ); } else { draw_channel_meters( log, mod.get_current_channel_vu_left( channel ), mod.get_current_channel_vu_right( channel ), width - 1 ); } } if ( width >= 3 ) { log << ":"; } } log << " " << "\r"; } else { if ( flags.show_ui ) { log << " "; log << std::setw(3) << std::setfill(':') << flags.gain * 0.01f << "dB"; log << "|"; log << std::setw(3) << std::setfill(':') << flags.separation << "%"; log << "|"; log << std::setw(2) << std::setfill(':') << flags.filtertaps << "taps"; log << "|"; log << std::setw(3) << std::setfill(':') << flags.ramping; } if ( flags.show_meters ) { log << " "; draw_meters_tiny( log, meter, flags ); } if ( flags.show_details && flags.show_ui ) { log << " "; log << "CPU:" << std::setw(6) << std::setfill(':') << cpu_str; log << "|"; log << "Chn:" << std::setw(3) << std::setfill(':') << mod.get_current_playing_channels(); } if ( flags.show_details && !flags.show_ui ) { if ( flags.show_progress ) { log << " "; log << "Ord:" << std::setw(3) << std::setfill(':') << mod.get_current_order() << "/" << std::setw(3) << std::setfill(':') << mod.get_num_orders(); log << "|"; log << "Pat:" << std::setw(3) << std::setfill(':') << mod.get_current_pattern(); log << "|"; log << "Row:" << std::setw(3) << std::setfill(':') << mod.get_current_row(); log << " "; log << "Spd:" << std::setw(2) << std::setfill(':') << mod.get_current_speed(); log << "|"; log << "Tmp:" << std::setw(3) << std::setfill(':') << mod.get_current_tempo(); } } if ( flags.show_progress ) { log << " "; log << seconds_to_string( mod.get_position_seconds() ); log << "/"; log << seconds_to_string( duration ); } if ( flags.show_ui || flags.show_details || flags.show_progress ) { log << " " << "\r"; } } log.writeout(); if ( count == 0 ) { break; } if ( flags.end_time > 0 && mod.get_position_seconds() >= flags.end_time ) { break; } } log.writeout(); } template < typename Tmod > std::map get_metadata( const Tmod & mod ) { std::map result; const std::vector metadata_keys = mod.get_metadata_keys(); for ( std::vector::const_iterator key = metadata_keys.begin(); key != metadata_keys.end(); ++key ) { result[ *key ] = mod.get_metadata( *key ); } return result; } class set_field : private std::ostringstream { private: std::vector & fields; public: set_field( std::vector & fields, const std::string & name ) : fields(fields) { fields.push_back( name ); } std::ostream & ostream() { return *this; } ~set_field() { fields.back().val = str(); } }; static void show_fields( textout & log, const std::vector & fields ) { const std::size_t fw = 11; for ( std::vector::const_iterator it = fields.begin(); it != fields.end(); ++it ) { std::string key = it->key; std::string val = it->val; if ( key.length() < fw ) { key += std::string( fw - key.length(), '.' ); } if ( key.length() > fw ) { key = key.substr( 0, fw ); } key += ": "; val = prepend_lines( val, std::string( fw, ' ' ) + ": " ); log << key << val << std::endl; } } static void probe_mod_file( commandlineflags & flags, const std::string & filename, std::uint64_t filesize, std::istream & data_stream, textout & log ) { log.writeout(); std::vector fields; if ( flags.filenames.size() > 1 ) { set_field( fields, "Playlist" ).ostream() << flags.playlist_index + 1 << "/" << flags.filenames.size(); set_field( fields, "Prev/Next" ).ostream() << "'" << ( flags.playlist_index > 0 ? get_filename( flags.filenames[ flags.playlist_index - 1 ] ) : std::string() ) << "'" << " / " << "['" << get_filename( filename ) << "']" << " / " << "'" << ( flags.playlist_index + 1 < flags.filenames.size() ? get_filename( flags.filenames[ flags.playlist_index + 1 ] ) : std::string() ) << "'" ; } if ( flags.verbose ) { set_field( fields, "Path" ).ostream() << filename; } if ( flags.show_details ) { set_field( fields, "Filename" ).ostream() << get_filename( filename ); set_field( fields, "Size" ).ostream() << bytes_to_string( filesize ); } int probe_result = openmpt::probe_file_header( openmpt::probe_file_header_flags_default, data_stream ); std::string probe_result_string; switch ( probe_result ) { case openmpt::probe_file_header_result_success: probe_result_string = "Success"; break; case openmpt::probe_file_header_result_failure: probe_result_string = "Failure"; break; case openmpt::probe_file_header_result_wantmoredata: probe_result_string = "Insufficient Data"; break; default: probe_result_string = "Internal Error"; break; } set_field( fields, "Probe" ).ostream() << probe_result_string; show_fields( log, fields ); log.writeout(); } template < typename Tmod > void render_mod_file( commandlineflags & flags, const std::string & filename, std::uint64_t filesize, Tmod & mod, textout & log, write_buffers_interface & audio_stream ) { log.writeout(); if ( flags.mode != ModeProbe && flags.mode != ModeInfo ) { mod.set_repeat_count( flags.repeatcount ); apply_mod_settings( flags, mod ); } double duration = mod.get_duration_seconds(); std::vector fields; if ( flags.filenames.size() > 1 ) { set_field( fields, "Playlist" ).ostream() << flags.playlist_index + 1 << "/" << flags.filenames.size(); set_field( fields, "Prev/Next" ).ostream() << "'" << ( flags.playlist_index > 0 ? get_filename( flags.filenames[ flags.playlist_index - 1 ] ) : std::string() ) << "'" << " / " << "['" << get_filename( filename ) << "']" << " / " << "'" << ( flags.playlist_index + 1 < flags.filenames.size() ? get_filename( flags.filenames[ flags.playlist_index + 1 ] ) : std::string() ) << "'" ; } if ( flags.verbose ) { set_field( fields, "Path" ).ostream() << filename; } if ( flags.show_details ) { set_field( fields, "Filename" ).ostream() << get_filename( filename ); set_field( fields, "Size" ).ostream() << bytes_to_string( filesize ); if ( !mod.get_metadata( "warnings" ).empty() ) { set_field( fields, "Warnings" ).ostream() << mod.get_metadata( "warnings" ); } if ( !mod.get_metadata( "container" ).empty() ) { set_field( fields, "Container" ).ostream() << mod.get_metadata( "container" ) << " (" << mod.get_metadata( "container_long" ) << ")"; } set_field( fields, "Type" ).ostream() << mod.get_metadata( "type" ) << " (" << mod.get_metadata( "type_long" ) << ")"; if ( ( mod.get_num_subsongs() > 1 ) && ( flags.subsong != -1 ) ) { set_field( fields, "Subsong" ).ostream() << flags.subsong; } set_field( fields, "Tracker" ).ostream() << mod.get_metadata( "tracker" ); if ( !mod.get_metadata( "date" ).empty() ) { set_field( fields, "Date" ).ostream() << mod.get_metadata( "date" ); } if ( !mod.get_metadata( "artist" ).empty() ) { set_field( fields, "Artist" ).ostream() << mod.get_metadata( "artist" ); } } if ( true ) { set_field( fields, "Title" ).ostream() << mod.get_metadata( "title" ); set_field( fields, "Duration" ).ostream() << seconds_to_string( duration ); } if ( flags.show_details ) { set_field( fields, "Subsongs" ).ostream() << mod.get_num_subsongs(); set_field( fields, "Channels" ).ostream() << mod.get_num_channels(); set_field( fields, "Orders" ).ostream() << mod.get_num_orders(); set_field( fields, "Patterns" ).ostream() << mod.get_num_patterns(); set_field( fields, "Instruments" ).ostream() << mod.get_num_instruments(); set_field( fields, "Samples" ).ostream() << mod.get_num_samples(); } if ( flags.show_message ) { set_field( fields, "Message" ).ostream() << mod.get_metadata( "message" ); } show_fields( log, fields ); log.writeout(); if ( flags.filenames.size() == 1 || flags.mode == ModeRender ) { audio_stream.write_metadata( get_metadata( mod ) ); } else { audio_stream.write_updated_metadata( get_metadata( mod ) ); } if ( flags.mode == ModeProbe || flags.mode == ModeInfo ) { return; } if ( flags.seek_target > 0.0 ) { mod.set_position_seconds( flags.seek_target ); } try { if ( flags.use_float ) { render_loop( flags, mod, duration, log, audio_stream ); } else { render_loop( flags, mod, duration, log, audio_stream ); } if ( flags.show_progress ) { log << std::endl; } } catch ( ... ) { if ( flags.show_progress ) { log << std::endl; } throw; } log.writeout(); } static void probe_file( commandlineflags & flags, const std::string & filename, textout & log ) { log.writeout(); std::ostringstream silentlog; try { #if defined(WIN32) && defined(UNICODE) && !defined(_MSC_VER) std::istringstream file_stream; #else std::ifstream file_stream; #endif std::uint64_t filesize = 0; bool use_stdin = ( filename == "-" ); if ( !use_stdin ) { #if defined(WIN32) && defined(UNICODE) && !defined(_MSC_VER) // Only MSVC has std::ifstream::ifstream(std::wstring). // Fake it for other compilers using _wfopen(). std::string data; FILE * f = _wfopen( utf8_to_wstring( filename ).c_str(), L"rb" ); if ( f ) { while ( !feof( f ) ) { static const std::size_t BUFFER_SIZE = 4096; char buffer[BUFFER_SIZE]; size_t data_read = fread( buffer, 1, BUFFER_SIZE, f ); std::copy( buffer, buffer + data_read, std::back_inserter( data ) ); } fclose( f ); f = NULL; } file_stream.str( data ); filesize = data.length(); #elif defined(_MSC_VER) && defined(UNICODE) file_stream.open( utf8_to_wstring( filename ), std::ios::binary ); file_stream.seekg( 0, std::ios::end ); filesize = file_stream.tellg(); file_stream.seekg( 0, std::ios::beg ); #else file_stream.open( filename, std::ios::binary ); file_stream.seekg( 0, std::ios::end ); filesize = file_stream.tellg(); file_stream.seekg( 0, std::ios::beg ); #endif } std::istream & data_stream = use_stdin ? std::cin : file_stream; if ( data_stream.fail() ) { throw exception( "file open error" ); } probe_mod_file( flags, filename, filesize, data_stream, log ); } catch ( silent_exit_exception & ) { throw; } catch ( std::exception & e ) { if ( !silentlog.str().empty() ) { log << "errors probing '" << filename << "': " << silentlog.str() << std::endl; } else { log << "errors probing '" << filename << "'" << std::endl; } log << "error probing '" << filename << "': " << e.what() << std::endl; } catch ( ... ) { if ( !silentlog.str().empty() ) { log << "errors probing '" << filename << "': " << silentlog.str() << std::endl; } else { log << "errors probing '" << filename << "'" << std::endl; } log << "unknown error probing '" << filename << "'" << std::endl; } log << std::endl; log.writeout(); } static void render_file( commandlineflags & flags, const std::string & filename, textout & log, write_buffers_interface & audio_stream ) { log.writeout(); std::ostringstream silentlog; try { #if defined(WIN32) && defined(UNICODE) && !defined(_MSC_VER) std::istringstream file_stream; #else std::ifstream file_stream; #endif std::uint64_t filesize = 0; bool use_stdin = ( filename == "-" ); if ( !use_stdin ) { #if defined(WIN32) && defined(UNICODE) && !defined(_MSC_VER) // Only MSVC has std::ifstream::ifstream(std::wstring). // Fake it for other compilers using _wfopen(). std::string data; FILE * f = _wfopen( utf8_to_wstring( filename ).c_str(), L"rb" ); if ( f ) { while ( !feof( f ) ) { static const std::size_t BUFFER_SIZE = 4096; char buffer[BUFFER_SIZE]; size_t data_read = fread( buffer, 1, BUFFER_SIZE, f ); std::copy( buffer, buffer + data_read, std::back_inserter( data ) ); } fclose( f ); f = NULL; } file_stream.str( data ); filesize = data.length(); #elif defined(_MSC_VER) && defined(UNICODE) file_stream.open( utf8_to_wstring( filename ), std::ios::binary ); file_stream.seekg( 0, std::ios::end ); filesize = file_stream.tellg(); file_stream.seekg( 0, std::ios::beg ); #else file_stream.open( filename, std::ios::binary ); file_stream.seekg( 0, std::ios::end ); filesize = file_stream.tellg(); file_stream.seekg( 0, std::ios::beg ); #endif } std::istream & data_stream = use_stdin ? std::cin : file_stream; if ( data_stream.fail() ) { throw exception( "file open error" ); } { openmpt::module mod( data_stream, silentlog, flags.ctls ); mod.select_subsong( flags.subsong ); silentlog.str( std::string() ); // clear, loader messages get stored to get_metadata( "warnings" ) by libopenmpt internally render_mod_file( flags, filename, filesize, mod, log, audio_stream ); } } catch ( prev_file & ) { throw; } catch ( next_file & ) { throw; } catch ( silent_exit_exception & ) { throw; } catch ( std::exception & e ) { if ( !silentlog.str().empty() ) { log << "errors loading '" << filename << "': " << silentlog.str() << std::endl; } else { log << "errors loading '" << filename << "'" << std::endl; } log << "error playing '" << filename << "': " << e.what() << std::endl; } catch ( ... ) { if ( !silentlog.str().empty() ) { log << "errors loading '" << filename << "': " << silentlog.str() << std::endl; } else { log << "errors loading '" << filename << "'" << std::endl; } log << "unknown error playing '" << filename << "'" << std::endl; } log << std::endl; log.writeout(); } static std::string get_random_filename(std::set & filenames) { // TODO: actually use a useful random distribution std::size_t index = std::rand() % filenames.size(); std::set::iterator it = filenames.begin(); std::advance( it, index ); return *it; } static void render_files( commandlineflags & flags, textout & log, write_buffers_interface & audio_stream ) { if ( flags.randomize ) { std::random_shuffle( flags.filenames.begin(), flags.filenames.end() ); } try { while ( true ) { if ( flags.shuffle ) { // TODO: improve prev/next logic std::set shuffle_set; shuffle_set.insert( flags.filenames.begin(), flags.filenames.end() ); while ( true ) { if ( shuffle_set.empty() ) { break; } std::string filename = get_random_filename( shuffle_set ); try { flags.playlist_index = std::find( flags.filenames.begin(), flags.filenames.end(), filename ) - flags.filenames.begin(); render_file( flags, filename, log, audio_stream ); shuffle_set.erase( filename ); continue; } catch ( prev_file & ) { shuffle_set.erase( filename ); continue; } catch ( next_file & ) { shuffle_set.erase( filename ); continue; } catch ( ... ) { throw; } } } else { std::vector::iterator filename = flags.filenames.begin(); while ( true ) { if ( filename == flags.filenames.end() ) { break; } try { flags.playlist_index = filename - flags.filenames.begin(); render_file( flags, *filename, log, audio_stream ); filename++; continue; } catch ( prev_file & e ) { while ( filename != flags.filenames.begin() && e.count ) { e.count--; --filename; } continue; } catch ( next_file & e ) { while ( filename != flags.filenames.end() && e.count ) { e.count--; ++filename; } continue; } catch ( ... ) { throw; } } } if ( !flags.restart ) { break; } } } catch ( ... ) { throw; } } static bool parse_playlist( commandlineflags & flags, std::string filename, std::ostream & log ) { log.flush(); bool is_playlist = false; bool m3u8 = false; if ( ends_with( filename, ".m3u") || ends_with( filename, ".m3U") || ends_with( filename, ".M3u") || ends_with( filename, ".M3U") ) { is_playlist = true; } if ( ends_with( filename, ".m3u8") || ends_with( filename, ".m3U8") || ends_with( filename, ".M3u8") || ends_with( filename, ".M3U8") ) { is_playlist = true; m3u8 = true; } if ( ends_with( filename, ".pls") || ends_with( filename, ".plS") || ends_with( filename, ".pLs") || ends_with( filename, ".pLS") || ends_with( filename, ".Pls") || ends_with( filename, ".PlS") || ends_with( filename, ".PLs") || ends_with( filename, ".PLS") ) { is_playlist = true; } std::string basepath = get_basepath( filename ); try { #if defined(WIN32) && defined(UNICODE) && !defined(_MSC_VER) std::istringstream file_stream; #else std::ifstream file_stream; #endif #if defined(WIN32) && defined(UNICODE) && !defined(_MSC_VER) // Only MSVC has std::ifstream::ifstream(std::wstring). // Fake it for other compilers using _wfopen(). std::string data; FILE * f = _wfopen( utf8_to_wstring( filename ).c_str(), L"rb" ); if ( f ) { while ( !feof( f ) ) { static const std::size_t BUFFER_SIZE = 4096; char buffer[BUFFER_SIZE]; size_t data_read = fread( buffer, 1, BUFFER_SIZE, f ); std::copy( buffer, buffer + data_read, std::back_inserter( data ) ); } fclose( f ); f = NULL; } file_stream.str( data ); #elif defined(_MSC_VER) && defined(UNICODE) file_stream.open( utf8_to_wstring( filename ), std::ios::binary ); #else file_stream.open( filename, std::ios::binary ); #endif std::string line; bool first = true; bool extm3u = false; bool pls = false; while ( std::getline( file_stream, line ) ) { std::string newfile; line = trim_eol( line ); if ( first ) { first = false; if ( line == "#EXTM3U" ) { extm3u = true; continue; } else if ( line == "[playlist]" ) { pls = true; } } if ( line.empty() ) { continue; } if ( pls ) { if ( begins_with( line, "File" ) ) { if ( line.find( "=" ) != std::string::npos ) { flags.filenames.push_back( line.substr( line.find( "=" ) + 1 ) ); } } else if ( begins_with( line, "Title" ) ) { continue; } else if ( begins_with( line, "Length" ) ) { continue; } else if ( begins_with( line, "NumberOfEntries" ) ) { continue; } else if ( begins_with( line, "Version" ) ) { continue; } else { continue; } } else if ( extm3u ) { if ( begins_with( line, "#EXTINF" ) ) { continue; } else if ( begins_with( line, "#" ) ) { continue; } if ( m3u8 ) { newfile = line; } else { #if defined(WIN32) newfile = wstring_to_utf8( locale_to_wstring( line ) ); #else newfile = line; #endif } } else { if ( m3u8 ) { newfile = line; } else { #if defined(WIN32) newfile = wstring_to_utf8( locale_to_wstring( line ) ); #else newfile = line; #endif } } if ( !newfile.empty() ) { if ( !is_absolute( newfile ) ) { newfile = basepath + newfile; } flags.filenames.push_back( newfile ); } } } catch ( std::exception & e ) { log << "error loading '" << filename << "': " << e.what() << std::endl; } catch ( ... ) { log << "unknown error loading '" << filename << "'" << std::endl; } log.flush(); return is_playlist; } static commandlineflags parse_openmpt123( const std::vector & args, std::ostream & log ) { log.flush(); if ( args.size() <= 1 ) { throw args_error_exception(); } commandlineflags flags; bool files_only = false; for ( std::vector::const_iterator i = args.begin(); i != args.end(); ++i ) { if ( i == args.begin() ) { // skip program name continue; } std::string arg = *i; std::string nextarg = ( i+1 != args.end() ) ? *(i+1) : ""; if ( files_only ) { flags.filenames.push_back( arg ); } else if ( arg.substr( 0, 1 ) != "-" ) { flags.filenames.push_back( arg ); } else { if ( arg == "--" ) { files_only = true; } else if ( arg == "-h" || arg == "--help" ) { throw show_help_exception(); } else if ( arg == "--help-keyboard" ) { throw show_help_keyboard_exception(); } else if ( arg == "-q" || arg == "--quiet" ) { flags.quiet = true; } else if ( arg == "-v" || arg == "--verbose" ) { flags.verbose = true; } else if ( arg == "--man-version" ) { throw show_man_version_exception(); } else if ( arg == "--man-help" ) { throw show_man_help_exception(); } else if ( arg == "--version" ) { throw show_version_number_exception(); } else if ( arg == "--short-version" ) { throw show_short_version_number_exception(); } else if ( arg == "--long-version" ) { throw show_long_version_number_exception(); } else if ( arg == "--credits" ) { throw show_credits_exception(); } else if ( arg == "--license" ) { throw show_license_exception(); } else if ( arg == "--probe" ) { flags.mode = ModeProbe; } else if ( arg == "--info" ) { flags.mode = ModeInfo; } else if ( arg == "--ui" ) { flags.mode = ModeUI; } else if ( arg == "--batch" ) { flags.mode = ModeBatch; } else if ( arg == "--render" ) { flags.mode = ModeRender; } else if ( arg == "--terminal-width" && nextarg != "" ) { std::istringstream istr( nextarg ); istr >> flags.terminal_width; ++i; } else if ( arg == "--terminal-height" && nextarg != "" ) { std::istringstream istr( nextarg ); istr >> flags.terminal_height; ++i; } else if ( arg == "--progress" ) { flags.show_progress = true; } else if ( arg == "--no-progress" ) { flags.show_progress = false; } else if ( arg == "--meters" ) { flags.show_meters = true; } else if ( arg == "--no-meters" ) { flags.show_meters = false; } else if ( arg == "--channel-meters" ) { flags.show_channel_meters = true; } else if ( arg == "--no-channel-meters" ) { flags.show_channel_meters = false; } else if ( arg == "--pattern" ) { flags.show_pattern = true; } else if ( arg == "--no-pattern" ) { flags.show_pattern = false; } else if ( arg == "--details" ) { flags.show_details = true; } else if ( arg == "--no-details" ) { flags.show_details = false; } else if ( arg == "--message" ) { flags.show_message = true; } else if ( arg == "--no-message" ) { flags.show_message = false; } else if ( arg == "--driver" && nextarg != "" ) { if ( false ) { // nothing } else if ( nextarg == "help" ) { std::ostringstream drivers; drivers << " Available drivers:" << std::endl; drivers << " " << "default" << std::endl; #if defined( MPT_WITH_PULSEAUDIO ) drivers << " " << "pulseaudio" << std::endl; #endif #if defined( MPT_WITH_SDL2 ) drivers << " " << "sdl2" << std::endl; #endif #if defined( MPT_WITH_SDL ) drivers << " " << "sdl" << std::endl; #endif #if defined( MPT_WITH_PORTAUDIO ) drivers << " " << "portaudio" << std::endl; #endif #if defined( WIN32 ) drivers << " " << "waveout" << std::endl; #endif throw show_help_exception( drivers.str() ); } else if ( nextarg == "default" ) { flags.driver = ""; } else { flags.driver = nextarg; } ++i; } else if ( arg == "--device" && nextarg != "" ) { if ( false ) { // nothing } else if ( nextarg == "help" ) { std::ostringstream devices; devices << " Available devices:" << std::endl; devices << " " << "default" << ": " << "default" << std::endl; #if defined( MPT_WITH_PULSEAUDIO ) devices << show_pulseaudio_devices( log ); #endif #if defined( MPT_WITH_SDL2 ) devices << show_sdl2_devices( log ); #endif #if defined( MPT_WITH_PORTAUDIO ) devices << show_portaudio_devices( log ); #endif #if defined( WIN32 ) devices << show_waveout_devices( log ); #endif throw show_help_exception( devices.str() ); } else if ( nextarg == "default" ) { flags.device = ""; } else { flags.device = nextarg; } ++i; } else if ( arg == "--buffer" && nextarg != "" ) { std::istringstream istr( nextarg ); istr >> flags.buffer; ++i; } else if ( arg == "--period" && nextarg != "" ) { std::istringstream istr( nextarg ); istr >> flags.period; ++i; } else if ( arg == "--update" && nextarg != "" ) { std::istringstream istr( nextarg ); istr >> flags.ui_redraw_interval; ++i; } else if ( arg == "--stdout" ) { flags.use_stdout = true; } else if ( ( arg == "-o" || arg == "--output" ) && nextarg != "" ) { flags.output_filename = nextarg; ++i; } else if ( arg == "--force" ) { flags.force_overwrite = true; } else if ( arg == "--output-type" && nextarg != "" ) { flags.output_extension = nextarg; ++i; } else if ( arg == "--samplerate" && nextarg != "" ) { std::istringstream istr( nextarg ); istr >> flags.samplerate; ++i; } else if ( arg == "--channels" && nextarg != "" ) { std::istringstream istr( nextarg ); istr >> flags.channels; ++i; } else if ( arg == "--float" ) { flags.use_float = true; } else if ( arg == "--no-float" ) { flags.use_float = false; } else if ( arg == "--gain" && nextarg != "" ) { std::istringstream istr( nextarg ); double gain = 0.0; istr >> gain; flags.gain = static_cast( gain * 100.0 ); ++i; } else if ( arg == "--stereo" && nextarg != "" ) { std::istringstream istr( nextarg ); istr >> flags.separation; ++i; } else if ( arg == "--filter" && nextarg != "" ) { std::istringstream istr( nextarg ); istr >> flags.filtertaps; ++i; } else if ( arg == "--ramping" && nextarg != "" ) { std::istringstream istr( nextarg ); istr >> flags.ramping; ++i; } else if ( arg == "--tempo" && nextarg != "" ) { std::istringstream istr( nextarg ); double tmp = 1.0; istr >> tmp; flags.tempo = double_to_tempo_flag( tmp ); ++i; } else if ( arg == "--pitch" && nextarg != "" ) { std::istringstream istr( nextarg ); double tmp = 1.0; istr >> tmp; flags.pitch = double_to_pitch_flag( tmp ); ++i; } else if ( arg == "--dither" && nextarg != "" ) { std::istringstream istr( nextarg ); istr >> flags.dither; ++i; } else if ( arg == "--playlist" && nextarg != "" ) { parse_playlist( flags, nextarg, log ); ++i; } else if ( arg == "--randomize" ) { flags.randomize = true; } else if ( arg == "--no-randomize" ) { flags.randomize = false; } else if ( arg == "--shuffle" ) { flags.shuffle = true; } else if ( arg == "--no-shuffle" ) { flags.shuffle = false; } else if ( arg == "--restart" ) { flags.restart = true; } else if ( arg == "--no-restart" ) { flags.restart = false; } else if ( arg == "--subsong" && nextarg != "" ) { std::istringstream istr( nextarg ); istr >> flags.subsong; ++i; } else if ( arg == "--repeat" && nextarg != "" ) { std::istringstream istr( nextarg ); istr >> flags.repeatcount; ++i; } else if ( arg == "--ctl" && nextarg != "" ) { std::istringstream istr( nextarg ); std::string ctl_c_v; istr >> ctl_c_v; if ( ctl_c_v.find( "=" ) == std::string::npos ) { throw args_error_exception(); } std::string ctl = ctl_c_v.substr( 0, ctl_c_v.find( "=" ) ); std::string val = ctl_c_v.substr( ctl_c_v.find( "=" ) + std::string("=").length(), std::string::npos ); if ( ctl.empty() ) { throw args_error_exception(); } flags.ctls[ ctl ] = val; ++i; } else if ( arg == "--seek" && nextarg != "" ) { std::istringstream istr( nextarg ); istr >> flags.seek_target; ++i; } else if ( arg == "--end-time" && nextarg != "" ) { std::istringstream istr( nextarg ); istr >> flags.end_time; ++i; } else if ( arg.size() > 0 && arg.substr( 0, 1 ) == "-" ) { throw args_error_exception(); } } } return flags; } #if defined(WIN32) class ConsoleCP_utf8_raii { private: const UINT oldCP; const UINT oldOutputCP; public: ConsoleCP_utf8_raii() : oldCP(GetConsoleCP()) , oldOutputCP(GetConsoleOutputCP()) { SetConsoleCP( 65001 ); // UTF-8 SetConsoleOutputCP( 65001 ); // UTF-8 } ~ConsoleCP_utf8_raii() { SetConsoleCP( oldCP ); SetConsoleOutputCP( oldOutputCP ); } }; class FD_binary_raii { private: FILE * file; int old_mode; public: FD_binary_raii(FILE * file, bool set_binary) : file(file) , old_mode(-1) { if ( set_binary ) { fflush( file ); old_mode = _setmode( _fileno( file ), _O_BINARY ); if ( old_mode == -1 ) { throw exception( "failed to set binary mode on file descriptor" ); } } } ~FD_binary_raii() { if ( old_mode != -1 ) { fflush( file ); old_mode = _setmode( _fileno( file ), old_mode ); } } }; #endif #if defined(WIN32) && defined(UNICODE) static int wmain( int wargc, wchar_t * wargv [] ) { #else static int main( int argc, char * argv [] ) { #endif std::vector args; #if defined(WIN32) && defined(UNICODE) for ( int arg = 0; arg < wargc; ++arg ) { args.push_back( wstring_to_utf8( wargv[arg] ) ); } #else args = std::vector( argv, argv + argc ); #endif #if defined(WIN32) ConsoleCP_utf8_raii console_cp; #endif textout_dummy dummy_log; #if defined(WIN32) textout_console std_out( GetStdHandle( STD_OUTPUT_HANDLE ) ); textout_console std_err( GetStdHandle( STD_ERROR_HANDLE ) ); #else textout_ostream std_out( std::cout ); textout_ostream std_err( std::clog ); #endif commandlineflags flags; try { flags = parse_openmpt123( args, std::cerr ); flags.check_and_sanitize(); } catch ( args_error_exception & ) { show_help( std_out ); return 1; } catch ( show_man_help_exception & ) { show_help( std_out, false, true, true ); return 0; } catch ( show_man_version_exception & ) { show_man_version( std_out ); return 0; } catch ( show_help_exception & e ) { show_help( std_out, true, e.longhelp, false, e.message ); if ( flags.verbose ) { show_credits( std_out ); } return 0; } catch ( show_help_keyboard_exception & ) { show_help_keyboard( std_out ); return 0; } catch ( show_long_version_number_exception & ) { show_long_version( std_out ); return 0; } catch ( show_version_number_exception & ) { show_version( std_out ); return 0; } catch ( show_short_version_number_exception & ) { show_short_version( std_out ); return 0; } catch ( show_credits_exception & ) { show_credits( std_out ); return 0; } catch ( show_license_exception & ) { show_license( std_out ); return 0; } catch ( silent_exit_exception & ) { return 0; } catch ( std::exception & e ) { std_err << "error: " << e.what() << std::endl; std_err.writeout(); return 1; } catch ( ... ) { std_err << "unknown error" << std::endl; std_err.writeout(); return 1; } try { bool stdin_can_ui = true; for ( std::vector::iterator filename = flags.filenames.begin(); filename != flags.filenames.end(); ++filename ) { if ( *filename == "-" ) { stdin_can_ui = false; break; } } bool stdout_can_ui = true; if ( flags.use_stdout ) { stdout_can_ui = false; } // set stdin binary #if defined(WIN32) FD_binary_raii stdin_guard( stdin, !stdin_can_ui ); #endif // set stdout binary #if defined(WIN32) FD_binary_raii stdout_guard( stdout, !stdout_can_ui ); #endif // setup terminal #if !defined(WIN32) if ( stdin_can_ui ) { if ( flags.mode == ModeUI ) { set_input_mode(); } } #endif textout & log = flags.quiet ? *static_cast( &dummy_log ) : *static_cast( stdout_can_ui ? &std_out : &std_err ); show_info( log, flags.verbose ); if ( !flags.warnings.empty() ) { log << flags.warnings << std::endl; } if ( flags.verbose ) { log << flags; } log.writeout(); std::srand( static_cast( std::time( NULL ) ) ); switch ( flags.mode ) { case ModeProbe: { for ( std::vector::iterator filename = flags.filenames.begin(); filename != flags.filenames.end(); ++filename ) { probe_file( flags, *filename, log ); flags.playlist_index++; } } break; case ModeInfo: { void_audio_stream dummy; render_files( flags, log, dummy ); } break; case ModeUI: case ModeBatch: { if ( flags.use_stdout ) { flags.apply_default_buffer_sizes(); stdout_stream_raii stdout_audio_stream; render_files( flags, log, stdout_audio_stream ); } else if ( !flags.output_filename.empty() ) { flags.apply_default_buffer_sizes(); file_audio_stream_raii file_audio_stream( flags, flags.output_filename, log ); render_files( flags, log, file_audio_stream ); #if defined( MPT_WITH_PULSEAUDIO ) } else if ( flags.driver == "pulseaudio" || flags.driver.empty() ) { pulseaudio_stream_raii pulseaudio_stream( flags, log ); render_files( flags, log, pulseaudio_stream ); #endif #if defined( MPT_WITH_SDL2 ) } else if ( flags.driver == "sdl2" || flags.driver.empty() ) { sdl2_stream_raii sdl2_stream( flags, log ); render_files( flags, log, sdl2_stream ); #endif #if defined( MPT_WITH_SDL ) } else if ( flags.driver == "sdl" || flags.driver.empty() ) { sdl_stream_raii sdl_stream( flags, log ); render_files( flags, log, sdl_stream ); #endif #if defined( MPT_WITH_PORTAUDIO ) } else if ( flags.driver == "portaudio" || flags.driver.empty() ) { portaudio_stream_raii portaudio_stream( flags, log ); render_files( flags, log, portaudio_stream ); #endif #if defined( WIN32 ) } else if ( flags.driver == "waveout" || flags.driver.empty() ) { waveout_stream_raii waveout_stream( flags ); render_files( flags, log, waveout_stream ); #endif } else { if ( flags.driver.empty() ) { throw exception( "openmpt123 is compiled without any audio driver" ); } else { throw exception( "audio driver '" + flags.driver + "' not found" ); } } } break; case ModeRender: { for ( std::vector::iterator filename = flags.filenames.begin(); filename != flags.filenames.end(); ++filename ) { flags.apply_default_buffer_sizes(); file_audio_stream_raii file_audio_stream( flags, *filename + std::string(".") + flags.output_extension, log ); render_file( flags, *filename, log, file_audio_stream ); flags.playlist_index++; } } break; case ModeNone: break; } } catch ( args_error_exception & ) { show_help( std_out ); return 1; #ifdef MPT_WITH_PULSEAUDIO } catch ( pulseaudio_exception & e ) { std_err << "PulseAudio error: " << e.what() << std::endl; std_err.writeout(); return 1; #endif #ifdef MPT_WITH_PORTAUDIO } catch ( portaudio_exception & e ) { std_err << "PortAudio error: " << e.what() << std::endl; std_err.writeout(); return 1; #endif #ifdef MPT_WITH_SDL } catch ( sdl_exception & e ) { std_err << "SDL error: " << e.what() << std::endl; std_err.writeout(); return 1; #endif #ifdef MPT_WITH_SDL2 } catch ( sdl2_exception & e ) { std_err << "SDL2 error: " << e.what() << std::endl; std_err.writeout(); return 1; #endif } catch ( silent_exit_exception & ) { return 0; } catch ( std::exception & e ) { std_err << "error: " << e.what() << std::endl; std_err.writeout(); return 1; } catch ( ... ) { std_err << "unknown error" << std::endl; std_err.writeout(); return 1; } return 0; } } // namespace openmpt123 #if defined(WIN32) && defined(UNICODE) #if defined(__GNUC__) // mingw64 does only default to special C linkage for "main", but not for "wmain". extern "C" #endif int wmain( int wargc, wchar_t * wargv [] ) { return openmpt123::wmain( wargc, wargv ); } #else int main( int argc, char * argv [] ) { return openmpt123::main( argc, argv ); } #endif libopenmpt-0.3.6+release.autotools/openmpt123/openmpt123_config.hpp0000644000372100037210000000246013157247257022153 00000000000000/* * openmpt123_config.hpp * --------------------- * Purpose: libopenmpt command line player * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #ifndef OPENMPT123_CONFIG_HPP #define OPENMPT123_CONFIG_HPP #if defined(HAVE_CONFIG_H) // wrapper for autoconf macros #include "config.h" #endif // HAVE_CONFIG_H #if defined(_WIN32) #ifndef WIN32 #define WIN32 #endif #endif // _WIN32 #if defined(WIN32) #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif #ifndef NOMINMAX #define NOMINMAX #endif #ifndef UNICODE #define UNICODE #endif #ifndef _UNICODE #define _UNICODE #endif #endif // WIN32 #if defined(WIN32) #define MPT_WITH_MMIO #endif // WIN32 #if defined(_MSC_VER) #pragma warning( disable : 4996 ) // 'foo': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _foo. See online help for details. #endif // _MSC_VER #if defined(MPT_BUILD_MSVC) #define MPT_WITH_FLAC #define MPT_WITH_PORTAUDIO #if defined(MPT_BUILD_MSVC_STATIC) #define FLAC__NO_DLL #endif #endif // MPT_BUILD_MSVC #if defined(MPT_WITH_SDL) #ifndef MPT_NEEDS_THREADS #define MPT_NEEDS_THREADS #endif #endif #define OPENMPT123_VERSION_STRING OPENMPT_API_VERSION_STRING #endif // OPENMPT123_CONFIG_HPP libopenmpt-0.3.6+release.autotools/openmpt123/openmpt123_waveout.hpp0000644000372100037210000001334112762337506022376 00000000000000/* * openmpt123_waveout.hpp * ------------------------ * Purpose: libopenmpt command line player * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #ifndef OPENMPT123_WAVEOUT_HPP #define OPENMPT123_WAVEOUT_HPP #include "openmpt123_config.hpp" #include "openmpt123.hpp" #if defined(WIN32) namespace openmpt123 { struct waveout_exception : public exception { waveout_exception() throw() : exception( "waveout" ) { } }; class waveout_stream_raii : public write_buffers_interface { private: HWAVEOUT waveout; std::size_t num_channels; std::size_t num_chunks; std::size_t frames_per_chunk; std::size_t bytes_per_chunk; std::vector waveheaders; std::vector > wavebuffers; std::deque byte_queue; public: waveout_stream_raii( commandlineflags & flags ) : waveout(NULL) , num_channels(0) , num_chunks(0) , frames_per_chunk(0) , bytes_per_chunk(0) { if ( flags.buffer == default_high ) { flags.buffer = 150; } else if ( flags.buffer == default_low ) { flags.buffer = 50; } if ( flags.period == default_high ) { flags.period = 30; } else if ( flags.period == default_low ) { flags.period = 10; } flags.apply_default_buffer_sizes(); WAVEFORMATEX wfx; ZeroMemory( &wfx, sizeof( wfx ) ); wfx.wFormatTag = flags.use_float ? WAVE_FORMAT_IEEE_FLOAT : WAVE_FORMAT_PCM; wfx.nChannels = flags.channels; wfx.nSamplesPerSec = flags.samplerate; wfx.wBitsPerSample = flags.use_float ? 32 : 16; wfx.nBlockAlign = ( wfx.wBitsPerSample / 8 ) * wfx.nChannels; wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; wfx.cbSize = 0; std::istringstream device_string( flags.device ); int device = -1; device_string >> device; waveOutOpen( &waveout, device == -1 ? WAVE_MAPPER : device, &wfx, 0, 0, CALLBACK_NULL ); num_channels = flags.channels; std::size_t frames_per_buffer = flags.samplerate * flags.buffer / 1000; num_chunks = ( flags.buffer + flags.period - 1 ) / flags.period; if ( num_chunks < 2 ) { num_chunks = 2; } frames_per_chunk = ( frames_per_buffer + num_chunks - 1 ) / num_chunks; bytes_per_chunk = wfx.nBlockAlign * frames_per_chunk; waveheaders.resize( num_chunks ); wavebuffers.resize( num_chunks ); for ( std::size_t i = 0; i < num_chunks; ++i ) { wavebuffers[i].resize( bytes_per_chunk ); waveheaders[i] = WAVEHDR(); waveheaders[i].lpData = wavebuffers[i].data(); waveheaders[i].dwBufferLength = static_cast( wavebuffers[i].size() ); waveheaders[i].dwFlags = 0; waveOutPrepareHeader( waveout, &waveheaders[i], sizeof( WAVEHDR ) ); } } ~waveout_stream_raii() { if ( waveout ) { write_or_wait( true ); drain(); waveOutReset( waveout ); for ( std::size_t i = 0; i < num_chunks; ++i ) { waveheaders[i].dwBufferLength = static_cast( wavebuffers[i].size() ); waveOutUnprepareHeader( waveout, &waveheaders[i], sizeof( WAVEHDR ) ); } wavebuffers.clear(); waveheaders.clear(); frames_per_chunk = 0; num_chunks = 0; waveOutClose( waveout ); waveout = NULL; } } private: void drain() { std::size_t empty_chunks = 0; while ( empty_chunks != num_chunks ) { empty_chunks = 0; for ( std::size_t chunk = 0; chunk < num_chunks; ++chunk ) { DWORD flags = waveheaders[chunk].dwFlags; if ( !(flags & WHDR_INQUEUE) || (flags & WHDR_DONE) ) { empty_chunks++; } } if ( empty_chunks != num_chunks ) { Sleep( 1 ); } } } std::size_t wait_for_empty_chunk() { while ( true ) { for ( std::size_t chunk = 0; chunk < num_chunks; ++chunk ) { DWORD flags = waveheaders[chunk].dwFlags; if ( !(flags & WHDR_INQUEUE) || (flags & WHDR_DONE) ) { return chunk; } } Sleep( 1 ); } } void write_chunk() { std::size_t chunk = wait_for_empty_chunk(); std::size_t chunk_bytes = std::min( byte_queue.size(), bytes_per_chunk ); waveheaders[chunk].dwBufferLength = static_cast( chunk_bytes ); for ( std::size_t byte = 0; byte < chunk_bytes; ++byte ) { wavebuffers[chunk][byte] = byte_queue.front(); byte_queue.pop_front(); } waveOutWrite( waveout, &waveheaders[chunk], sizeof( WAVEHDR ) ); } void write_or_wait( bool flush = false ) { while ( byte_queue.size() >= bytes_per_chunk ) { write_chunk(); } if ( flush && !byte_queue.empty() ) { write_chunk(); } } template < typename Tsample > void write_buffers( const std::vector buffers, std::size_t frames ) { for ( std::size_t frame = 0; frame < frames; ++frame ) { for ( std::size_t channel = 0; channel < buffers.size(); ++channel ) { Tsample val = buffers[channel][frame]; char buf[ sizeof( Tsample ) ]; std::memcpy( buf, &val, sizeof( Tsample ) ); std::copy( buf, buf + sizeof( Tsample ), std::back_inserter( byte_queue ) ); } } write_or_wait(); } public: void write( const std::vector buffers, std::size_t frames ) { write_buffers( buffers, frames ); } void write( const std::vector buffers, std::size_t frames ) { write_buffers( buffers, frames ); } bool pause() { waveOutPause( waveout ); return true; } bool unpause() { waveOutRestart( waveout ); return true; } bool sleep( int ms ) { Sleep( ms ); return true; } }; static std::string show_waveout_devices( std::ostream & /*log*/ ) { std::ostringstream devices; devices << " waveout:" << std::endl; for ( UINT i = 0; i < waveOutGetNumDevs(); ++i ) { devices << " " << i << ": "; WAVEOUTCAPSW caps; ZeroMemory( &caps, sizeof( caps ) ); waveOutGetDevCapsW( i, &caps, sizeof( caps ) ); devices << wstring_to_utf8( caps.szPname ); devices << std::endl; } return devices.str(); } } // namespace openmpt123 #endif // WIN32 #endif // OPENMPT123_WAVEOUT_HPP libopenmpt-0.3.6+release.autotools/openmpt123/openmpt123.hpp0000644000372100037210000004001613176403233020612 00000000000000/* * openmpt123.hpp * -------------- * Purpose: libopenmpt command line player * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #ifndef OPENMPT123_HPP #define OPENMPT123_HPP #include "openmpt123_config.hpp" namespace openmpt123 { struct exception : public openmpt::exception { exception( const std::string & text ) throw() : openmpt::exception(text) { } }; struct show_help_exception { std::string message; bool longhelp; show_help_exception( const std::string & msg = "", bool longhelp_ = true ) : message(msg), longhelp(longhelp_) { } }; struct args_error_exception { args_error_exception() { } }; struct show_help_keyboard_exception { }; #if defined(WIN32) std::string wstring_to_utf8( const std::wstring & unicode_string ) { int required_size = WideCharToMultiByte( CP_UTF8, 0, unicode_string.c_str(), -1, NULL, 0, NULL, NULL ); if ( required_size <= 0 ) { return std::string(); } std::vector utf8_buf( required_size ); WideCharToMultiByte( CP_UTF8, 0, unicode_string.c_str(), -1, &utf8_buf[0], required_size, NULL, NULL ); return &utf8_buf[0]; } std::wstring utf8_to_wstring( const std::string & utf8_string ) { int required_size = MultiByteToWideChar( CP_UTF8, 0, utf8_string.c_str(), -1, NULL, 0 ); if ( required_size <= 0 ) { return std::wstring(); } std::vector unicode_buf( required_size ); MultiByteToWideChar( CP_UTF8, 0, utf8_string.data(), -1, &unicode_buf[0], required_size ); return &unicode_buf[0]; } std::string wstring_to_locale( const std::wstring & unicode_string ) { int required_size = WideCharToMultiByte( CP_ACP, 0, unicode_string.c_str(), -1, NULL, 0, NULL, NULL ); if ( required_size <= 0 ) { return std::string(); } std::vector locale_buf( required_size ); WideCharToMultiByte( CP_ACP, 0, unicode_string.c_str(), -1, &locale_buf[0], required_size, NULL, NULL ); return &locale_buf[0]; } std::wstring locale_to_wstring( const std::string & locale_string ) { int required_size = MultiByteToWideChar( CP_ACP, 0, locale_string.c_str(), -1, NULL, 0 ); if ( required_size <= 0 ) { return std::wstring(); } std::vector unicode_buf( required_size ); MultiByteToWideChar( CP_ACP, 0, locale_string.data(), -1, &unicode_buf[0], required_size ); return &unicode_buf[0]; } #endif // WIN32 #if defined(MPT_NEEDS_THREADS) #if defined(WIN32) class mutex { private: CRITICAL_SECTION impl; public: mutex() { InitializeCriticalSection(&impl); } ~mutex() { DeleteCriticalSection(&impl); } void lock() { EnterCriticalSection(&impl); } void unlock() { LeaveCriticalSection(&impl); } }; #else class mutex { private: pthread_mutex_t impl; public: mutex() { pthread_mutexattr_t attr; pthread_mutexattr_init( &attr ); pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_NORMAL ); pthread_mutex_init( &impl, &attr ); pthread_mutexattr_destroy( &attr ); } ~mutex() { pthread_mutex_destroy( &impl ); } void lock() { pthread_mutex_lock( &impl ); } void unlock() { pthread_mutex_unlock( &impl ); } }; #endif #endif struct field { std::string key; std::string val; field( const std::string & key ) : key(key) { return; } }; class textout : public std::ostringstream { public: textout() { return; } virtual ~textout() { return; } public: virtual void write( const std::string & text ) = 0; virtual void writeout() { write( str() ); str(std::string()); } }; class textout_dummy : public textout { public: textout_dummy() { return; } virtual ~textout_dummy() { return; } public: virtual void write( const std::string & /* text */ ) { return; } }; class textout_ostream : public textout { private: std::ostream & s; public: textout_ostream( std::ostream & s_ ) : s(s_) { return; } virtual ~textout_ostream() { writeout(); } public: virtual void write( const std::string & text ) { s << text; } virtual void writeout() { textout::writeout(); s.flush(); } }; #if defined(WIN32) class textout_console : public textout { private: HANDLE handle; public: textout_console( HANDLE handle_ ) : handle(handle_) { return; } virtual ~textout_console() { writeout(); } public: virtual void write( const std::string & text ) { #if defined(UNICODE) std::wstring wtext = utf8_to_wstring( text ); WriteConsole( handle, wtext.data(), static_cast( wtext.size() ), NULL, NULL ); #else WriteConsole( handle, text.data(), static_cast( text.size() ), NULL, NULL ); #endif } }; #endif // WIN32 static inline float mpt_round( float val ) { if ( val >= 0.0f ) { return std::floor( val + 0.5f ); } else { return std::ceil( val - 0.5f ); } } static inline long mpt_lround( float val ) { return static_cast< long >( mpt_round( val ) ); } static inline std::string append_software_tag( std::string software ) { std::string openmpt123 = std::string() + "openmpt123 " + OPENMPT123_VERSION_STRING + " (libopenmpt " + openmpt::string::get( "library_version" ) + ", OpenMPT " + openmpt::string::get( "core_version" ) + ")"; if ( software.empty() ) { software = openmpt123; } else { software += " (via " + openmpt123 + ")"; } return software; } static inline std::string get_encoder_tag() { return std::string() + "openmpt123 " + OPENMPT123_VERSION_STRING + " (libopenmpt " + openmpt::string::get( "library_version" ) + ", OpenMPT " + openmpt::string::get( "core_version" ) + ")"; } static inline std::string get_extension( std::string filename ) { if ( filename.find_last_of( "." ) != std::string::npos ) { return filename.substr( filename.find_last_of( "." ) + 1 ); } return ""; } bool IsTerminal( int fd ); enum Mode { ModeNone, ModeProbe, ModeInfo, ModeUI, ModeBatch, ModeRender }; static inline std::string mode_to_string( Mode mode ) { switch ( mode ) { case ModeNone: return "none"; break; case ModeProbe: return "probe"; break; case ModeInfo: return "info"; break; case ModeUI: return "ui"; break; case ModeBatch: return "batch"; break; case ModeRender: return "render"; break; } return ""; } static const std::int32_t default_low = -2; static const std::int32_t default_high = -1; struct commandlineflags { Mode mode; bool canUI; std::int32_t ui_redraw_interval; bool canProgress; std::string driver; std::string device; std::int32_t buffer; std::int32_t period; std::int32_t samplerate; std::int32_t channels; std::int32_t gain; std::int32_t separation; std::int32_t filtertaps; std::int32_t ramping; // ramping strength : -1:default 0:off 1 2 3 4 5 // roughly milliseconds std::int32_t tempo; std::int32_t pitch; std::int32_t dither; std::int32_t repeatcount; std::int32_t subsong; std::map ctls; double seek_target; double end_time; bool quiet; bool verbose; int terminal_width; int terminal_height; bool show_details; bool show_message; bool show_ui; bool show_progress; bool show_meters; bool show_channel_meters; bool show_pattern; bool use_float; bool use_stdout; bool randomize; bool shuffle; bool restart; std::size_t playlist_index; std::vector filenames; std::string output_filename; std::string output_extension; bool force_overwrite; bool paused; std::string warnings; void apply_default_buffer_sizes() { if ( ui_redraw_interval == default_high ) { ui_redraw_interval = 50; } else if ( ui_redraw_interval == default_low ) { ui_redraw_interval = 10; } if ( buffer == default_high ) { buffer = 250; } else if ( buffer == default_low ) { buffer = 50; } if ( period == default_high ) { period = 50; } else if ( period == default_low ) { period = 10; } } commandlineflags() { mode = ModeUI; ui_redraw_interval = default_high; driver = ""; device = ""; buffer = default_high; period = default_high; samplerate = 48000; channels = 2; use_float = true; gain = 0; separation = 100; filtertaps = 8; ramping = -1; tempo = 0; pitch = 0; dither = 1; repeatcount = 0; subsong = -1; seek_target = 0.0; end_time = 0.0; quiet = false; verbose = false; terminal_width = 72; terminal_height = 23; #if defined(WIN32) CONSOLE_SCREEN_BUFFER_INFO csbi; ZeroMemory( &csbi, sizeof( CONSOLE_SCREEN_BUFFER_INFO ) ); GetConsoleScreenBufferInfo( GetStdHandle( STD_OUTPUT_HANDLE ), &csbi ); terminal_width = csbi.dwSize.X - 1; terminal_height = 23; //csbi.dwSize.Y - 1; #else // WIN32 if ( isatty( STDERR_FILENO ) ) { if ( std::getenv( "COLUMNS" ) ) { std::istringstream istr( std::getenv( "COLUMNS" ) ); int tmp = 0; istr >> tmp; if ( tmp > 0 ) { terminal_width = tmp; } } if ( std::getenv( "ROWS" ) ) { std::istringstream istr( std::getenv( "ROWS" ) ); int tmp = 0; istr >> tmp; if ( tmp > 0 ) { terminal_height = tmp; } } #if defined(TIOCGWINSZ) struct winsize ts; if ( ioctl( STDERR_FILENO, TIOCGWINSZ, &ts ) >= 0 ) { terminal_width = ts.ws_col; terminal_height = ts.ws_row; } #elif defined(TIOCGSIZE) struct ttysize ts; if ( ioctl( STDERR_FILENO, TIOCGSIZE, &ts ) >= 0 ) { terminal_width = ts.ts_cols; terminal_height = ts.ts_rows; } #endif } #endif show_details = true; show_message = false; #if defined(WIN32) canUI = IsTerminal( 0 ) ? true : false; canProgress = IsTerminal( 2 ) ? true : false; #else // !WIN32 canUI = isatty( STDIN_FILENO ) ? true : false; canProgress = isatty( STDERR_FILENO ) ? true : false; #endif // WIN32 show_ui = canUI; show_progress = canProgress; show_meters = canUI && canProgress; show_channel_meters = false; show_pattern = false; use_stdout = false; randomize = false; shuffle = false; restart = false; playlist_index = 0; output_extension = "wav"; force_overwrite = false; paused = false; } void check_and_sanitize() { if ( filenames.size() == 0 ) { throw args_error_exception(); } if ( use_stdout && ( device != commandlineflags().device || !output_filename.empty() ) ) { throw args_error_exception(); } if ( !output_filename.empty() && ( device != commandlineflags().device || use_stdout ) ) { throw args_error_exception(); } for ( std::vector::iterator i = filenames.begin(); i != filenames.end(); ++i ) { if ( *i == "-" ) { canUI = false; } } show_ui = canUI; if ( mode == ModeNone ) { if ( canUI ) { mode = ModeUI; } else { mode = ModeBatch; } } if ( mode == ModeUI && !canUI ) { throw args_error_exception(); } if ( show_progress && !canProgress ) { throw args_error_exception(); } switch ( mode ) { case ModeNone: throw args_error_exception(); break; case ModeProbe: show_ui = false; show_progress = false; show_meters = false; show_channel_meters = false; show_pattern = false; break; case ModeInfo: show_ui = false; show_progress = false; show_meters = false; show_channel_meters = false; show_pattern = false; break; case ModeUI: break; case ModeBatch: show_meters = false; show_channel_meters = false; show_pattern = false; break; case ModeRender: show_meters = false; show_channel_meters = false; show_pattern = false; show_ui = false; break; } if ( quiet ) { verbose = false; show_ui = false; show_details = false; show_progress = false; show_channel_meters = false; } if ( verbose ) { show_details = true; } if ( channels != 1 && channels != 2 && channels != 4 ) { channels = commandlineflags().channels; } if ( samplerate < 0 ) { samplerate = commandlineflags().samplerate; } if ( mode == ModeRender && !output_filename.empty() ) { std::ostringstream warning; warning << "Warning: --output is deprecated in --render mode. Use --output-type instead." << std::endl; warnings += warning.str(); } if ( mode != ModeRender && output_extension != "wav" ) { std::ostringstream warning; warning << "Warning: --output-type is deprecated in modes other than --render. Use --output instead." << std::endl; warnings += warning.str(); } if ( !output_filename.empty() ) { output_extension = get_extension( output_filename ); } if ( mode == ModeRender && output_extension.empty() ) { throw args_error_exception(); } } }; template < typename Tsample > Tsample convert_sample_to( float val ); template < > float convert_sample_to( float val ) { return val; } template < > std::int16_t convert_sample_to( float val ) { std::int32_t tmp = static_cast( val * 32768.0f ); tmp = std::min( tmp, 32767 ); tmp = std::max( tmp, -32768 ); return static_cast( tmp ); } class write_buffers_interface { protected: virtual ~write_buffers_interface() { return; } public: virtual void write_metadata( std::map metadata ) { (void)metadata; return; } virtual void write_updated_metadata( std::map metadata ) { (void)metadata; return; } virtual void write( const std::vector buffers, std::size_t frames ) = 0; virtual void write( const std::vector buffers, std::size_t frames ) = 0; virtual bool pause() { return false; } virtual bool unpause() { return false; } virtual bool sleep( int /*ms*/ ) { return false; } virtual bool is_dummy() const { return false; } }; class write_buffers_blocking_wrapper : public write_buffers_interface { protected: std::size_t channels; std::size_t sampleQueueMaxFrames; std::deque sampleQueue; protected: virtual ~write_buffers_blocking_wrapper() { return; } protected: write_buffers_blocking_wrapper( const commandlineflags & flags ) : channels(flags.channels) , sampleQueueMaxFrames(0) { return; } void set_queue_size_frames( std::size_t frames ) { sampleQueueMaxFrames = frames; } template < typename Tsample > float pop_queue() { float val = 0.0f; if ( !sampleQueue.empty() ) { val = sampleQueue.front(); sampleQueue.pop_front(); } return convert_sample_to( val ); } template < typename Tsample > void fill_buffer( Tsample * buf, std::size_t framesToRender ) { for ( std::size_t frame = 0; frame < framesToRender; ++frame ) { for ( std::size_t channel = 0; channel < channels; ++channel ) { *buf = pop_queue(); buf++; } } } private: void wait_for_queue_space() { while ( sampleQueue.size() >= sampleQueueMaxFrames * channels ) { unlock(); sleep( 1 ); lock(); } } public: void write( const std::vector buffers, std::size_t frames ) { lock(); for ( std::size_t frame = 0; frame < frames; ++frame ) { for ( std::size_t channel = 0; channel < channels; ++channel ) { wait_for_queue_space(); sampleQueue.push_back( buffers[channel][frame] ); } } unlock(); } void write( const std::vector buffers, std::size_t frames ) { lock(); for ( std::size_t frame = 0; frame < frames; ++frame ) { for ( std::size_t channel = 0; channel < channels; ++channel ) { wait_for_queue_space(); sampleQueue.push_back( buffers[channel][frame] * (1.0f/32768.0f) ); } } unlock(); } virtual void lock() = 0; virtual void unlock() = 0; virtual bool sleep( int ms ) = 0; }; class void_audio_stream : public write_buffers_interface { public: virtual ~void_audio_stream() { return; } public: virtual void write( const std::vector buffers, std::size_t frames ) { (void)buffers; (void)frames; } virtual void write( const std::vector buffers, std::size_t frames ) { (void)buffers; (void)frames; } virtual bool is_dummy() const { return true; } }; class file_audio_stream_base : public write_buffers_interface { protected: file_audio_stream_base() { return; } public: virtual void write_metadata( std::map metadata ) { (void)metadata; return; } virtual void write_updated_metadata( std::map metadata ) { (void)metadata; return; } virtual void write( const std::vector buffers, std::size_t frames ) = 0; virtual void write( const std::vector buffers, std::size_t frames ) = 0; virtual ~file_audio_stream_base() { return; } }; } // namespace openmpt123 #endif // OPENMPT123_HPP libopenmpt-0.3.6+release.autotools/openmpt123/openmpt123_flac.hpp0000644000372100037210000001235212762337506021612 00000000000000/* * openmpt123_flac.hpp * ------------------- * Purpose: libopenmpt command line player * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #ifndef OPENMPT123_FLAC_HPP #define OPENMPT123_FLAC_HPP #include "openmpt123_config.hpp" #include "openmpt123.hpp" #if defined(MPT_WITH_FLAC) #if defined(_MSC_VER) && defined(__clang__) && defined(__c2__) #include #if __STDC__ typedef _off_t off_t; #endif #endif #include #include #include namespace openmpt123 { class flac_stream_raii : public file_audio_stream_base { private: commandlineflags flags; std::string filename; bool called_init; std::vector< std::pair< std::string, std::string > > tags; FLAC__StreamMetadata * flac_metadata[1]; FLAC__StreamEncoder * encoder; std::vector interleaved_buffer; void add_vorbiscomment_field( FLAC__StreamMetadata * vorbiscomment, const std::string & field, const std::string & value ) { if ( !value.empty() ) { FLAC__StreamMetadata_VorbisComment_Entry entry; FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair( &entry, field.c_str(), value.c_str() ); FLAC__metadata_object_vorbiscomment_append_comment( vorbiscomment, entry, false ); } } public: flac_stream_raii( const std::string & filename_, const commandlineflags & flags_, std::ostream & /*log*/ ) : flags(flags_), filename(filename_), called_init(false), encoder(0) { flac_metadata[0] = 0; encoder = FLAC__stream_encoder_new(); if ( !encoder ) { throw exception( "error creating flac encoder" ); } FLAC__stream_encoder_set_channels( encoder, flags.channels ); FLAC__stream_encoder_set_bits_per_sample( encoder, flags.use_float ? 24 : 16 ); FLAC__stream_encoder_set_sample_rate( encoder, flags.samplerate ); FLAC__stream_encoder_set_compression_level( encoder, 8 ); } ~flac_stream_raii() { if ( encoder ) { FLAC__stream_encoder_finish( encoder ); FLAC__stream_encoder_delete( encoder ); encoder = 0; } if ( flac_metadata[0] ) { FLAC__metadata_object_delete( flac_metadata[0] ); flac_metadata[0] = 0; } } void write_metadata( std::map metadata ) { if ( called_init ) { return; } tags.clear(); tags.push_back( std::make_pair( "TITLE", metadata[ "title" ] ) ); tags.push_back( std::make_pair( "ARTIST", metadata[ "artist" ] ) ); tags.push_back( std::make_pair( "DATE", metadata[ "date" ] ) ); tags.push_back( std::make_pair( "COMMENT", metadata[ "message" ] ) ); if ( !metadata[ "type" ].empty() && !metadata[ "tracker" ].empty() ) { tags.push_back( std::make_pair( "SOURCEMEDIA", std::string() + "'" + metadata[ "type" ] + "' tracked music file, made with '" + metadata[ "tracker" ] + "', rendered with '" + get_encoder_tag() + "'" ) ); } else if ( !metadata[ "type_long" ].empty() ) { tags.push_back( std::make_pair( "SOURCEMEDIA", std::string() + "'" + metadata[ "type" ] + "' tracked music file, rendered with '" + get_encoder_tag() + "'" ) ); } else if ( !metadata[ "tracker" ].empty() ) { tags.push_back( std::make_pair( "SOURCEMEDIA", std::string() + "tracked music file, made with '" + metadata[ "tracker" ] + "', rendered with '" + get_encoder_tag() + "'" ) ); } else { tags.push_back( std::make_pair( "SOURCEMEDIA", std::string() + "tracked music file, rendered with '" + get_encoder_tag() + "'" ) ); } tags.push_back( std::make_pair( "ENCODER", get_encoder_tag() ) ); flac_metadata[0] = FLAC__metadata_object_new( FLAC__METADATA_TYPE_VORBIS_COMMENT ); for ( std::vector< std::pair< std::string, std::string > >::iterator tag = tags.begin(); tag != tags.end(); ++tag ) { add_vorbiscomment_field( flac_metadata[0], tag->first, tag->second ); } FLAC__stream_encoder_set_metadata( encoder, flac_metadata, 1 ); } void write( const std::vector buffers, std::size_t frames ) { if ( !called_init ) { FLAC__stream_encoder_init_file( encoder, filename.c_str(), NULL, 0 ); called_init = true; } interleaved_buffer.clear(); for ( std::size_t frame = 0; frame < frames; frame++ ) { for ( std::size_t channel = 0; channel < buffers.size(); channel++ ) { float in = buffers[channel][frame]; if ( in <= -1.0f ) { in = -1.0f; } else if ( in >= 1.0f ) { in = 1.0f; } FLAC__int32 out = mpt_lround( in * (1<<23) ); out = std::max( 0 - (1<<23), out ); out = std::min( out, 0 + (1<<23) - 1 ); interleaved_buffer.push_back( out ); } } FLAC__stream_encoder_process_interleaved( encoder, interleaved_buffer.data(), static_cast( frames ) ); } void write( const std::vector buffers, std::size_t frames ) { if ( !called_init ) { FLAC__stream_encoder_init_file( encoder, filename.c_str(), NULL, 0 ); called_init = true; } interleaved_buffer.clear(); for ( std::size_t frame = 0; frame < frames; frame++ ) { for ( std::size_t channel = 0; channel < buffers.size(); channel++ ) { interleaved_buffer.push_back( buffers[channel][frame] ); } } FLAC__stream_encoder_process_interleaved( encoder, interleaved_buffer.data(), static_cast( frames ) ); } }; } // namespace openmpt123 #endif // MPT_WITH_FLAC #endif // OPENMPT123_FLAC_HPP libopenmpt-0.3.6+release.autotools/openmpt123/openmpt123_portaudio.hpp0000644000372100037210000002334512762337506022717 00000000000000/* * openmpt123_portaudio.hpp * ------------------------ * Purpose: libopenmpt command line player * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #ifndef OPENMPT123_PORTAUDIO_HPP #define OPENMPT123_PORTAUDIO_HPP #include "openmpt123_config.hpp" #include "openmpt123.hpp" #if defined(MPT_WITH_PORTAUDIO) #include namespace openmpt123 { struct portaudio_exception : public exception { portaudio_exception( PaError code ) throw() : exception( Pa_GetErrorText( code ) ) { } }; typedef void (*PaUtilLogCallback ) (const char *log); #ifdef _MSC_VER extern "C" void PaUtil_SetDebugPrintFunction(PaUtilLogCallback cb); #endif class portaudio_raii { private: std::ostream & log; bool log_set; bool portaudio_initialized; static std::ostream * portaudio_log_stream; private: static void portaudio_log_function( const char * log ) { if ( portaudio_log_stream ) { *portaudio_log_stream << "PortAudio: " << log; } } protected: void check_portaudio_error( PaError e ) { if ( e > 0 ) { return; } if ( e == paNoError ) { return; } if ( e == paOutputUnderflowed ) { log << "PortAudio warning: " << Pa_GetErrorText( e ) << std::endl; return; } throw portaudio_exception( e ); } public: portaudio_raii( bool verbose, std::ostream & log ) : log(log), log_set(false), portaudio_initialized(false) { if ( verbose ) { portaudio_log_stream = &log; } else { portaudio_log_stream = 0; } #ifdef _MSC_VER PaUtil_SetDebugPrintFunction( portaudio_log_function ); log_set = true; #endif check_portaudio_error( Pa_Initialize() ); portaudio_initialized = true; if ( verbose ) { *portaudio_log_stream << std::endl; } } ~portaudio_raii() { if ( portaudio_initialized ) { check_portaudio_error( Pa_Terminate() ); portaudio_initialized = false; } if ( log_set ) { #ifdef _MSC_VER PaUtil_SetDebugPrintFunction( NULL ); log_set = false; #endif } portaudio_log_stream = 0; } }; std::ostream * portaudio_raii::portaudio_log_stream = 0; class portaudio_stream_blocking_raii : public portaudio_raii, public write_buffers_interface { private: PaStream * stream; bool interleaved; std::size_t channels; std::vector sampleBufFloat; std::vector sampleBufInt; public: portaudio_stream_blocking_raii( commandlineflags & flags, std::ostream & log ) : portaudio_raii(flags.verbose, log) , stream(NULL) , interleaved(false) , channels(flags.channels) { PaStreamParameters streamparameters; std::memset( &streamparameters, 0, sizeof(PaStreamParameters) ); std::istringstream device_string( flags.device ); int device = -1; device_string >> device; streamparameters.device = ( device == -1 ) ? Pa_GetDefaultOutputDevice() : device; streamparameters.channelCount = flags.channels; streamparameters.sampleFormat = ( flags.use_float ? paFloat32 : paInt16 ) | paNonInterleaved; if ( flags.buffer == default_high ) { streamparameters.suggestedLatency = Pa_GetDeviceInfo( streamparameters.device )->defaultHighOutputLatency; flags.buffer = static_cast( Pa_GetDeviceInfo( streamparameters.device )->defaultHighOutputLatency * 1000.0 ); } else if ( flags.buffer == default_low ) { streamparameters.suggestedLatency = Pa_GetDeviceInfo( streamparameters.device )->defaultLowOutputLatency; flags.buffer = static_cast( Pa_GetDeviceInfo( streamparameters.device )->defaultLowOutputLatency * 1000.0 ); } else { streamparameters.suggestedLatency = flags.buffer * 0.001; } unsigned long framesperbuffer = 0; if ( flags.mode != ModeUI ) { framesperbuffer = paFramesPerBufferUnspecified; flags.period = 50; flags.period = std::min( flags.period, flags.buffer / 3 ); } else if ( flags.period == default_high ) { framesperbuffer = paFramesPerBufferUnspecified; flags.period = 50; flags.period = std::min( flags.period, flags.buffer / 3 ); } else if ( flags.period == default_low ) { framesperbuffer = paFramesPerBufferUnspecified; flags.period = 10; flags.period = std::min( flags.period, flags.buffer / 3 ); } else { framesperbuffer = flags.period * flags.samplerate / 1000; } if ( flags.period <= 0 ) { flags.period = 1; } flags.apply_default_buffer_sizes(); if ( flags.verbose ) { log << "PortAudio:" << std::endl; log << " device: " << streamparameters.device << " [ " << Pa_GetHostApiInfo( Pa_GetDeviceInfo( streamparameters.device )->hostApi )->name << " / " << Pa_GetDeviceInfo( streamparameters.device )->name << " ] " << std::endl; log << " low latency: " << Pa_GetDeviceInfo( streamparameters.device )->defaultLowOutputLatency << std::endl; log << " high latency: " << Pa_GetDeviceInfo( streamparameters.device )->defaultHighOutputLatency << std::endl; log << " suggested latency: " << streamparameters.suggestedLatency << std::endl; log << " frames per buffer: " << framesperbuffer << std::endl; log << " ui redraw: " << flags.period << std::endl; } PaError e = PaError(); e = Pa_OpenStream( &stream, NULL, &streamparameters, flags.samplerate, framesperbuffer, ( flags.dither > 0 ) ? paNoFlag : paDitherOff, NULL, NULL ); if ( e != paNoError ) { // Non-interleaved failed, try interleaved next. // This might help broken portaudio on MacOS X. streamparameters.sampleFormat &= ~paNonInterleaved; e = Pa_OpenStream( &stream, NULL, &streamparameters, flags.samplerate, framesperbuffer, ( flags.dither > 0 ) ? paNoFlag : paDitherOff, NULL, NULL ); if ( e == paNoError ) { interleaved = true; } check_portaudio_error( e ); } check_portaudio_error( Pa_StartStream( stream ) ); if ( flags.verbose ) { log << " channels: " << streamparameters.channelCount << std::endl; log << " sampleformat: " << ( ( ( streamparameters.sampleFormat & ~paNonInterleaved ) == paFloat32 ) ? "paFloat32" : "paInt16" ) << std::endl; log << " latency: " << Pa_GetStreamInfo( stream )->outputLatency << std::endl; log << " samplerate: " << Pa_GetStreamInfo( stream )->sampleRate << std::endl; log << std::endl; } } ~portaudio_stream_blocking_raii() { if ( stream ) { PaError stopped = Pa_IsStreamStopped( stream ); check_portaudio_error( stopped ); if ( !stopped ) { check_portaudio_error( Pa_StopStream( stream ) ); } check_portaudio_error( Pa_CloseStream( stream ) ); stream = NULL; } } private: template void write_frames( const Tsample * buffer, std::size_t frames ) { while ( frames > 0 ) { unsigned long chunk_frames = static_cast( std::min( frames, std::numeric_limits::max() ) ); check_portaudio_error( Pa_WriteStream( stream, buffer, chunk_frames ) ); buffer += chunk_frames * channels; frames -= chunk_frames; } } template void write_frames( std::vector buffers, std::size_t frames ) { while ( frames > 0 ) { unsigned long chunk_frames = static_cast( std::min( frames, std::numeric_limits::max() ) ); check_portaudio_error( Pa_WriteStream( stream, buffers.data(), chunk_frames ) ); for ( std::size_t channel = 0; channel < channels; ++channel ) { buffers[channel] += chunk_frames; } frames -= chunk_frames; } } public: void write( const std::vector buffers, std::size_t frames ) { if ( interleaved ) { sampleBufFloat.clear(); for ( std::size_t frame = 0; frame < frames; ++frame ) { for ( std::size_t channel = 0; channel < channels; ++channel ) { sampleBufFloat.push_back( buffers[channel][frame] ); } } write_frames( sampleBufFloat.data(), frames ); } else { write_frames( buffers, frames ); } } void write( const std::vector buffers, std::size_t frames ) { if ( interleaved ) { sampleBufInt.clear(); for ( std::size_t frame = 0; frame < frames; ++frame ) { for ( std::size_t channel = 0; channel < channels; ++channel ) { sampleBufInt.push_back( buffers[channel][frame] ); } } write_frames( sampleBufInt.data(), frames ); } else { write_frames( buffers, frames ); } } bool unpause() { check_portaudio_error( Pa_StartStream( stream ) ); return true; } bool pause() { check_portaudio_error( Pa_StopStream( stream ) ); return true; } bool sleep( int ms ) { Pa_Sleep( ms ); return true; } }; #define portaudio_stream_raii portaudio_stream_blocking_raii static std::string show_portaudio_devices( std::ostream & log ) { std::ostringstream devices; devices << " portaudio:" << std::endl; portaudio_raii portaudio( false, log ); for ( PaDeviceIndex i = 0; i < Pa_GetDeviceCount(); ++i ) { if ( Pa_GetDeviceInfo( i ) && Pa_GetDeviceInfo( i )->maxOutputChannels > 0 ) { devices << " " << i << ": "; if ( Pa_GetHostApiInfo( Pa_GetDeviceInfo( i )->hostApi ) && Pa_GetHostApiInfo( Pa_GetDeviceInfo( i )->hostApi )->name ) { devices << Pa_GetHostApiInfo( Pa_GetDeviceInfo( i )->hostApi )->name; } else { devices << "Host API " << Pa_GetDeviceInfo( i )->hostApi; } if ( Pa_GetHostApiInfo( Pa_GetDeviceInfo( i )->hostApi ) ) { if ( i == Pa_GetHostApiInfo( Pa_GetDeviceInfo( i )->hostApi )->defaultOutputDevice ) { devices << " (default)"; } } devices << " - "; if ( Pa_GetDeviceInfo( i )->name ) { devices << Pa_GetDeviceInfo( i )->name; } else { devices << "Device " << i; } devices << " ("; devices << "high latency: " << Pa_GetDeviceInfo( i )->defaultHighOutputLatency; devices << ", "; devices << "low latency: " << Pa_GetDeviceInfo( i )->defaultLowOutputLatency; devices << ")"; devices << std::endl; } } return devices.str(); } } // namespace openmpt123 #endif // MPT_WITH_PORTAUDIO #endif // OPENMPT123_PORTAUDIO_HPP libopenmpt-0.3.6+release.autotools/openmpt123/openmpt123_sdl2.hpp0000644000372100037210000001212712674772457021563 00000000000000/* * openmpt123_sdl2.hpp * ------------------- * Purpose: libopenmpt command line player * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #ifndef OPENMPT123_SDL2_HPP #define OPENMPT123_SDL2_HPP #include "openmpt123_config.hpp" #include "openmpt123.hpp" #if defined(MPT_WITH_SDL2) #include #ifdef main #undef main #endif #ifdef SDL_main #undef SDL_main #endif namespace openmpt123 { struct sdl2_exception : public exception { sdl2_exception( int /*code*/ ) throw() : exception( "SDL2 error" ) { } }; static void check_sdl2_error( int e ) { if ( e < 0 ) { throw sdl2_exception( e ); return; } } class sdl2_raii { public: sdl2_raii( Uint32 flags ) { check_sdl2_error( SDL_Init( flags ) ); } ~sdl2_raii() { SDL_Quit(); } }; class sdl2_stream_raii : public write_buffers_blocking_wrapper { private: std::ostream & log; sdl2_raii sdl2; int dev; std::size_t channels; bool use_float; protected: std::uint32_t round_up_power2(std::uint32_t x) { std::uint32_t result = 1; while ( result < x ) { result *= 2; } return result; } public: sdl2_stream_raii( commandlineflags & flags, std::ostream & log_ ) : write_buffers_blocking_wrapper(flags) , log(log_) , sdl2( SDL_INIT_NOPARACHUTE | SDL_INIT_TIMER | SDL_INIT_AUDIO ) , dev(-1) , channels(flags.channels) , use_float(flags.use_float) { if ( flags.buffer == default_high ) { flags.buffer = 160; } else if ( flags.buffer == default_low ) { flags.buffer = 80; } if ( flags.period == default_high ) { flags.period = 20; } else if ( flags.period == default_low ) { flags.period = 10; } flags.apply_default_buffer_sizes(); SDL_AudioSpec audiospec; std::memset( &audiospec, 0, sizeof( SDL_AudioSpec ) ); audiospec.freq = flags.samplerate; audiospec.format = ( flags.use_float ? AUDIO_F32SYS : AUDIO_S16SYS ); audiospec.channels = flags.channels; audiospec.silence = 0; audiospec.samples = round_up_power2( ( flags.buffer * flags.samplerate ) / ( 1000 * 2 ) ); audiospec.size = audiospec.samples * audiospec.channels * ( flags.use_float ? sizeof( float ) : sizeof( std::int16_t ) ); audiospec.callback = &sdl2_callback_wrapper; audiospec.userdata = this; if ( flags.verbose ) { log << "SDL2:" << std::endl; log << " latency: " << ( audiospec.samples * 2.0 / flags.samplerate ) << " (2 * " << audiospec.samples << ")" << std::endl; log << std::endl; } set_queue_size_frames( round_up_power2( ( flags.buffer * flags.samplerate ) / ( 1000 * 2 ) ) ); SDL_AudioSpec audiospec_obtained; std::memset( &audiospec_obtained, 0, sizeof( SDL_AudioSpec ) ); std::memcpy( &audiospec_obtained, &audiospec, sizeof( SDL_AudioSpec ) ); dev = SDL_OpenAudioDevice( NULL, 0, &audiospec, &audiospec_obtained, 0 ); if ( dev < 0 ) { check_sdl2_error( dev ); } else if ( dev == 0 ) { check_sdl2_error( -1 ); } SDL_PauseAudioDevice( dev, 0 ); } ~sdl2_stream_raii() { SDL_PauseAudioDevice( dev, 1 ); SDL_CloseAudioDevice( dev ); } private: static void sdl2_callback_wrapper( void * userdata, Uint8 * stream, int len ) { return reinterpret_cast( userdata )->sdl2_callback( stream, len ); } void sdl2_callback( Uint8 * stream, int len ) { return ( use_float ? sdl2_callback_impl( stream, len ) : sdl2_callback_impl( stream, len ) ); } template < typename Tsample > void sdl2_callback_impl( Uint8 * stream, int len ) { std::size_t framesToRender = len / sizeof( Tsample ) / channels; for ( std::size_t frame = 0; frame < framesToRender; ++frame ) { for ( std::size_t channel = 0; channel < channels; ++channel ) { Tsample sample = pop_queue(); std::memcpy( stream, &sample, sizeof( Tsample ) ); stream += sizeof( Tsample ); } } } public: bool pause() { SDL_PauseAudioDevice( dev, 1 ); return true; } bool unpause() { SDL_PauseAudioDevice( dev, 0 ); return true; } void lock() { SDL_LockAudioDevice( dev ); } void unlock() { SDL_UnlockAudioDevice( dev ); } bool sleep( int ms ) { SDL_Delay( ms ); return true; } }; static std::string show_sdl2_devices( std::ostream & /* log */ ) { std::ostringstream devices; std::size_t device_index = 0; devices << " SDL2:" << std::endl; sdl2_raii sdl2( SDL_INIT_NOPARACHUTE | SDL_INIT_AUDIO ); for ( int driver = 0; driver < SDL_GetNumAudioDrivers(); ++driver ) { const char * driver_name = SDL_GetAudioDriver( driver ); if ( !driver_name ) { continue; } if ( std::string( driver_name ).empty() ) { continue; } if ( SDL_AudioInit( driver_name ) < 0 ) { continue; } for ( int device = 0; device < SDL_GetNumAudioDevices( 0 ); ++device ) { const char * device_name = SDL_GetAudioDeviceName( device, 0 ); if ( !device_name ) { continue; } if ( std::string( device_name ).empty() ) { continue; } devices << " " << device_index << ": " << driver_name << " - " << device_name << std::endl; device_index++; } SDL_AudioQuit(); } return devices.str(); } } // namespace openmpt123 #endif // MPT_WITH_SDL2 #endif // OPENMPT123_SDL2_HPP libopenmpt-0.3.6+release.autotools/openmpt123/openmpt123_raw.hpp0000644000372100037210000000352612762337506021501 00000000000000/* * openmpt123_raw.hpp * ------------------ * Purpose: libopenmpt command line player * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #ifndef OPENMPT123_RAW_HPP #define OPENMPT123_RAW_HPP #include "openmpt123_config.hpp" #include "openmpt123.hpp" #include namespace openmpt123 { class raw_stream_raii : public file_audio_stream_base { private: commandlineflags flags; std::ofstream file; std::vector interleaved_float_buffer; std::vector interleaved_int_buffer; public: raw_stream_raii( const std::string & filename, const commandlineflags & flags_, std::ostream & /*log*/ ) : flags(flags_), file(filename.c_str(), std::ios::binary) { return; } ~raw_stream_raii() { return; } void write_metadata( std::map /* metadata */ ) { return; } void write( const std::vector buffers, std::size_t frames ) { interleaved_float_buffer.clear(); for ( std::size_t frame = 0; frame < frames; frame++ ) { for ( std::size_t channel = 0; channel < buffers.size(); channel++ ) { interleaved_float_buffer.push_back( buffers[channel][frame] ); } } file.write( reinterpret_cast( interleaved_float_buffer.data() ), frames * buffers.size() * sizeof( float ) ); } void write( const std::vector buffers, std::size_t frames ) { interleaved_int_buffer.clear(); for ( std::size_t frame = 0; frame < frames; frame++ ) { for ( std::size_t channel = 0; channel < buffers.size(); channel++ ) { interleaved_int_buffer.push_back( buffers[channel][frame] ); } } file.write( reinterpret_cast( interleaved_int_buffer.data() ), frames * buffers.size() * sizeof( std::int16_t ) ); } }; } // namespace openmpt123 #endif // OPENMPT123_RAW_HPP libopenmpt-0.3.6+release.autotools/openmpt123/openmpt123_mmio.hpp0000644000372100037210000001020612751306463021636 00000000000000/* * openmpt123_mmio.hpp * ------------------- * Purpose: libopenmpt command line player * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #ifndef OPENMPT123_MMIO_HPP #define OPENMPT123_MMIO_HPP #include "openmpt123_config.hpp" #include "openmpt123.hpp" #if defined(MPT_WITH_MMIO) namespace openmpt123 { #define CHECKED(x) do { \ HRESULT err = x; \ if ( err != 0 ) { \ throw exception( "error writing wave file" ); \ } \ } while(0) #define UNCHECKED(x) do { \ HRESULT err = x; \ if ( err != 0 ) { \ log << "error writing wave file" << std::endl; \ } \ } while(0) class mmio_stream_raii : public file_audio_stream_base { private: std::ostream & log; commandlineflags flags; WAVEFORMATEX waveformatex; HMMIO mmio; MMCKINFO WAVE_chunk; MMCKINFO fmt__chunk; MMCKINFO data_chunk; MMIOINFO data_info; public: mmio_stream_raii( const std::string & filename, const commandlineflags & flags_, std::ostream & log_ ) : log(log_), flags(flags_), mmio(NULL) { ZeroMemory( &waveformatex, sizeof( WAVEFORMATEX ) ); waveformatex.cbSize = 0; waveformatex.wFormatTag = flags.use_float ? WAVE_FORMAT_IEEE_FLOAT : WAVE_FORMAT_PCM; waveformatex.nChannels = flags.channels; waveformatex.nSamplesPerSec = flags.samplerate; waveformatex.wBitsPerSample = flags.use_float ? 32 : 16; waveformatex.nBlockAlign = flags.channels * ( waveformatex.wBitsPerSample / 8 ); waveformatex.nAvgBytesPerSec = waveformatex.nSamplesPerSec * waveformatex.nBlockAlign; #if defined(WIN32) && defined(UNICODE) wchar_t * tmp = _wcsdup( utf8_to_wstring( filename ).c_str() ); mmio = mmioOpen( tmp, NULL, MMIO_ALLOCBUF | MMIO_READWRITE | MMIO_CREATE ); free( tmp ); tmp = 0; #else char * tmp = strdup( filename.c_str() ); mmio = mmioOpen( tmp, NULL, MMIO_ALLOCBUF | MMIO_READWRITE | MMIO_CREATE ); free( tmp ); tmp = 0; #endif ZeroMemory( &WAVE_chunk, sizeof( MMCKINFO ) ); WAVE_chunk.fccType = mmioFOURCC('W', 'A', 'V', 'E'); CHECKED(mmioCreateChunk( mmio, &WAVE_chunk, MMIO_CREATERIFF )); ZeroMemory( &fmt__chunk, sizeof( MMCKINFO ) ); fmt__chunk.ckid = mmioFOURCC('f', 'm', 't', ' '); fmt__chunk.cksize = sizeof( WAVEFORMATEX ); CHECKED(mmioCreateChunk( mmio, &fmt__chunk, 0 )); mmioWrite( mmio, (const char*)&waveformatex, sizeof( WAVEFORMATEX ) ); CHECKED(mmioAscend( mmio, &fmt__chunk, 0 )); ZeroMemory( &data_chunk, sizeof( MMCKINFO ) ); data_chunk.ckid = mmioFOURCC('d', 'a', 't', 'a'); data_chunk.cksize = 0; CHECKED(mmioCreateChunk( mmio, &data_chunk, 0 )); ZeroMemory( &data_info, sizeof( MMIOINFO ) ); CHECKED(mmioGetInfo( mmio, &data_info, 0 )); } void write( const std::vector buffers, std::size_t frames ) { for ( std::size_t frame = 0; frame < frames; frame++ ) { for ( std::size_t channel = 0; channel < buffers.size(); channel++ ) { if ( data_info.pchEndWrite - data_info.pchNext < static_cast( sizeof( float ) ) ) { data_info.dwFlags |= MMIO_DIRTY; CHECKED(mmioAdvance( mmio, &data_info, MMIO_WRITE )); } std::memcpy( data_info.pchNext, &( buffers[channel][frame] ), sizeof( float ) ); data_info.pchNext += sizeof( float ); } } } void write( const std::vector buffers, std::size_t frames ) { for ( std::size_t frame = 0; frame < frames; frame++ ) { for ( std::size_t channel = 0; channel < buffers.size(); channel++ ) { if ( data_info.pchEndWrite - data_info.pchNext < static_cast( sizeof( std::int16_t ) ) ) { data_info.dwFlags |= MMIO_DIRTY; CHECKED(mmioAdvance( mmio, &data_info, MMIO_WRITE )); } std::memcpy( data_info.pchNext, &( buffers[channel][frame] ), sizeof( std::int16_t ) ); data_info.pchNext += sizeof( std::int16_t ); } } } ~mmio_stream_raii() { data_info.dwFlags |= MMIO_DIRTY; UNCHECKED(mmioSetInfo( mmio, &data_info, 0 )); UNCHECKED(mmioAscend( mmio, &data_chunk, 0 )); UNCHECKED(mmioAscend( mmio, &WAVE_chunk, 0 )); UNCHECKED(mmioClose( mmio, 0 )); mmio = NULL; } }; #undef CHECKED } // namespace openmpt123 #endif // MPT_WITH_MMIO #endif // OPENMPT123_MMIO_HPP libopenmpt-0.3.6+release.autotools/openmpt123/openmpt123_sndfile.hpp0000644000372100037210000001534512254575533022336 00000000000000/* * openmpt123_sndfile.hpp * ---------------------- * Purpose: libopenmpt command line player * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #ifndef OPENMPT123_SNDFILE_HPP #define OPENMPT123_SNDFILE_HPP #include "openmpt123_config.hpp" #include "openmpt123.hpp" #if defined(MPT_WITH_SNDFILE) #include namespace openmpt123 { class sndfile_stream_raii : public file_audio_stream_base { private: commandlineflags flags; std::ostream & log; SNDFILE * sndfile; std::vector interleaved_float_buffer; std::vector interleaved_int_buffer; private: enum match_mode_enum { match_print, match_recurse, match_exact, match_better, match_any }; std::string match_mode_to_string( match_mode_enum match_mode ) { switch ( match_mode ) { case match_print : return "print" ; break; case match_recurse: return "recurse"; break; case match_exact : return "exact" ; break; case match_better : return "better" ; break; case match_any : return "any" ; break; } return ""; } int matched_result( const SF_FORMAT_INFO & format_info, const SF_FORMAT_INFO & subformat_info, match_mode_enum match_mode ) { if ( flags.verbose ) { log << "sndfile: using format '" << format_info.name << " (" << format_info.extension << ")" << " / " << subformat_info.name << "', " << "match: " << match_mode_to_string( match_mode ) << std::endl; } return ( format_info.format & SF_FORMAT_TYPEMASK ) | subformat_info.format; } int find_format( const std::string & extension, match_mode_enum match_mode ) { if ( match_mode == match_recurse ) { int result = 0; result = find_format( extension, match_exact ); if ( result ) { return result; } result = find_format( extension, match_better ); if ( result ) { return result; } result = find_format( extension, match_any ); if ( result ) { return result; } if ( result ) { return result; } return 0; } int format = 0; int major_count; sf_command( 0, SFC_GET_FORMAT_MAJOR_COUNT, &major_count, sizeof( int ) ); for ( int m = 0; m < major_count; m++ ) { SF_FORMAT_INFO format_info; format_info.format = m; sf_command( 0, SFC_GET_FORMAT_MAJOR, &format_info, sizeof( SF_FORMAT_INFO ) ); format = format_info.format; int subtype_count; sf_command( 0, SFC_GET_FORMAT_SUBTYPE_COUNT, &subtype_count, sizeof( int ) ); for ( int s = 0; s < subtype_count; s++ ) { SF_FORMAT_INFO subformat_info; subformat_info.format = s; sf_command( 0, SFC_GET_FORMAT_SUBTYPE, &subformat_info, sizeof( SF_FORMAT_INFO ) ); format = ( format & SF_FORMAT_TYPEMASK ) | subformat_info.format; SF_INFO sfinfo; std::memset( &sfinfo, 0, sizeof( SF_INFO ) ); sfinfo.channels = flags.channels; sfinfo.format = format; if ( sf_format_check( &sfinfo ) ) { switch ( match_mode ) { case match_print: log << "sndfile: " << ( format_info.name ? format_info.name : "" ) << " (" << ( format_info.extension ? format_info.extension : "" ) << ")" << " / " << ( subformat_info.name ? subformat_info.name : "" ) << " [" << std::setbase(16) << std::setw(8) << std::setfill('0') << format_info.format << "|" << std::setbase(16) << std::setw(8) << std::setfill('0') << subformat_info.format << "]" << std::endl; break; case match_recurse: break; case match_exact: if ( extension == format_info.extension ) { if ( flags.use_float && ( subformat_info.format == SF_FORMAT_FLOAT ) ) { return matched_result( format_info, subformat_info, match_mode ); } else if ( !flags.use_float && ( subformat_info.format == SF_FORMAT_PCM_16 ) ) { return matched_result( format_info, subformat_info, match_mode ); } } break; case match_better: if ( extension == format_info.extension ) { if ( flags.use_float && ( subformat_info.format == SF_FORMAT_FLOAT || subformat_info.format == SF_FORMAT_DOUBLE ) ) { return matched_result( format_info, subformat_info, match_mode ); } else if ( !flags.use_float && ( subformat_info.format & ( subformat_info.format == SF_FORMAT_PCM_16 || subformat_info.format == SF_FORMAT_PCM_24 || subformat_info.format == SF_FORMAT_PCM_32 ) ) ) { return matched_result( format_info, subformat_info, match_mode ); } } break; case match_any: if ( extension == format_info.extension ) { return matched_result( format_info, subformat_info, match_mode ); } break; } } } } return 0; } void write_metadata_field( int str_type, const std::string & str ) { if ( !str.empty() ) { sf_set_string( sndfile, str_type, str.c_str() ); } } public: sndfile_stream_raii( const std::string & filename, const commandlineflags & flags_, std::ostream & log_ ) : flags(flags_), log(log_), sndfile(0) { if ( flags.verbose ) { find_format( "", match_print ); log << std::endl; } int format = find_format( flags.output_extension, match_recurse ); if ( !format ) { throw exception( "unknown file type" ); } SF_INFO info; std::memset( &info, 0, sizeof( SF_INFO ) ); info.samplerate = flags.samplerate; info.channels = flags.channels; info.format = format; sndfile = sf_open( filename.c_str(), SFM_WRITE, &info ); } ~sndfile_stream_raii() { sf_close( sndfile ); sndfile = 0; } void write_metadata( std::map metadata ) { write_metadata_field( SF_STR_TITLE, metadata[ "title" ] ); write_metadata_field( SF_STR_ARTIST, metadata[ "artist" ] ); write_metadata_field( SF_STR_DATE, metadata[ "date" ] ); write_metadata_field( SF_STR_COMMENT, metadata[ "message" ] ); write_metadata_field( SF_STR_SOFTWARE, append_software_tag( metadata[ "tracker" ] ) ); } void write( const std::vector buffers, std::size_t frames ) { interleaved_float_buffer.clear(); for ( std::size_t frame = 0; frame < frames; frame++ ) { for ( std::size_t channel = 0; channel < buffers.size(); channel++ ) { interleaved_float_buffer.push_back( buffers[channel][frame] ); } } sf_writef_float( sndfile, interleaved_float_buffer.data(), frames ); } void write( const std::vector buffers, std::size_t frames ) { interleaved_int_buffer.clear(); for ( std::size_t frame = 0; frame < frames; frame++ ) { for ( std::size_t channel = 0; channel < buffers.size(); channel++ ) { interleaved_int_buffer.push_back( buffers[channel][frame] ); } } sf_writef_short( sndfile, interleaved_int_buffer.data(), frames ); } }; } // namespace openmpt123 #endif // MPT_WITH_SNDFILE #endif // OPENMPT123_SNDFILE_HPP libopenmpt-0.3.6+release.autotools/openmpt123/openmpt123_pulseaudio.hpp0000644000372100037210000001141612762626610023054 00000000000000/* * openmpt123_pulseaudio.hpp * ------------------------- * Purpose: libopenmpt command line player * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #ifndef OPENMPT123_PULSEAUDIO_HPP #define OPENMPT123_PULSEAUDIO_HPP #include "openmpt123_config.hpp" #include "openmpt123.hpp" #if defined(MPT_WITH_PULSEAUDIO) #include #include namespace openmpt123 { struct pulseaudio_exception : public exception { static std::string error_to_string( int error ) { try { if ( error == 0 ) { return std::string(); } std::ostringstream e; const char * str = pa_strerror( error ); if ( !str ) { e << "error=" << error; return e.str(); } if ( std::strlen(str) == 0 ) { e << "error=" << error; return e.str(); } e << str << " (error=" << error << ")"; return e.str(); } catch ( const std::bad_alloc & ) { return std::string(); } } pulseaudio_exception( int error ) throw() : exception( error_to_string( error ) ) { } }; class pulseaudio_stream_raii : public write_buffers_interface { private: pa_simple * stream; std::size_t channels; std::size_t sampleSize; std::vector sampleBufFloat; std::vector sampleBufInt; public: pulseaudio_stream_raii( commandlineflags & flags, std::ostream & /* log */ ) : stream(NULL) , channels(flags.channels) , sampleSize(flags.use_float ? sizeof( float ) : sizeof( std::int16_t )) { int error = 0; pa_sample_spec ss; std::memset( &ss, 0, sizeof( pa_sample_spec ) ); ss.format = ( flags.use_float ? PA_SAMPLE_FLOAT32 : PA_SAMPLE_S16NE ); ss.rate = flags.samplerate; ss.channels = flags.channels; pa_buffer_attr ba; std::memset( &ba, 0, sizeof( pa_buffer_attr ) ); bool use_ba = false; if ( flags.buffer != default_high && flags.buffer != default_low ) { use_ba = true; ba.maxlength = channels * sampleSize * ( flags.buffer * flags.samplerate / 1000 ); } else { ba.maxlength = static_cast(-1); } if ( flags.period != default_high && flags.period != default_low ) { use_ba = true; ba.minreq = channels * sampleSize * ( flags.period * flags.samplerate / 1000 ); if ( ba.maxlength != static_cast(-1) ) { ba.tlength = ba.maxlength - ba.minreq; ba.prebuf = ba.tlength; } else { ba.tlength = static_cast(-1); ba.prebuf = static_cast(-1); } } else { ba.minreq = static_cast(-1); ba.tlength = static_cast(-1); ba.prebuf = static_cast(-1); } ba.fragsize = 0; flags.apply_default_buffer_sizes(); sampleBufFloat.resize( channels * ( flags.ui_redraw_interval * flags.samplerate / 1000 ) ); sampleBufInt.resize( channels * ( flags.ui_redraw_interval * flags.samplerate / 1000 ) ); stream = pa_simple_new( NULL, "openmpt123", PA_STREAM_PLAYBACK, NULL, "openmpt123", &ss, NULL, ( use_ba ? &ba : NULL ), &error ); if ( !stream ) { throw pulseaudio_exception( error ); } } ~pulseaudio_stream_raii() { int error = 0; if ( stream ) { error = 0; if ( pa_simple_drain( stream, &error ) < 0 ) { // throw pulseaudio_exception( error ); } pa_simple_free( stream ); stream = NULL; } } private: template void write_frames( const Tsample * buffer, std::size_t frames ) { int error = 0; if ( pa_simple_write( stream, buffer, frames * channels * sampleSize, &error ) < 0 ) { throw pulseaudio_exception( error ); } } public: void write( const std::vector buffers, std::size_t frames ) { sampleBufFloat.clear(); for ( std::size_t frame = 0; frame < frames; ++frame ) { for ( std::size_t channel = 0; channel < channels; ++channel ) { sampleBufFloat.push_back( buffers[channel][frame] ); } } write_frames( sampleBufFloat.data(), frames ); } void write( const std::vector buffers, std::size_t frames ) { sampleBufInt.clear(); for ( std::size_t frame = 0; frame < frames; ++frame ) { for ( std::size_t channel = 0; channel < channels; ++channel ) { sampleBufInt.push_back( buffers[channel][frame] ); } } write_frames( sampleBufInt.data(), frames ); } bool unpause() { return true; } bool pause() { int error = 0; error = 0; if ( pa_simple_drain( stream, &error ) < 0 ) { throw pulseaudio_exception( error ); } return true; } bool sleep( int ms ) { pa_msleep( ms ); return true; } }; static std::string show_pulseaudio_devices( std::ostream & /* log */ ) { std::ostringstream devices; devices << " pulseaudio:" << std::endl; devices << " " << "0" << ": Default Device" << std::endl; return devices.str(); } } // namespace openmpt123 #endif // MPT_WITH_PULSEAUDIO #endif // OPENMPT123_PULSEAUDIO_HPP libopenmpt-0.3.6+release.autotools/openmpt123/openmpt123_sdl.hpp0000644000372100037210000000654312527676474021505 00000000000000/* * openmpt123_sdl.hpp * ------------------ * Purpose: libopenmpt command line player * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #ifndef OPENMPT123_SDL_HPP #define OPENMPT123_SDL_HPP #include "openmpt123_config.hpp" #include "openmpt123.hpp" #if defined(MPT_WITH_SDL) #include #ifdef main #undef main #endif #ifdef SDL_main #undef SDL_main #endif namespace openmpt123 { struct sdl_exception : public exception { sdl_exception( int /*code*/ ) throw() : exception( "SDL error" ) { } }; class sdl_stream_raii : public write_buffers_blocking_wrapper { private: std::ostream & log; std::size_t channels; protected: void check_sdl_error( int e ) { if ( e < 0 ) { throw sdl_exception( e ); return; } } std::uint32_t round_up_power2(std::uint32_t x) { std::uint32_t result = 1; while ( result < x ) { result *= 2; } return result; } public: sdl_stream_raii( commandlineflags & flags, std::ostream & log_ ) : write_buffers_blocking_wrapper(flags) , log(log_) , channels(flags.channels) { if ( flags.buffer == default_high ) { flags.buffer = 160; } else if ( flags.buffer == default_low ) { flags.buffer = 80; } if ( flags.period == default_high ) { flags.period = 20; } else if ( flags.period == default_low ) { flags.period = 10; } flags.apply_default_buffer_sizes(); check_sdl_error( SDL_Init( SDL_INIT_NOPARACHUTE | SDL_INIT_TIMER | SDL_INIT_AUDIO ) ); SDL_AudioSpec audiospec; std::memset( &audiospec, 0, sizeof( SDL_AudioSpec ) ); audiospec.freq = flags.samplerate; audiospec.format = AUDIO_S16SYS; audiospec.channels = flags.channels; audiospec.silence = 0; audiospec.samples = round_up_power2( ( flags.buffer * flags.samplerate ) / ( 1000 * 2 ) ); audiospec.size = audiospec.samples * audiospec.channels * sizeof( std::int16_t ); audiospec.callback = &sdl_callback_wrapper; audiospec.userdata = this; if ( flags.verbose ) { log << "SDL:" << std::endl; log << " latency: " << ( audiospec.samples * 2.0 / flags.samplerate ) << " (2 * " << audiospec.samples << ")" << std::endl; log << std::endl; } set_queue_size_frames( round_up_power2( ( flags.buffer * flags.samplerate ) / ( 1000 * 2 ) ) ); check_sdl_error( SDL_OpenAudio( &audiospec, NULL ) ); SDL_PauseAudio( 0 ); } ~sdl_stream_raii() { SDL_PauseAudio( 1 ); SDL_CloseAudio(); SDL_Quit(); } private: static void sdl_callback_wrapper( void * userdata, Uint8 * stream, int len ) { return reinterpret_cast( userdata )->sdl_callback( stream, len ); } void sdl_callback( Uint8 * stream, int len ) { std::size_t framesToRender = len / sizeof( std::int16_t ) / channels; for ( std::size_t frame = 0; frame < framesToRender; ++frame ) { for ( std::size_t channel = 0; channel < channels; ++channel ) { std::int16_t sample = pop_queue(); std::memcpy( stream, &sample, sizeof( std::int16_t ) ); stream += sizeof( std::int16_t ); } } } public: bool pause() { SDL_PauseAudio( 1 ); return true; } bool unpause() { SDL_PauseAudio( 0 ); return true; } void lock() { SDL_LockAudio(); } void unlock() { SDL_UnlockAudio(); } bool sleep( int ms ) { SDL_Delay( ms ); return true; } }; } // namespace openmpt123 #endif // MPT_WITH_SDL #endif // OPENMPT123_SDL_HPP libopenmpt-0.3.6+release.autotools/openmpt123/openmpt123_stdout.hpp0000644000372100037210000000307512762337506022231 00000000000000/* * openmpt123_stdout.hpp * --------------------- * Purpose: libopenmpt command line player * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #ifndef OPENMPT123_STDOUT_HPP #define OPENMPT123_STDOUT_HPP #include "openmpt123_config.hpp" #include "openmpt123.hpp" namespace openmpt123 { class stdout_stream_raii : public write_buffers_interface { private: std::vector interleaved_float_buffer; std::vector interleaved_int_buffer; public: stdout_stream_raii() { return; } public: void write( const std::vector buffers, std::size_t frames ) { interleaved_float_buffer.clear(); for ( std::size_t frame = 0; frame < frames; frame++ ) { for ( std::size_t channel = 0; channel < buffers.size(); channel++ ) { interleaved_float_buffer.push_back( buffers[channel][frame] ); } } std::cout.write( reinterpret_cast( interleaved_float_buffer.data() ), interleaved_float_buffer.size() * sizeof( float ) ); } void write( const std::vector buffers, std::size_t frames ) { interleaved_int_buffer.clear(); for ( std::size_t frame = 0; frame < frames; frame++ ) { for ( std::size_t channel = 0; channel < buffers.size(); channel++ ) { interleaved_int_buffer.push_back( buffers[channel][frame] ); } } std::cout.write( reinterpret_cast( interleaved_int_buffer.data() ), interleaved_int_buffer.size() * sizeof( std::int16_t ) ); } }; } // namespace openmpt123 #endif // OPENMPT123_STDOUT_HPP libopenmpt-0.3.6+release.autotools/sounddsp/0000755000372100037210000000000013235362226016201 500000000000000libopenmpt-0.3.6+release.autotools/sounddsp/EQ.h0000644000372100037210000000254313161656666016617 00000000000000/* * EQ.h * ---- * Purpose: Mixing code for equalizer. * Notes : Ugh... This should really be removed at some point. * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #include "../soundlib/Mixer.h" // For MIXBUFFERSIZE OPENMPT_NAMESPACE_BEGIN #ifndef NO_EQ #define MAX_EQ_BANDS 6 typedef struct _EQBANDSTRUCT { float32 a0; float32 a1; float32 a2; float32 b1; float32 b2; float32 x1; float32 x2; float32 y1; float32 y2; float32 Gain; float32 CenterFrequency; bool bEnable; } EQBANDSTRUCT; class CEQ { private: EQBANDSTRUCT gEQ[MAX_EQ_BANDS*2]; public: CEQ(); public: void Initialize(bool bReset, DWORD MixingFreq); void ProcessStereo(int *pbuffer, float *MixFloatBuffer, UINT nCount); void ProcessMono(int *pbuffer, float *MixFloatBuffer, UINT nCount); void SetEQGains(const UINT *pGains, UINT nGains, const UINT *pFreqs, bool bReset, DWORD MixingFreq); }; class CQuadEQ { private: CEQ front; CEQ rear; float EQTempFloatBuffer[MIXBUFFERSIZE * 2]; public: void Initialize(bool bReset, DWORD MixingFreq); void Process(int *frontBuffer, int *rearBuffer, UINT nCount, UINT nChannels); void SetEQGains(const UINT *pGains, UINT nGains, const UINT *pFreqs, bool bReset, DWORD MixingFreq); }; #endif // !NO_EQ OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/sounddsp/EQ.cpp0000644000372100037210000003422013161656666017147 00000000000000/* * EQ.cpp * ------ * Purpose: Mixing code for equalizer. * Notes : Ugh... This should really be removed at some point. * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "../soundlib/Sndfile.h" #include "../soundlib/MixerLoops.h" #include "../sounddsp/EQ.h" #include OPENMPT_NAMESPACE_BEGIN #ifndef NO_EQ #define EQ_BANDWIDTH 2.0 #define EQ_ZERO 0.000001 static const UINT gEqLinearToDB[33] = { 16, 19, 22, 25, 28, 31, 34, 37, 40, 43, 46, 49, 52, 55, 58, 61, 64, 76, 88, 100, 112, 124, 136, 148, 160, 172, 184, 196, 208, 220, 232, 244, 256 }; static const EQBANDSTRUCT gEQDefaults[MAX_EQ_BANDS*2] = { // Default: Flat EQ {0,0,0,0,0, 0,0,0,0, 1, 120, false}, {0,0,0,0,0, 0,0,0,0, 1, 600, false}, {0,0,0,0,0, 0,0,0,0, 1, 1200, false}, {0,0,0,0,0, 0,0,0,0, 1, 3000, false}, {0,0,0,0,0, 0,0,0,0, 1, 6000, false}, {0,0,0,0,0, 0,0,0,0, 1, 10000, false}, {0,0,0,0,0, 0,0,0,0, 1, 120, false}, {0,0,0,0,0, 0,0,0,0, 1, 600, false}, {0,0,0,0,0, 0,0,0,0, 1, 1200, false}, {0,0,0,0,0, 0,0,0,0, 1, 3000, false}, {0,0,0,0,0, 0,0,0,0, 1, 6000, false}, {0,0,0,0,0, 0,0,0,0, 1, 10000, false}, }; #ifdef ENABLE_X86 #if MPT_COMPILER_MSVC #pragma warning(push) #pragma warning(disable:4100) #endif // MPT_COMPILER_MSVC #define PBS_A0 DWORD PTR [eax + EQBANDSTRUCT.a0] #define PBS_A1 DWORD PTR [eax + EQBANDSTRUCT.a1] #define PBS_A2 DWORD PTR [eax + EQBANDSTRUCT.a2] #define PBS_B1 DWORD PTR [eax + EQBANDSTRUCT.b1] #define PBS_B2 DWORD PTR [eax + EQBANDSTRUCT.b2] #define PBS_X1 DWORD PTR [eax + EQBANDSTRUCT.x1] #define PBS_X2 DWORD PTR [eax + EQBANDSTRUCT.x2] #define PBS_Y1 DWORD PTR [eax + EQBANDSTRUCT.y1] #define PBS_Y2 DWORD PTR [eax + EQBANDSTRUCT.y2] static void EQFilter(EQBANDSTRUCT *pbs, float32 *pbuffer, UINT nCount) { _asm { mov eax, pbs // eax = pbs mov edx, nCount // edx = nCount mov ecx, pbuffer // ecx = pbuffer fld PBS_Y2 // ST(3)=y2 fld PBS_Y1 // ST(2)=y1 fld PBS_X2 // ST(1)=x2 fld PBS_X1 // ST(0)=x1 EQ_Loop: fld DWORD PTR [ecx] // ST(0):x ST(1):x1 ST(2):x2 ST(3):y1 ST(4):y2 fld PBS_A0 // ST(0):a0 ST(1):x ST(2):x1 ST(3):x2 ST(4):y1 ST(5):y2 fmul ST(0), ST(1) // ST(0):a0*x fld PBS_A1 // ST(0):a1 ST(1):a0*x ST(2):x ST(3):x1 ST(4):x2 ST(5):y1 ST(6):y2 fmul ST(0), ST(3) // ST(0):a1*x1 add ecx, 4 faddp ST(1), ST(0) fld PBS_A2 fmul ST(0), ST(4) faddp ST(1), ST(0) fld PBS_B1 fmul ST(0), ST(5) faddp ST(1), ST(0) fld PBS_B2 fmul ST(0), ST(6) sub edx, 1 faddp ST(1), ST(0) fst DWORD PTR [ecx-4] // *pbuffer = a0*x+a1*x1+a2*x2+b1*y1+b2*y2 // Here, ST(0)=y ST(1)=x ST(2)=x1 ST(3)=x2 ST(4)=y1 ST(5)=y2 fxch ST(4) // y1=y fstp ST(5) // y2=y1 // Here, ST(0)=x ST(1)=x1 ST(2)=x2 ST(3)=y1 ST(4)=y2 fxch ST(1) // x1=x fstp ST(2) // x2=x1 jnz EQ_Loop // Store x1,y1,x2,y2 and pop FPU stack fstp PBS_X1 fstp PBS_X2 fstp PBS_Y1 fstp PBS_Y2 } } #ifdef ENABLE_X86_AMD static void AMD_StereoEQ(EQBANDSTRUCT *pbl, EQBANDSTRUCT *pbr, float32 *pbuffer, UINT nCount) { float tmp[16]; _asm { mov eax, pbl mov edx, pbr mov ebx, pbuffer mov ecx, nCount lea edi, [tmp+8] and edi, 0xfffffff8 movd mm7, [eax+EQBANDSTRUCT.a0] movd mm0, [edx+EQBANDSTRUCT.a0] movd mm6, [eax+EQBANDSTRUCT.a1] movd mm1, [edx+EQBANDSTRUCT.a1] punpckldq mm7, mm0 punpckldq mm6, mm1 movq [edi], mm7 // [edi] = a0 movq [edi+8], mm6 // [edi+8] = a1 movd mm5, [eax+EQBANDSTRUCT.a2] movd mm0, [edx+EQBANDSTRUCT.a2] movd mm4, [eax+EQBANDSTRUCT.b1] movd mm1, [edx+EQBANDSTRUCT.b1] movd mm3, [eax+EQBANDSTRUCT.b2] movd mm2, [edx+EQBANDSTRUCT.b2] punpckldq mm5, mm0 punpckldq mm4, mm1 punpckldq mm3, mm2 movq [edi+16], mm5 // [edi+16] = a2 movq [edi+24], mm4 // [edi+24] = b1 movq [edi+32], mm3 // [edi+32] = b2 movd mm4, [eax+EQBANDSTRUCT.x1] movd mm0, [edx+EQBANDSTRUCT.x1] movd mm5, [eax+EQBANDSTRUCT.x2] movd mm1, [edx+EQBANDSTRUCT.x2] punpckldq mm4, mm0 // mm4 = x1 punpckldq mm5, mm1 // mm5 = x2 movd mm6, [eax+EQBANDSTRUCT.y1] movd mm2, [edx+EQBANDSTRUCT.y1] movd mm7, [eax+EQBANDSTRUCT.y2] movd mm3, [edx+EQBANDSTRUCT.y2] punpckldq mm6, mm2 // mm6 = y1 punpckldq mm7, mm3 // mm7 = y2 mainloop: movq mm0, [ebx] movq mm3, [edi+8] add ebx, 8 movq mm1, [edi+16] pfmul mm3, mm4 // x1 * a1 movq mm2, [edi+32] pfmul mm1, mm5 // x2 * a2 movq mm5, mm4 // x2 = x1 pfmul mm2, mm7 // y2 * b2 movq mm7, mm6 // y2 = y1 pfmul mm6, [edi+24] // y1 * b1 movq mm4, mm0 // x1 = x pfmul mm0, [edi] // x * a0 pfadd mm6, mm1 // x2*a2 + y1*b1 pfadd mm6, mm2 // x2*a2 + y1*b1 + y2*b2 pfadd mm6, mm3 // x1*a1 + x2*a2 + y1*b1 + y2*b2 pfadd mm6, mm0 // x*a0 + x1*a1 + x2*a2 + y1*b1 + y2*b2 dec ecx movq [ebx-8], mm6 jnz mainloop movd [eax+EQBANDSTRUCT.x1], mm4 punpckhdq mm4, mm4 movd [eax+EQBANDSTRUCT.x2], mm5 punpckhdq mm5, mm5 movd [eax+EQBANDSTRUCT.y1], mm6 punpckhdq mm6, mm6 movd [eax+EQBANDSTRUCT.y2], mm7 punpckhdq mm7, mm7 movd [edx+EQBANDSTRUCT.x1], mm4 movd [edx+EQBANDSTRUCT.x2], mm5 movd [edx+EQBANDSTRUCT.y1], mm6 movd [edx+EQBANDSTRUCT.y2], mm7 emms } } #endif // ENABLE_X86_AMD #ifdef ENABLE_SSE static void SSE_StereoEQ(EQBANDSTRUCT *pbl, EQBANDSTRUCT *pbr, float32 *pbuffer, UINT nCount) { static const float gk1 = 1.0f; _asm { mov eax, pbl mov edx, pbr mov ebx, pbuffer mov ecx, nCount movss xmm0, [eax+EQBANDSTRUCT.Gain] movss xmm1, gk1 comiss xmm0, xmm1 jne doeq movss xmm0, [edx+EQBANDSTRUCT.Gain] comiss xmm0, xmm1 je done doeq: test ecx, ecx jz done movss xmm6, [eax+EQBANDSTRUCT.a1] movss xmm7, [eax+EQBANDSTRUCT.a2] movss xmm4, [eax+EQBANDSTRUCT.x1] movss xmm5, [eax+EQBANDSTRUCT.x2] movlhps xmm6, xmm7 // xmm6 = [ 0 | a2 | 0 | a1 ] movlhps xmm4, xmm5 // xmm4 = [ 0 | x2 | 0 | x1 ] movss xmm2, [edx+EQBANDSTRUCT.a1] movss xmm3, [edx+EQBANDSTRUCT.a2] movss xmm0, [edx+EQBANDSTRUCT.x1] movss xmm1, [edx+EQBANDSTRUCT.x2] movlhps xmm2, xmm3 // xmm2 = [ 0 | a'2 | 0 | a'1 ] movlhps xmm0, xmm1 // xmm0 = [ 0 | x'2 | 0 | x'1 ] shufps xmm6, xmm2, 0x88 // xmm6 = [ a'2 | a'1 | a2 | a1 ] shufps xmm4, xmm0, 0x88 // xmm4 = [ x'2 | x'1 | x2 | x1 ] shufps xmm6, xmm6, 0xD8 // xmm6 = [ a'2 | a2 | a'1 | a1 ] shufps xmm4, xmm4, 0xD8 // xmm4 = [ x'2 | x2 | x'1 | x1 ] movss xmm7, [eax+EQBANDSTRUCT.b1] movss xmm0, [eax+EQBANDSTRUCT.b2] movss xmm2, [edx+EQBANDSTRUCT.b1] movss xmm1, [edx+EQBANDSTRUCT.b2] movlhps xmm7, xmm0 // xmm7 = [ 0 | b2 | 0 | b1 ] movlhps xmm2, xmm1 // xmm2 = [ 0 | b'2 | 0 | b'1 ] shufps xmm7, xmm2, 0x88 // xmm7 = [ b'2 | b'1 | b2 | b1 ] shufps xmm7, xmm7, 0xD8 // xmm7 = [ b'2 | b2 | b'1 | b1 ] movss xmm5, [eax+EQBANDSTRUCT.y1] movss xmm1, [eax+EQBANDSTRUCT.y2] movss xmm3, [edx+EQBANDSTRUCT.y1] movss xmm0, [edx+EQBANDSTRUCT.y2] movlhps xmm5, xmm1 // xmm5 = [ 0 | y2 | 0 | y1 ] movlhps xmm3, xmm0 // xmm3 = [ 0 | y'2 | 0 | y'1 ] shufps xmm5, xmm3, 0x88 // xmm5 = [ y'2 | y'1 | y2 | y1 ] shufps xmm5, xmm5, 0xD8 // xmm5 = [ y'2 | y2 | y'1 | y1 ] movss xmm3, [eax+EQBANDSTRUCT.a0] movss xmm2, [edx+EQBANDSTRUCT.a0] shufps xmm3, xmm2, 0x88 shufps xmm3, xmm3, 0xD8 // xmm3 = [ 0 | 0 | a'0 | a0 ] mainloop: movlps xmm0, qword ptr [ebx] add ebx, 8 movaps xmm1, xmm5 // xmm1 = [ y2r | y2l | y1r | y1l ] mulps xmm1, xmm7 // xmm1 = [b2r*y2r|b2l*y2l|b1r*y1r|b1l*y1l] movaps xmm2, xmm4 // xmm2 = [ x2r | x2l | x1r | x1l ] mulps xmm2, xmm6 // xmm6 = [a2r*x2r|a2l*x2l|a1r*x1r|a1l*x1l] shufps xmm4, xmm0, 0x44 // xmm4 = [ xr | xl | x1r | x1l ] mulps xmm0, xmm3 // xmm0 = [ 0 | 0 |a0r*xr|a0l*xl] shufps xmm4, xmm4, 0x4E // xmm4 = [ x1r | x1l | xr | xl ] addps xmm1, xmm2 // xmm1 = [b2r*y2r+a2r*x2r|b2l*y2l+a2l*x2l|b1r*y1r+a1r*x1r|b1l*y1l+a1l*x1l] addps xmm1, xmm0 // xmm1 = [b2r*y2r+a2r*x2r|b2l*y2l+a2l*x2l|b1r*y1r+a1r*x1r+a0r*xr|b1l*y1l+a1l*x1l+a0l*xl] sub ecx, 1 movhlps xmm0, xmm1 addps xmm0, xmm1 // xmm0 = [ ? | ? | yr(n) | yl(n) ] movlps [ebx-8], xmm0 shufps xmm0, xmm5, 0x44 movaps xmm5, xmm0 jnz mainloop movhlps xmm0, xmm4 movhlps xmm1, xmm5 movss [eax+EQBANDSTRUCT.x1], xmm4 movss [eax+EQBANDSTRUCT.x2], xmm0 movss [eax+EQBANDSTRUCT.y1], xmm5 movss [eax+EQBANDSTRUCT.y2], xmm1 shufps xmm4, xmm4, 0x01 shufps xmm0, xmm0, 0x01 shufps xmm5, xmm5, 0x01 shufps xmm1, xmm1, 0x01 movss [edx+EQBANDSTRUCT.x1], xmm4 movss [edx+EQBANDSTRUCT.x2], xmm0 movss [edx+EQBANDSTRUCT.y1], xmm5 movss [edx+EQBANDSTRUCT.y2], xmm1 done:; } } #endif // ENABLE_SSE #if MPT_COMPILER_MSVC #pragma warning(pop) #endif // MPT_COMPILER_MSVC #else static void EQFilter(EQBANDSTRUCT *pbs, float32 *pbuffer, UINT nCount) { for (UINT i=0; ia1 * pbs->x1 + pbs->a2 * pbs->x2 + pbs->a0 * x + pbs->b1 * pbs->y1 + pbs->b2 * pbs->y2; pbs->x2 = pbs->x1; pbs->y2 = pbs->y1; pbs->x1 = x; pbuffer[i] = y; pbs->y1 = y; } } #endif void CEQ::ProcessMono(int *pbuffer, float *MixFloatBuffer, UINT nCount) { MonoMixToFloat(pbuffer, MixFloatBuffer, nCount, 1.0f/MIXING_SCALEF); for (UINT b=0; b 0.45f) gEQ[band].Gain = 1; // if (f > 0.25) f = 0.25; // k = tan(PI*f); k = f * 3.141592654f; k = k + k*f; // if (k > (float32)0.707) k = (float32)0.707; k2 = k*k; v0 = gEQ[band].Gain; v1 = 1; if (gEQ[band].Gain < 1.0) { v0 *= (0.5f/EQ_BANDWIDTH); v1 *= (0.5f/EQ_BANDWIDTH); } else { v0 *= (1.0f/EQ_BANDWIDTH); v1 *= (1.0f/EQ_BANDWIDTH); } r = (1 + v0*k + k2) / (1 + v1*k + k2); if (r != gEQ[band].a0) { gEQ[band].a0 = r; b = true; } r = 2 * (k2 - 1) / (1 + v1*k + k2); if (r != gEQ[band].a1) { gEQ[band].a1 = r; b = true; } r = (1 - v0*k + k2) / (1 + v1*k + k2); if (r != gEQ[band].a2) { gEQ[band].a2 = r; b = true; } r = - 2 * (k2 - 1) / (1 + v1*k + k2); if (r != gEQ[band].b1) { gEQ[band].b1 = r; b = true; } r = - (1 - v1*k + k2) / (1 + v1*k + k2); if (r != gEQ[band].b2) { gEQ[band].b2 = r; b = true; } if (b) { gEQ[band].x1 = 0; gEQ[band].x2 = 0; gEQ[band].y1 = 0; gEQ[band].y2 = 0; } } else { gEQ[band].a0 = 0; gEQ[band].a1 = 0; gEQ[band].a2 = 0; gEQ[band].b1 = 0; gEQ[band].b2 = 0; gEQ[band].x1 = 0; gEQ[band].x2 = 0; gEQ[band].y1 = 0; gEQ[band].y2 = 0; } } void CEQ::SetEQGains(const UINT *pGains, UINT nGains, const UINT *pFreqs, bool bReset, DWORD MixingFreq) { for (UINT i=0; i 32) n = 32; g = ((float32)gEqLinearToDB[n]) / 64.0f; if (pFreqs) f = (float32)(int)pFreqs[i]; } else { g = 1; } gEQ[i].Gain = g; gEQ[i].CenterFrequency = f; gEQ[i+MAX_EQ_BANDS].Gain = g; gEQ[i+MAX_EQ_BANDS].CenterFrequency = f; if (f > 20.0f) { gEQ[i].bEnable = true; gEQ[i+MAX_EQ_BANDS].bEnable = true; } else { gEQ[i].bEnable = false; gEQ[i+MAX_EQ_BANDS].bEnable = false; } } Initialize(bReset, MixingFreq); } void CQuadEQ::Initialize(bool bReset, DWORD MixingFreq) { front.Initialize(bReset, MixingFreq); rear.Initialize(bReset, MixingFreq); } void CQuadEQ::SetEQGains(const UINT *pGains, UINT nGains, const UINT *pFreqs, bool bReset, DWORD MixingFreq) { front.SetEQGains(pGains, nGains, pFreqs, bReset, MixingFreq); rear.SetEQGains(pGains, nGains, pFreqs, bReset, MixingFreq); } void CQuadEQ::Process(int *frontBuffer, int *rearBuffer, UINT nCount, UINT nChannels) { if(nChannels == 1) { front.ProcessMono(frontBuffer, EQTempFloatBuffer, nCount); } else if(nChannels == 2) { front.ProcessStereo(frontBuffer, EQTempFloatBuffer, nCount); } else if(nChannels == 4) { front.ProcessStereo(frontBuffer, EQTempFloatBuffer, nCount); rear.ProcessStereo(rearBuffer, EQTempFloatBuffer, nCount); } } #else MPT_MSVC_WORKAROUND_LNK4221(EQ) #endif // !NO_EQ OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/sounddsp/Reverb.cpp0000644000372100037210000013606413161656666020100 00000000000000/* * Reverb.cpp * ---------- * Purpose: Mixing code for reverb. * Notes : Ugh... This should really be removed at some point. * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #ifndef NO_REVERB #include "Reverb.h" #include "../soundlib/MixerLoops.h" #ifdef ENABLE_MMX #include #endif #ifdef ENABLE_SSE2 #include #endif #endif // NO_REVERB OPENMPT_NAMESPACE_BEGIN #ifndef NO_REVERB #ifdef ENABLE_MMX // Load two 32-bit values static MPT_FORCEINLINE __m64 Load64MMX(const int32 *x) { return _mm_set_pi32(x[1], x[0]); } // Load four 16-bit values static MPT_FORCEINLINE __m64 Load64MMX(const LR16 (&x)[2]) { return Load64MMX(&x->lr); } // Store 64-bit value from register (MSVC does not have_mm_cvtsi64_si64x) - macro to avoid emms warnings #define Store64MMX(dst, src) \ MPT_DO \ { \ STATIC_ASSERT(sizeof((dst)[0]) == 4); \ (dst)[0] = _mm_cvtsi64_si32(src); \ (dst)[1] = _mm_cvtsi64_si32(_mm_unpackhi_pi32(src, src)); \ } MPT_WHILE_0 #endif #ifdef ENABLE_SSE2 // Load two 32-bit values static MPT_FORCEINLINE __m128i Load64SSE(const int32 *x) { return _mm_loadl_epi64(reinterpret_cast(x)); } // Load four 16-bit values static MPT_FORCEINLINE __m128i Load64SSE(const LR16 (&x)[2]) { return _mm_loadl_epi64(reinterpret_cast(&x)); } // Store two 32-bit or four 16-bit values from register static MPT_FORCEINLINE void Store64SSE(int32 *dst, __m128i src) { return _mm_storel_epi64(reinterpret_cast<__m128i *>(dst), src); } static MPT_FORCEINLINE void Store64SSE(LR16 *dst, __m128i src) { return _mm_storel_epi64(reinterpret_cast<__m128i *>(dst), src); } #endif CReverbSettings::CReverbSettings() { m_nReverbType = 0; m_nReverbDepth = 8; // 50% } CReverb::CReverb() { // Shared reverb state InitMixBuffer(MixReverbBuffer, static_cast(mpt::size(MixReverbBuffer))); gnRvbROfsVol = 0; gnRvbLOfsVol = 0; gnReverbSend = 0; gnReverbSamples = 0; gnReverbDecaySamples = 0; // Internal reverb state g_bLastInPresent = 0; g_bLastOutPresent = 0; g_nLastRvbIn_xl = 0; g_nLastRvbIn_xr = 0; g_nLastRvbIn_yl = 0; g_nLastRvbIn_yr = 0; g_nLastRvbOut_xl = 0; g_nLastRvbOut_xr = 0; MemsetZero(gnDCRRvb_Y1); MemsetZero(gnDCRRvb_X1); // Reverb mix buffers MemsetZero(g_RefDelay); MemsetZero(g_LateReverb); } static int32 OnePoleLowPassCoef(int32 scale, float g, float F_c, float F_s) { if(g > 0.999999f) return 0; g *= g; double scale_over_1mg = scale / (1.0 - g); double cosw = std::cos(2.0 * M_PI * F_c / F_s); return Util::Round((1.0 - (std::sqrt((g + g) * (1.0 - cosw) - g * g * (1.0 - cosw * cosw)) + g * cosw)) * scale_over_1mg); } static float mBToLinear(int32 value_mB) { if(!value_mB) return 1; if(value_mB <= -100000) return 0; const double val = value_mB * 3.321928094887362304 / (100.0 * 20.0); // log2(10)/(100*20) return static_cast(std::pow(2.0, val - static_cast(0.5 + val))); } static int32 mBToLinear(int32 scale, int32 value_mB) { return Util::Round(mBToLinear(value_mB) * scale); } struct SNDMIX_REVERB_PROPERTIES { int32 lRoom; // [-10000, 0] default: -10000 mB int32 lRoomHF; // [-10000, 0] default: 0 mB float flDecayTime; // [0.1, 20.0] default: 1.0 s float flDecayHFRatio; // [0.1, 2.0] default: 0.5 int32 lReflections; // [-10000, 1000] default: -10000 mB float flReflectionsDelay; // [0.0, 0.3] default: 0.02 s int32 lReverb; // [-10000, 2000] default: -10000 mB float flReverbDelay; // [0.0, 0.1] default: 0.04 s float flDiffusion; // [0.0, 100.0] default: 100.0 % float flDensity; // [0.0, 100.0] default: 100.0 % }; struct SNDMIX_RVBPRESET { SNDMIX_REVERB_PROPERTIES Preset; const char *name; }; static SNDMIX_RVBPRESET gRvbPresets[NUM_REVERBTYPES] = { {{ SNDMIX_REVERB_PRESET_PLATE }, "GM Plate"}, {{ SNDMIX_REVERB_PRESET_SMALLROOM }, "GM Small Room"}, {{ SNDMIX_REVERB_PRESET_MEDIUMROOM }, "GM Medium Room"}, {{ SNDMIX_REVERB_PRESET_LARGEROOM }, "GM Large Room"}, {{ SNDMIX_REVERB_PRESET_MEDIUMHALL }, "GM Medium Hall"}, {{ SNDMIX_REVERB_PRESET_LARGEHALL }, "GM Large Hall"}, {{ SNDMIX_REVERB_PRESET_GENERIC }, "Generic"}, {{ SNDMIX_REVERB_PRESET_PADDEDCELL }, "Padded Cell"}, {{ SNDMIX_REVERB_PRESET_ROOM }, "Room"}, {{ SNDMIX_REVERB_PRESET_BATHROOM }, "Bathroom"}, {{ SNDMIX_REVERB_PRESET_LIVINGROOM }, "Living Room"}, {{ SNDMIX_REVERB_PRESET_STONEROOM }, "Stone Room"}, {{ SNDMIX_REVERB_PRESET_AUDITORIUM }, "Auditorium"}, {{ SNDMIX_REVERB_PRESET_CONCERTHALL }, "Concert Hall"}, {{ SNDMIX_REVERB_PRESET_CAVE }, "Cave"}, {{ SNDMIX_REVERB_PRESET_ARENA }, "Arena"}, {{ SNDMIX_REVERB_PRESET_HANGAR }, "Hangar"}, {{ SNDMIX_REVERB_PRESET_CARPETEDHALLWAY }, "Carpeted Hallway"}, {{ SNDMIX_REVERB_PRESET_HALLWAY }, "Hallway"}, {{ SNDMIX_REVERB_PRESET_STONECORRIDOR }, "Stone Corridor"}, {{ SNDMIX_REVERB_PRESET_ALLEY }, "Alley"}, {{ SNDMIX_REVERB_PRESET_FOREST }, "Forest"}, {{ SNDMIX_REVERB_PRESET_CITY }, "City"}, {{ SNDMIX_REVERB_PRESET_MOUNTAINS }, "Mountains"}, {{ SNDMIX_REVERB_PRESET_QUARRY }, "Quarry"}, {{ SNDMIX_REVERB_PRESET_PLAIN }, "Plain"}, {{ SNDMIX_REVERB_PRESET_PARKINGLOT }, "Parking Lot"}, {{ SNDMIX_REVERB_PRESET_SEWERPIPE }, "Sewer Pipe"}, {{ SNDMIX_REVERB_PRESET_UNDERWATER }, "Underwater"}, }; const char *GetReverbPresetName(uint32 nPreset) { return (nPreset < NUM_REVERBTYPES) ? gRvbPresets[nPreset].name : nullptr; } ////////////////////////////////////////////////////////////////////////// // // I3DL2 environmental reverb support // struct REFLECTIONPRESET { int32 lDelayFactor; int16 sGainLL, sGainRR, sGainLR, sGainRL; }; const REFLECTIONPRESET gReflectionsPreset[ENVIRONMENT_NUMREFLECTIONS] = { // %Delay, ll, rr, lr, rl {0, 9830, 6554, 0, 0}, {10, 6554, 13107, 0, 0}, {24, -9830, 13107, 0, 0}, {36, 13107, -6554, 0, 0}, {54, 16384, 16384, -1638, -1638}, {61, -13107, 8192, -328, -328}, {73, -11468, -11468, -3277, 3277}, {87, 13107, -9830, 4916, -4916} }; //////////////////////////////////////////////////////////////////////////////////// // // Implementation // MPT_FORCEINLINE int32 ftol(float f) { return static_cast(f); } static void I3dl2_to_Generic( const SNDMIX_REVERB_PROPERTIES *pReverb, EnvironmentReverb *pRvb, float flOutputFreq, int32 lMinRefDelay, int32 lMaxRefDelay, int32 lMinRvbDelay, int32 lMaxRvbDelay, int32 lTankLength) { float flDelayFactor, flDelayFactorHF, flDecayTimeHF; int32 lDensity, lTailDiffusion; // Common parameters pRvb->ReverbLevel = pReverb->lReverb; pRvb->ReflectionsLevel = pReverb->lReflections; pRvb->RoomHF = pReverb->lRoomHF; // HACK: Somewhat normalize the reverb output level int32 lMaxLevel = (pRvb->ReverbLevel > pRvb->ReflectionsLevel) ? pRvb->ReverbLevel : pRvb->ReflectionsLevel; if (lMaxLevel < -600) { lMaxLevel += 600; pRvb->ReverbLevel -= lMaxLevel; pRvb->ReflectionsLevel -= lMaxLevel; } // Pre-Diffusion factor (for both reflections and late reverb) lDensity = 8192 + ftol(79.31f * pReverb->flDensity); pRvb->PreDiffusion = lDensity; // Late reverb diffusion lTailDiffusion = ftol((0.15f + pReverb->flDiffusion * (0.36f*0.01f)) * 32767.0f); if (lTailDiffusion > 0x7f00) lTailDiffusion = 0x7f00; pRvb->TankDiffusion = lTailDiffusion; // Verify reflections and reverb delay parameters float flRefDelay = pReverb->flReflectionsDelay; if (flRefDelay > 0.100f) flRefDelay = 0.100f; int32 lReverbDelay = ftol(pReverb->flReverbDelay * flOutputFreq); int32 lReflectionsDelay = ftol(flRefDelay * flOutputFreq); int32 lReverbDecayTime = ftol(pReverb->flDecayTime * flOutputFreq); if (lReflectionsDelay < lMinRefDelay) { lReverbDelay -= (lMinRefDelay - lReflectionsDelay); lReflectionsDelay = lMinRefDelay; } if (lReflectionsDelay > lMaxRefDelay) { lReverbDelay += (lReflectionsDelay - lMaxRefDelay); lReflectionsDelay = lMaxRefDelay; } // Adjust decay time when adjusting reverb delay if (lReverbDelay < lMinRvbDelay) { lReverbDecayTime -= (lMinRvbDelay - lReverbDelay); lReverbDelay = lMinRvbDelay; } if (lReverbDelay > lMaxRvbDelay) { lReverbDecayTime += (lReverbDelay - lMaxRvbDelay); lReverbDelay = lMaxRvbDelay; } pRvb->ReverbDelay = lReverbDelay; pRvb->ReverbDecaySamples = lReverbDecayTime; // Setup individual reflections delay and gains for (uint32 iRef=0; iRefReflections[iRef]; ref.Delay = lReflectionsDelay + (gReflectionsPreset[iRef].lDelayFactor * lReverbDelay + 50)/100; ref.GainLL = gReflectionsPreset[iRef].sGainLL; ref.GainRL = gReflectionsPreset[iRef].sGainRL; ref.GainLR = gReflectionsPreset[iRef].sGainLR; ref.GainRR = gReflectionsPreset[iRef].sGainRR; } // Late reverb decay time if (lTankLength < 10) lTankLength = 10; flDelayFactor = (lReverbDecayTime <= lTankLength) ? 1.0f : ((float)lTankLength / (float)lReverbDecayTime); pRvb->ReverbDecay = ftol(std::pow(0.001f, flDelayFactor) * 32768.0f); // Late Reverb Decay HF flDecayTimeHF = (float)lReverbDecayTime * pReverb->flDecayHFRatio; flDelayFactorHF = (flDecayTimeHF <= (float)lTankLength) ? 1.0f : ((float)lTankLength / flDecayTimeHF); pRvb->flReverbDamping = std::pow(0.001f, flDelayFactorHF); } void CReverb::Shutdown() { gnReverbSend = 0; gnRvbLOfsVol = 0; gnRvbROfsVol = 0; // Clear out all reverb state g_bLastInPresent = false; g_bLastOutPresent = false; g_nLastRvbIn_xl = g_nLastRvbIn_xr = 0; g_nLastRvbIn_yl = g_nLastRvbIn_yr = 0; g_nLastRvbOut_xl = g_nLastRvbOut_xr = 0; MemsetZero(gnDCRRvb_X1); MemsetZero(gnDCRRvb_Y1); // Zero internal buffers MemsetZero(g_LateReverb.Diffusion1); MemsetZero(g_LateReverb.Diffusion2); MemsetZero(g_LateReverb.Delay1); MemsetZero(g_LateReverb.Delay2); MemsetZero(g_RefDelay.RefDelayBuffer); MemsetZero(g_RefDelay.PreDifBuffer); MemsetZero(g_RefDelay.RefOut); } void CReverb::Initialize(bool bReset, uint32 MixingFreq) { if (m_Settings.m_nReverbType >= NUM_REVERBTYPES) m_Settings.m_nReverbType = 0; static SNDMIX_REVERB_PROPERTIES *spCurrentPreset = nullptr; SNDMIX_REVERB_PROPERTIES *pRvbPreset = &gRvbPresets[m_Settings.m_nReverbType].Preset; if ((pRvbPreset != spCurrentPreset) || (bReset)) { // Reverb output frequency is half of the dry output rate float flOutputFrequency = (float)MixingFreq; EnvironmentReverb rvb; // Reset reverb parameters spCurrentPreset = pRvbPreset; I3dl2_to_Generic(pRvbPreset, &rvb, flOutputFrequency, RVBMINREFDELAY, RVBMAXREFDELAY, RVBMINRVBDELAY, RVBMAXRVBDELAY, ( RVBDIF1L_LEN + RVBDIF1R_LEN + RVBDIF2L_LEN + RVBDIF2R_LEN + RVBDLY1L_LEN + RVBDLY1R_LEN + RVBDLY2L_LEN + RVBDLY2R_LEN) / 2); // Store reverb decay time (in samples) for reverb auto-shutdown gnReverbDecaySamples = rvb.ReverbDecaySamples; // Room attenuation at high frequencies int32 nRoomLP; nRoomLP = OnePoleLowPassCoef(32768, mBToLinear(rvb.RoomHF), 5000, flOutputFrequency); g_RefDelay.nCoeffs.c.l = (int16)nRoomLP; g_RefDelay.nCoeffs.c.r = (int16)nRoomLP; // Pre-Diffusion factor (for both reflections and late reverb) g_RefDelay.nPreDifCoeffs.c.l = (int16)(rvb.PreDiffusion*2); g_RefDelay.nPreDifCoeffs.c.r = (int16)(rvb.PreDiffusion*2); // Setup individual reflections delay and gains for (uint32 iRef=0; iRef<8; iRef++) { SWRvbReflection &ref = g_RefDelay.Reflections[iRef]; ref.DelayDest = rvb.Reflections[iRef].Delay; ref.Delay = ref.DelayDest; ref.Gains[0].c.l = rvb.Reflections[iRef].GainLL; ref.Gains[0].c.r = rvb.Reflections[iRef].GainRL; ref.Gains[1].c.l = rvb.Reflections[iRef].GainLR; ref.Gains[1].c.r = rvb.Reflections[iRef].GainRR; } g_LateReverb.nReverbDelay = rvb.ReverbDelay; // Reflections Master Gain uint32 lReflectionsGain = 0; if (rvb.ReflectionsLevel > -9000) { lReflectionsGain = mBToLinear(32768, rvb.ReflectionsLevel); } g_RefDelay.lMasterGain = lReflectionsGain; // Late reverb master gain uint32 lReverbGain = 0; if (rvb.ReverbLevel > -9000) { lReverbGain = mBToLinear(32768, rvb.ReverbLevel); } g_LateReverb.lMasterGain = lReverbGain; // Late reverb diffusion uint32 nTailDiffusion = rvb.TankDiffusion; if (nTailDiffusion > 0x7f00) nTailDiffusion = 0x7f00; g_LateReverb.nDifCoeffs[0].c.l = (int16)nTailDiffusion; g_LateReverb.nDifCoeffs[0].c.r = (int16)nTailDiffusion; g_LateReverb.nDifCoeffs[1].c.l = (int16)nTailDiffusion; g_LateReverb.nDifCoeffs[1].c.r = (int16)nTailDiffusion; g_LateReverb.Dif2InGains[0].c.l = 0x7000; g_LateReverb.Dif2InGains[0].c.r = 0x1000; g_LateReverb.Dif2InGains[1].c.l = 0x1000; g_LateReverb.Dif2InGains[1].c.r = 0x7000; // Late reverb decay time int32 nReverbDecay = rvb.ReverbDecay; Limit(nReverbDecay, 0, 0x7ff0); g_LateReverb.nDecayDC[0].c.l = (int16)nReverbDecay; g_LateReverb.nDecayDC[0].c.r = 0; g_LateReverb.nDecayDC[1].c.l = 0; g_LateReverb.nDecayDC[1].c.r = (int16)nReverbDecay; // Late Reverb Decay HF float fReverbDamping = rvb.flReverbDamping * rvb.flReverbDamping; int32 nDampingLowPass; nDampingLowPass = OnePoleLowPassCoef(32768, fReverbDamping, 5000, flOutputFrequency); Limit(nDampingLowPass, 0x100, 0x7f00); g_LateReverb.nDecayLP[0].c.l = (int16)nDampingLowPass; g_LateReverb.nDecayLP[0].c.r = 0; g_LateReverb.nDecayLP[1].c.l = 0; g_LateReverb.nDecayLP[1].c.r = (int16)nDampingLowPass; } if (bReset) { gnReverbSamples = 0; Shutdown(); } // Wait at least 5 seconds before shutting down the reverb if (gnReverbDecaySamples < MixingFreq*5) { gnReverbDecaySamples = MixingFreq*5; } } mixsample_t *CReverb::GetReverbSendBuffer(uint32 nSamples) { if(!gnReverbSend) { // and we did not clear the buffer yet, do it now because we will get new data StereoFill(MixReverbBuffer, nSamples, gnRvbROfsVol, gnRvbLOfsVol); } gnReverbSend = 1; // we will have to process reverb return MixReverbBuffer; } // Reverb void CReverb::Process(mixsample_t *MixSoundBuffer, uint32 nSamples) { if((!gnReverbSend) && (!gnReverbSamples)) { // no data is sent to reverb and reverb decayed completely return; } if(!gnReverbSend) { // no input data in MixReverbBuffer, so the buffer got not cleared in GetReverbSendBuffer(), do it now for decay StereoFill(MixReverbBuffer, nSamples, gnRvbROfsVol, gnRvbLOfsVol); } uint32 nIn, nOut; // Dynamically adjust reverb master gains int32 lMasterGain; lMasterGain = ((g_RefDelay.lMasterGain * m_Settings.m_nReverbDepth) >> 4); if (lMasterGain > 0x7fff) lMasterGain = 0x7fff; g_RefDelay.ReflectionsGain.c.l = (int16)lMasterGain; g_RefDelay.ReflectionsGain.c.r = (int16)lMasterGain; lMasterGain = ((g_LateReverb.lMasterGain * m_Settings.m_nReverbDepth) >> 4); if (lMasterGain > 0x10000) lMasterGain = 0x10000; g_LateReverb.RvbOutGains[0].c.l = (int16)((lMasterGain+0x7f) >> 3); // l->l g_LateReverb.RvbOutGains[0].c.r = (int16)((lMasterGain+0xff) >> 4); // r->l g_LateReverb.RvbOutGains[1].c.l = (int16)((lMasterGain+0xff) >> 4); // l->r g_LateReverb.RvbOutGains[1].c.r = (int16)((lMasterGain+0x7f) >> 3); // r->r // Process Dry/Wet Mix int32 lMaxRvbGain = (g_RefDelay.lMasterGain > g_LateReverb.lMasterGain) ? g_RefDelay.lMasterGain : g_LateReverb.lMasterGain; if (lMaxRvbGain > 32768) lMaxRvbGain = 32768; int32 lDryVol = (36 - m_Settings.m_nReverbDepth)>>1; if (lDryVol < 8) lDryVol = 8; if (lDryVol > 16) lDryVol = 16; lDryVol = 16 - (((16-lDryVol) * lMaxRvbGain) >> 15); ReverbDryMix(MixSoundBuffer, MixReverbBuffer, lDryVol, nSamples); // Downsample 2x + 1st stage of lowpass filter nIn = ReverbProcessPreFiltering1x(MixReverbBuffer, nSamples); nOut = nIn; // Main reverb processing: split into small chunks (needed for short reverb delays) // Reverb Input + Low-Pass stage #2 + Pre-diffusion if (nIn > 0) ProcessPreDelay(&g_RefDelay, MixReverbBuffer, nIn); // Process Reverb Reflections and Late Reverberation int32 *pRvbOut = MixReverbBuffer; uint32 nRvbSamples = nOut, nCount = 0; while (nRvbSamples > 0) { uint32 nPosRef = g_RefDelay.nRefOutPos & SNDMIX_REVERB_DELAY_MASK; uint32 nPosRvb = (nPosRef - g_LateReverb.nReverbDelay) & SNDMIX_REVERB_DELAY_MASK; uint32 nmax1 = (SNDMIX_REVERB_DELAY_MASK+1) - nPosRef; uint32 nmax2 = (SNDMIX_REVERB_DELAY_MASK+1) - nPosRvb; nmax1 = (nmax1 < nmax2) ? nmax1 : nmax2; uint32 n = nRvbSamples; if (n > nmax1) n = nmax1; if (n > 64) n = 64; // Reflections output + late reverb delay ProcessReflections(&g_RefDelay, &g_RefDelay.RefOut[nPosRef], pRvbOut, n); // Late Reverberation ProcessLateReverb(&g_LateReverb, &g_RefDelay.RefOut[nPosRvb], pRvbOut, n); // Update delay positions g_RefDelay.nRefOutPos = (g_RefDelay.nRefOutPos + n) & SNDMIX_REVERB_DELAY_MASK; g_RefDelay.nDelayPos = (g_RefDelay.nDelayPos + n) & SNDMIX_REFLECTIONS_DELAY_MASK; nCount += n*2; pRvbOut += n*2; nRvbSamples -= n; } // Adjust nDelayPos, in case nIn != nOut g_RefDelay.nDelayPos = (g_RefDelay.nDelayPos - nOut + nIn) & SNDMIX_REFLECTIONS_DELAY_MASK; // Upsample 2x ReverbProcessPostFiltering1x(MixReverbBuffer, MixSoundBuffer, nSamples); // Automatically shut down if needed if(gnReverbSend) gnReverbSamples = gnReverbDecaySamples; // reset decay counter else if(gnReverbSamples > nSamples) gnReverbSamples -= nSamples; // decay else // decayed { Shutdown(); gnReverbSamples = 0; } gnReverbSend = 0; // no input data in MixReverbBuffer } void CReverb::ReverbDryMix(int32 * MPT_RESTRICT pDry, int32 * MPT_RESTRICT pWet, int lDryVol, uint32 nSamples) { for (uint32 i=0; i>4) * lDryVol; pDry[i*2+1] += (pWet[i*2+1]>>4) * lDryVol; } } uint32 CReverb::ReverbProcessPreFiltering2x(int32 * MPT_RESTRICT pWet, uint32 nSamples) { uint32 nOutSamples = 0; int lowpass = g_RefDelay.nCoeffs.c.l; int y1_l = g_nLastRvbIn_yl, y1_r = g_nLastRvbIn_yr; uint32 n = nSamples; if (g_bLastInPresent) { int x1_l = g_nLastRvbIn_xl, x1_r = g_nLastRvbIn_xr; int x2_l = pWet[0], x2_r = pWet[1]; x1_l = (x1_l+x2_l)>>13; x1_r = (x1_r+x2_r)>>13; y1_l = x1_l + (((x1_l - y1_l)*lowpass)>>15); y1_r = x1_r + (((x1_r - y1_r)*lowpass)>>15); pWet[0] = y1_l; pWet[1] = y1_r; pWet+=2; n--; nOutSamples = 1; g_bLastInPresent = false; } if (n & 1) { n--; g_nLastRvbIn_xl = pWet[n*2]; g_nLastRvbIn_xr = pWet[n*2+1]; g_bLastInPresent = true; } n >>= 1; for (uint32 i=0; i>13; int x1_r = pWet[i*4+1]; int x2_r = pWet[i*4+3]; x1_r = (x1_r+x2_r)>>13; y1_l = x1_l + (((x1_l - y1_l)*lowpass)>>15); y1_r = x1_r + (((x1_r - y1_r)*lowpass)>>15); pWet[i*2] = y1_l; pWet[i*2+1] = y1_r; } g_nLastRvbIn_yl = y1_l; g_nLastRvbIn_yr = y1_r; return nOutSamples + n; } uint32 CReverb::ReverbProcessPreFiltering1x(int32 * MPT_RESTRICT pWet, uint32 nSamples) { int lowpass = g_RefDelay.nCoeffs.c.l; int y1_l = g_nLastRvbIn_yl, y1_r = g_nLastRvbIn_yr; for (uint32 i=0; i> 12; int x_r = pWet[i*2+1] >> 12; y1_l = x_l + (((x_l - y1_l)*lowpass)>>15); y1_r = x_r + (((x_r - y1_r)*lowpass)>>15); pWet[i*2] = y1_l; pWet[i*2+1] = y1_r; } g_nLastRvbIn_yl = y1_l; g_nLastRvbIn_yr = y1_r; return nSamples; } void CReverb::ReverbProcessPostFiltering2x(const int32 * MPT_RESTRICT pRvb, int32 * MPT_RESTRICT pDry, uint32 nSamples) { uint32 n0 = nSamples, n; int x1_l = g_nLastRvbOut_xl, x1_r = g_nLastRvbOut_xr; if (g_bLastOutPresent) { pDry[0] += x1_l; pDry[1] += x1_r; pDry += 2; n0--; g_bLastOutPresent = false; } n = n0 >> 1; for (uint32 i=0; i>1; pDry[i*4+1] += (x_r + x1_r)>>1; pDry[i*4+2] += x_l; pDry[i*4+3] += x_r; x1_l = x_l; x1_r = x_r; } if (n0 & 1) { int x_l = pRvb[n*2], x_r = pRvb[n*2+1]; pDry[n*4] += (x_l + x1_l)>>1; pDry[n*4+1] += (x_r + x1_r)>>1; x1_l = x_l; x1_r = x_r; g_bLastOutPresent = true; } g_nLastRvbOut_xl = x1_l; g_nLastRvbOut_xr = x1_r; } #define DCR_AMOUNT 9 // Stereo Add + DC removal void CReverb::ReverbProcessPostFiltering1x(const int32 * MPT_RESTRICT pRvb, int32 * MPT_RESTRICT pDry, uint32 nSamples) { #ifdef ENABLE_MMX if(GetProcSupport() & PROCSUPPORT_MMX) { __m64 nDCRRvb_Y1 = Load64MMX(gnDCRRvb_Y1); __m64 nDCRRvb_X1 = Load64MMX(gnDCRRvb_X1); __m64 in = _mm_set1_pi32(0); while(nSamples--) { in = Load64MMX(pRvb); pRvb += 2; // x(n-1) - x(n) __m64 diff = _mm_sub_pi32(nDCRRvb_X1, in); nDCRRvb_X1 = _mm_add_pi32(nDCRRvb_Y1, _mm_sub_pi32(_mm_srai_pi32(diff, DCR_AMOUNT + 1), diff)); __m64 out = _mm_add_pi32(Load64MMX(pDry), nDCRRvb_X1); nDCRRvb_Y1 = _mm_sub_pi32(nDCRRvb_X1, _mm_srai_pi32(nDCRRvb_X1, DCR_AMOUNT)); nDCRRvb_X1 = in; Store64MMX(pDry, out); pDry += 2; } Store64MMX(gnDCRRvb_X1, in); Store64MMX(gnDCRRvb_Y1, nDCRRvb_Y1); _mm_empty(); return; } #endif int32 X1L = gnDCRRvb_X1[0], X1R = gnDCRRvb_X1[1]; int32 Y1L = gnDCRRvb_Y1[0], Y1R = gnDCRRvb_Y1[1]; int32 inL = 0, inR = 0; while(nSamples--) { inL = pRvb[0]; inR = pRvb[1]; pRvb += 2; int32 outL = pDry[0], outR = pDry[1]; // x(n-1) - x(n) X1L -= inL; X1R -= inR; X1L = X1L / (1 << (DCR_AMOUNT + 1)) - X1L; X1R = X1R / (1 << (DCR_AMOUNT + 1)) - X1R; Y1L += X1L; Y1R += X1R; // add to dry mix outL += Y1L; outR += Y1R; Y1L -= Y1L / (1 << DCR_AMOUNT); Y1R -= Y1R / (1 << DCR_AMOUNT); X1L = inL; X1R = inR; pDry[0] = outL; pDry[1] = outR; pDry += 2; } gnDCRRvb_Y1[0] = Y1L; gnDCRRvb_Y1[1] = Y1R; gnDCRRvb_X1[0] = inL; gnDCRRvb_X1[1] = inR; } void CReverb::ReverbDCRemoval(int32 * MPT_RESTRICT pBuffer, uint32 nSamples) { #ifdef ENABLE_MMX if(GetProcSupport() & PROCSUPPORT_MMX) { __m64 nDCRRvb_Y1 = Load64MMX(gnDCRRvb_Y1); __m64 nDCRRvb_X1 = Load64MMX(gnDCRRvb_X1); while(nSamples--) { __m64 in = Load64MMX(pBuffer); __m64 diff = _mm_sub_pi32(nDCRRvb_X1, in); __m64 out = _mm_add_pi32(nDCRRvb_Y1, _mm_sub_pi32(_mm_srai_pi32(diff, DCR_AMOUNT + 1), diff)); Store64MMX(pBuffer, out); pBuffer += 2; nDCRRvb_Y1 = _mm_sub_pi32(out, _mm_srai_pi32(out, DCR_AMOUNT)); nDCRRvb_X1 = in; } Store64MMX(gnDCRRvb_X1, nDCRRvb_X1); Store64MMX(gnDCRRvb_Y1, nDCRRvb_Y1); _mm_empty(); return; } #endif int32 X1L = gnDCRRvb_X1[0], X1R = gnDCRRvb_X1[1]; int32 Y1L = gnDCRRvb_Y1[0], Y1R = gnDCRRvb_Y1[1]; int32 inL = 0, inR = 0; while(nSamples--) { inL = pBuffer[0]; inR = pBuffer[1]; // x(n-1) - x(n) X1L -= inL; X1R -= inR; X1L = X1L / (1 << (DCR_AMOUNT + 1)) - X1L; X1R = X1R / (1 << (DCR_AMOUNT + 1)) - X1R; Y1L += X1L; Y1R += X1R; pBuffer[0] = Y1L; pBuffer[1] = Y1R; pBuffer += 2; Y1L -= Y1L / (1 << DCR_AMOUNT); Y1R -= Y1R / (1 << DCR_AMOUNT); X1L = inL; X1R = inR; } gnDCRRvb_Y1[0] = Y1L; gnDCRRvb_Y1[1] = Y1R; gnDCRRvb_X1[0] = inL; gnDCRRvb_X1[1] = inR; } ////////////////////////////////////////////////////////////////////////// // // Pre-Delay: // // 1. Saturate and low-pass the reverb input (stage 2 of roomHF) // 2. Process pre-diffusion // 3. Insert the result in the reflections delay buffer // // Save some typing static MPT_FORCEINLINE int32 Clamp16(int32 x) { return Clamp(x, int16_min, int16_max); } void CReverb::ProcessPreDelay(SWRvbRefDelay * MPT_RESTRICT pPreDelay, const int32 * MPT_RESTRICT pIn, uint32 nSamples) { uint32 preDifPos = pPreDelay->nPreDifPos; uint32 delayPos = pPreDelay->nDelayPos - 1; #ifdef ENABLE_SSE2 if(GetProcSupport() & PROCSUPPORT_SSE2) { __m128i coeffs = _mm_cvtsi32_si128(pPreDelay->nCoeffs.lr); __m128i history = _mm_cvtsi32_si128(pPreDelay->History.lr); __m128i preDifCoeffs = _mm_cvtsi32_si128(pPreDelay->nPreDifCoeffs.lr); while(nSamples--) { __m128i in32 = Load64SSE(pIn); // 16-bit unsaturated reverb input [ r | l ] __m128i inSat = _mm_packs_epi32(in32, in32); // [ r | l | r | l ] (16-bit saturated) pIn += 2; // Low-pass __m128i lp = _mm_mulhi_epi16(_mm_subs_epi16(history, inSat), coeffs); __m128i preDif = _mm_cvtsi32_si128(pPreDelay->PreDifBuffer[preDifPos].lr); history = _mm_adds_epi16(_mm_adds_epi16(lp, lp), inSat); // Pre-Diffusion preDifPos = (preDifPos + 1) & SNDMIX_PREDIFFUSION_DELAY_MASK; delayPos = (delayPos + 1) & SNDMIX_REFLECTIONS_DELAY_MASK; __m128i preDif2 = _mm_subs_epi16(history, _mm_mulhi_epi16(preDif, preDifCoeffs)); pPreDelay->PreDifBuffer[preDifPos].lr = _mm_cvtsi128_si32(preDif2); pPreDelay->RefDelayBuffer[delayPos].lr = _mm_cvtsi128_si32(_mm_adds_epi16(_mm_mulhi_epi16(preDifCoeffs, preDif2), preDif)); } pPreDelay->nPreDifPos = preDifPos; pPreDelay->History.lr = _mm_cvtsi128_si32(history); return; } #endif #ifdef ENABLE_MMX if(GetProcSupport() & PROCSUPPORT_MMX) { __m64 coeffs = _mm_cvtsi32_si64(pPreDelay->nCoeffs.lr); __m64 history = _mm_cvtsi32_si64(pPreDelay->History.lr); __m64 preDifCoeffs = _mm_cvtsi32_si64(pPreDelay->nPreDifCoeffs.lr); while(nSamples--) { __m64 in32 = Load64MMX(pIn); // 16-bit unsaturated reverb input [ r | l ] __m64 inSat = _mm_packs_pi32(in32, in32); // [ r | l | r | l ] (16-bit saturated) pIn += 2; // Low-pass __m64 lp = _mm_mulhi_pi16(_mm_subs_pi16(history, inSat), coeffs); __m64 preDif = _mm_cvtsi32_si64(pPreDelay->PreDifBuffer[preDifPos].lr); history = _mm_adds_pi16(_mm_adds_pi16(lp, lp), inSat); // Pre-Diffusion preDifPos = (preDifPos + 1) & SNDMIX_PREDIFFUSION_DELAY_MASK; delayPos = (delayPos + 1) & SNDMIX_REFLECTIONS_DELAY_MASK; __m64 preDif2 = _mm_subs_pi16(history, _mm_mulhi_pi16(preDif, preDifCoeffs)); pPreDelay->PreDifBuffer[preDifPos].lr = _mm_cvtsi64_si32(preDif2); pPreDelay->RefDelayBuffer[delayPos].lr = _mm_cvtsi64_si32(_mm_adds_pi16(_mm_mulhi_pi16(preDifCoeffs, preDif2), preDif)); } pPreDelay->nPreDifPos = preDifPos; pPreDelay->History.lr = _mm_cvtsi64_si32(history); _mm_empty(); return; } #endif const int32 coeffsL = pPreDelay->nCoeffs.c.l, coeffsR = pPreDelay->nCoeffs.c.r; const int32 preDifCoeffsL = pPreDelay->nPreDifCoeffs.c.l, preDifCoeffsR = pPreDelay->nPreDifCoeffs.c.r; int16 historyL = pPreDelay->History.c.l, historyR = pPreDelay->History.c.r; while(nSamples--) { int32 inL = Clamp16(pIn[0]); int32 inR = Clamp16(pIn[1]); pIn += 2; // Low-pass int32 lpL = (Clamp16(historyL - inL) * coeffsL) / 65536; int32 lpR = (Clamp16(historyR - inR) * coeffsR) / 65536; historyL = mpt::saturate_cast(Clamp16(lpL + lpL) + inL); historyR = mpt::saturate_cast(Clamp16(lpR + lpR) + inR); // Pre-Diffusion int32 preDifL = pPreDelay->PreDifBuffer[preDifPos].c.l; int32 preDifR = pPreDelay->PreDifBuffer[preDifPos].c.r; preDifPos = (preDifPos + 1) & SNDMIX_PREDIFFUSION_DELAY_MASK; delayPos = (delayPos + 1) & SNDMIX_REFLECTIONS_DELAY_MASK; int16 preDif2L = mpt::saturate_cast(historyL - preDifL * preDifCoeffsL / 65536); int16 preDif2R = mpt::saturate_cast(historyR - preDifR * preDifCoeffsR / 65536); pPreDelay->PreDifBuffer[preDifPos].c.l = preDif2L; pPreDelay->PreDifBuffer[preDifPos].c.r = preDif2R; pPreDelay->RefDelayBuffer[delayPos].c.l = mpt::saturate_cast(preDifCoeffsL * preDif2L / 65536 + preDifL); pPreDelay->RefDelayBuffer[delayPos].c.r = mpt::saturate_cast(preDifCoeffsR * preDif2R / 65536 + preDifR); } pPreDelay->nPreDifPos = preDifPos; pPreDelay->History.c.l = historyL; pPreDelay->History.c.r = historyR; } //////////////////////////////////////////////////////////////////// // // ProcessReflections: // First stage: // - process 4 reflections, output to pRefOut // - output results to pRefOut // Second stage: // - process another 3 reflections // - sum with pRefOut // - apply reflections master gain and accumulate in the given output // void CReverb::ProcessReflections(SWRvbRefDelay * MPT_RESTRICT pPreDelay, LR16 * MPT_RESTRICT pRefOut, int32 * MPT_RESTRICT pOut, uint32 nSamples) { #ifdef ENABLE_SSE2 if(GetProcSupport() & PROCSUPPORT_SSE2) { union { __m128i xmm; int16 i[8]; } pos; const LR16 *refDelayBuffer = pPreDelay->RefDelayBuffer; #define GETDELAY(x) static_cast(pPreDelay->Reflections[x].Delay) __m128i delayPos = _mm_set_epi16(GETDELAY(7), GETDELAY(6), GETDELAY(5), GETDELAY(4), GETDELAY(3), GETDELAY(2), GETDELAY(1), GETDELAY(0)); #undef GETDELAY delayPos = _mm_sub_epi16(_mm_set1_epi16(static_cast(pPreDelay->nDelayPos - 1)), delayPos); __m128i gain12 = _mm_unpacklo_epi64(Load64SSE(pPreDelay->Reflections[0].Gains), Load64SSE(pPreDelay->Reflections[1].Gains)); __m128i gain34 = _mm_unpacklo_epi64(Load64SSE(pPreDelay->Reflections[2].Gains), Load64SSE(pPreDelay->Reflections[3].Gains)); __m128i gain56 = _mm_unpacklo_epi64(Load64SSE(pPreDelay->Reflections[4].Gains), Load64SSE(pPreDelay->Reflections[5].Gains)); __m128i gain78 = _mm_unpacklo_epi64(Load64SSE(pPreDelay->Reflections[6].Gains), Load64SSE(pPreDelay->Reflections[7].Gains)); // For 28-bit final output: 16+15-3 = 28 __m128i refGain = _mm_srai_epi32(_mm_set_epi32(0, 0, pPreDelay->ReflectionsGain.c.r, pPreDelay->ReflectionsGain.c.l), 3); __m128i delayInc = _mm_set1_epi16(1), delayMask = _mm_set1_epi16(SNDMIX_REFLECTIONS_DELAY_MASK); while(nSamples--) { delayPos = _mm_and_si128(_mm_add_epi16(delayInc, delayPos), delayMask); _mm_storeu_si128(&pos.xmm, delayPos); __m128i ref12 = _mm_set_epi32(refDelayBuffer[pos.i[1]].lr, refDelayBuffer[pos.i[1]].lr, refDelayBuffer[pos.i[0]].lr, refDelayBuffer[pos.i[0]].lr); __m128i ref34 = _mm_set_epi32(refDelayBuffer[pos.i[3]].lr, refDelayBuffer[pos.i[3]].lr, refDelayBuffer[pos.i[2]].lr, refDelayBuffer[pos.i[2]].lr); __m128i ref56 = _mm_set_epi32(refDelayBuffer[pos.i[5]].lr, refDelayBuffer[pos.i[5]].lr, refDelayBuffer[pos.i[4]].lr, refDelayBuffer[pos.i[4]].lr); __m128i ref78 = _mm_set_epi32(0, 0, refDelayBuffer[pos.i[6]].lr, refDelayBuffer[pos.i[6]].lr); // First stage __m128i refOut1 = _mm_add_epi32(_mm_madd_epi16(ref12, gain12), _mm_madd_epi16(ref34, gain34)); refOut1 = _mm_srai_epi32(_mm_add_epi32(refOut1, _mm_shuffle_epi32(refOut1, _MM_SHUFFLE(1, 0, 3, 2))), 15); // Second stage __m128i refOut2 = _mm_add_epi32(_mm_madd_epi16(ref56, gain56), _mm_madd_epi16(ref78, gain78)); refOut2 = _mm_srai_epi32(_mm_add_epi32(refOut2, _mm_shuffle_epi32(refOut2, _MM_SHUFFLE(1, 0, 3, 2))), 15); // Saturate to 16-bit and sum stages __m128i refOut = _mm_adds_epi16(_mm_packs_epi32(refOut1, refOut1), _mm_packs_epi32(refOut2, refOut2)); pRefOut->lr = _mm_cvtsi128_si32(refOut); pRefOut++; __m128i out = _mm_madd_epi16(_mm_unpacklo_epi16(refOut, refOut), refGain); // Apply reflections gain // At this, point, this is the only output of the reverb Store64SSE(pOut, out); pOut += 2; } return; } #endif #ifdef ENABLE_MMX if(GetProcSupport() & PROCSUPPORT_MMX) { // First stage uint32 numSamples = nSamples; const LR16 *refDelayBuffer = pPreDelay->RefDelayBuffer; int pos1 = pPreDelay->nDelayPos - pPreDelay->Reflections[0].Delay - 1; int pos2 = pPreDelay->nDelayPos - pPreDelay->Reflections[1].Delay - 1; int pos3 = pPreDelay->nDelayPos - pPreDelay->Reflections[2].Delay - 1; int pos4 = pPreDelay->nDelayPos - pPreDelay->Reflections[3].Delay - 1; __m64 gain1 = Load64MMX(pPreDelay->Reflections[0].Gains); __m64 gain2 = Load64MMX(pPreDelay->Reflections[1].Gains); __m64 gain3 = Load64MMX(pPreDelay->Reflections[2].Gains); __m64 gain4 = Load64MMX(pPreDelay->Reflections[3].Gains); while(numSamples--) { pos1 = (pos1 + 1) & SNDMIX_REFLECTIONS_DELAY_MASK; pos2 = (pos2 + 1) & SNDMIX_REFLECTIONS_DELAY_MASK; pos3 = (pos3 + 1) & SNDMIX_REFLECTIONS_DELAY_MASK; pos4 = (pos4 + 1) & SNDMIX_REFLECTIONS_DELAY_MASK; __m64 ref1 = _mm_cvtsi32_si64(refDelayBuffer[pos1].lr); // [0 | 0 | r | l ] __m64 ref2 = _mm_cvtsi32_si64(refDelayBuffer[pos2].lr); __m64 ref3 = _mm_cvtsi32_si64(refDelayBuffer[pos3].lr); __m64 ref4 = _mm_cvtsi32_si64(refDelayBuffer[pos4].lr); __m64 refOut = _mm_srai_pi32(_mm_add_pi32( _mm_add_pi32(_mm_madd_pi16(_mm_unpacklo_pi32(ref1, ref1), gain1), _mm_madd_pi16(_mm_unpacklo_pi32(ref2, ref2), gain2)), _mm_add_pi32(_mm_madd_pi16(_mm_unpacklo_pi32(ref3, ref3), gain3), _mm_madd_pi16(_mm_unpacklo_pi32(ref4, ref4), gain4))), 15); pRefOut->lr = _mm_cvtsi64_si32(_mm_packs_pi32(refOut, refOut)); pRefOut++; } // Second stage numSamples = nSamples; pRefOut -= nSamples; __m64 refGain = _mm_unpacklo_pi16(_mm_cvtsi32_si64(pPreDelay->ReflectionsGain.lr), _mm_cvtsi32_si64(0)); // [0 | g_r | 0 | g_l] refGain = _mm_srai_pi32(refGain, 3); // For 28-bit final output: 16+15-3 = 28 int pos5 = pPreDelay->nDelayPos - pPreDelay->Reflections[4].Delay - 1; int pos6 = pPreDelay->nDelayPos - pPreDelay->Reflections[5].Delay - 1; int pos7 = pPreDelay->nDelayPos - pPreDelay->Reflections[6].Delay - 1; __m64 gain5 = Load64MMX(pPreDelay->Reflections[4].Gains); __m64 gain6 = Load64MMX(pPreDelay->Reflections[5].Gains); __m64 gain7 = Load64MMX(pPreDelay->Reflections[6].Gains); while(numSamples--) { pos5 = (pos5 + 1) & SNDMIX_REFLECTIONS_DELAY_MASK; pos6 = (pos6 + 1) & SNDMIX_REFLECTIONS_DELAY_MASK; pos7 = (pos7 + 1) & SNDMIX_REFLECTIONS_DELAY_MASK; __m64 ref5 = _mm_cvtsi32_si64(refDelayBuffer[pos5].lr); // [0 | 0 | r | l ] __m64 ref6 = _mm_cvtsi32_si64(refDelayBuffer[pos6].lr); __m64 ref7 = _mm_cvtsi32_si64(refDelayBuffer[pos7].lr); __m64 refPrev = _mm_cvtsi32_si64(pRefOut->lr); // output of previous reflections __m64 refOut = _mm_srai_pi32(_mm_add_pi32( _mm_add_pi32(_mm_madd_pi16(_mm_unpacklo_pi32(ref5, ref5), gain5), _mm_madd_pi16(_mm_unpacklo_pi32(ref7, ref7), gain7)), _mm_madd_pi16(_mm_unpacklo_pi32(ref6, ref6), gain6)), 15); refOut = _mm_adds_pi16(_mm_packs_pi32(refOut, refOut), refPrev); pRefOut->lr = _mm_cvtsi64_si32(refOut); // late reverb stereo input pRefOut++; __m64 out = _mm_madd_pi16(_mm_unpacklo_pi16(refOut, refOut), refGain); // Apply reflections gain // At this, point, this is the only output of the reverb Store64MMX(pOut, out); pOut += 2; } _mm_empty(); return; } #endif int pos[7]; for(int i = 0; i < 7; i++) pos[i] = pPreDelay->nDelayPos - pPreDelay->Reflections[i].Delay - 1; // For 28-bit final output: 16+15-3 = 28 int16 refGain = pPreDelay->ReflectionsGain.c.l / (1 << 3); while(nSamples--) { // First stage int32 refOutL = 0, refOutR = 0; for(int i = 0; i < 4; i++) { pos[i] = (pos[i] + 1) & SNDMIX_REFLECTIONS_DELAY_MASK; int16 refL = pPreDelay->RefDelayBuffer[pos[i]].c.l, refR = pPreDelay->RefDelayBuffer[pos[i]].c.r; refOutL += refL * pPreDelay->Reflections[i].Gains[0].c.l + refR * pPreDelay->Reflections[i].Gains[0].c.r; refOutR += refL * pPreDelay->Reflections[i].Gains[1].c.l + refR * pPreDelay->Reflections[i].Gains[1].c.r; } int16 stage1l = mpt::saturate_cast(refOutL / (1 << 15)); int16 stage1r = mpt::saturate_cast(refOutR / (1 << 15)); // Second stage refOutL = 0; refOutR = 0; for(int i = 4; i < 7; i++) { pos[i] = (pos[i] + 1) & SNDMIX_REFLECTIONS_DELAY_MASK; int16 refL = pPreDelay->RefDelayBuffer[pos[i]].c.l, refR = pPreDelay->RefDelayBuffer[pos[i]].c.r; refOutL += refL * pPreDelay->Reflections[i].Gains[0].c.l + refR * pPreDelay->Reflections[i].Gains[0].c.r; refOutR += refL * pPreDelay->Reflections[i].Gains[1].c.l + refR * pPreDelay->Reflections[i].Gains[1].c.r; } pOut[0] = (pRefOut->c.l = mpt::saturate_cast(stage1l + refOutL / (1 << 15))) * refGain; pOut[1] = (pRefOut->c.r = mpt::saturate_cast(stage1r + refOutR / (1 << 15))) * refGain; pRefOut++; pOut += 2; } } ////////////////////////////////////////////////////////////////////////// // // Late reverberation (with SW reflections) // void CReverb::ProcessLateReverb(SWLateReverb * MPT_RESTRICT pReverb, LR16 * MPT_RESTRICT pRefOut, int32 * MPT_RESTRICT pMixOut, uint32 nSamples) { // Calculate delay line offset from current delay position #define DELAY_OFFSET(x) ((delayPos - (x)) & RVBDLY_MASK) #ifdef ENABLE_SSE2 if(GetProcSupport() & PROCSUPPORT_SSE2) { int delayPos = pReverb->nDelayPos & RVBDLY_MASK; __m128i rvbOutGains = Load64SSE(pReverb->RvbOutGains); __m128i difCoeffs = Load64SSE(pReverb->nDifCoeffs); __m128i decayLP = Load64SSE(pReverb->nDecayLP); __m128i lpHistory = Load64SSE(pReverb->LPHistory); while(nSamples--) { __m128i refIn = _mm_cvtsi32_si128(pRefOut->lr); // 16-bit stereo input pRefOut++; __m128i delay2 = _mm_unpacklo_epi32( _mm_cvtsi32_si128(pReverb->Delay2[DELAY_OFFSET(RVBDLY2L_LEN)].lr), _mm_cvtsi32_si128(pReverb->Delay2[DELAY_OFFSET(RVBDLY2R_LEN)].lr)); // Unsigned to avoid sign extension uint16 diff1L = pReverb->Diffusion1[DELAY_OFFSET(RVBDIF1L_LEN)].c.l; uint16 diff1R = pReverb->Diffusion1[DELAY_OFFSET(RVBDIF1R_LEN)].c.r; int32 diffusion1 = diff1L | (diff1R << 16); // diffusion1 history uint16 diff2L = pReverb->Diffusion2[DELAY_OFFSET(RVBDIF2L_LEN)].c.l; uint16 diff2R = pReverb->Diffusion2[DELAY_OFFSET(RVBDIF2R_LEN)].c.r; int32 diffusion2 = diff2L | (diff2R << 16); // diffusion2 history __m128i lpDecay = _mm_mulhi_epi16(_mm_subs_epi16(lpHistory, delay2), decayLP); lpHistory = _mm_adds_epi16(_mm_adds_epi16(lpDecay, lpDecay), delay2); // Low-passed decay // Apply decay gain __m128i histDecay = _mm_srai_epi32(_mm_madd_epi16(Load64SSE(pReverb->nDecayDC), lpHistory), 15); __m128i histDecayPacked = _mm_shuffle_epi32(_mm_packs_epi32(histDecay, histDecay), _MM_SHUFFLE(2, 0, 2, 0)); __m128i histDecayIn = _mm_adds_epi16(_mm_shuffle_epi32(_mm_packs_epi32(histDecay, histDecay), _MM_SHUFFLE(2, 0, 2, 0)), _mm_srai_epi16(_mm_unpacklo_epi32(refIn, refIn), 2)); __m128i histDecayInDiff = _mm_subs_epi16(histDecayIn, _mm_mulhi_epi16(_mm_cvtsi32_si128(diffusion1), difCoeffs)); pReverb->Diffusion1[delayPos].lr = _mm_cvtsi128_si32(histDecayInDiff); __m128i delay1Out = _mm_adds_epi16(_mm_mulhi_epi16(difCoeffs, histDecayInDiff), _mm_cvtsi32_si128(diffusion1)); // Insert the diffusion output in the reverb delay line pReverb->Delay1[delayPos].lr = _mm_cvtsi128_si32(delay1Out); __m128i histDecayInDelay = _mm_adds_epi16(histDecayIn, _mm_unpacklo_epi32(delay1Out, delay1Out)); // Input to second diffuser __m128i delay1 = _mm_unpacklo_epi32( _mm_cvtsi32_si128(pReverb->Delay1[DELAY_OFFSET(RVBDLY1L_LEN)].lr), _mm_cvtsi32_si128(pReverb->Delay1[DELAY_OFFSET(RVBDLY1R_LEN)].lr)); __m128i delay1Gains = _mm_srai_epi32(_mm_madd_epi16(delay1, Load64SSE(pReverb->Dif2InGains)), 15); __m128i delay1GainsSat = _mm_shuffle_epi32(_mm_packs_epi32(delay1Gains, delay1Gains), _MM_SHUFFLE(2, 0, 2, 0)); __m128i histDelay1 = _mm_subs_epi16(_mm_adds_epi16(histDecayInDelay, delay1), delay1GainsSat); // accumulate with reverb output __m128i diff2out = _mm_subs_epi16(delay1GainsSat, _mm_mulhi_epi16(_mm_cvtsi32_si128(diffusion2), difCoeffs)); __m128i diff2outCoeffs = _mm_mulhi_epi16(difCoeffs, diff2out); pReverb->Diffusion2[delayPos].lr = _mm_cvtsi128_si32(diff2out); __m128i mixOut = Load64SSE(pMixOut); __m128i delay2out = _mm_adds_epi16(diff2outCoeffs, _mm_cvtsi32_si128(diffusion2)); pReverb->Delay2[delayPos].lr = _mm_cvtsi128_si32(delay2out); delayPos = (delayPos + 1) & RVBDLY_MASK; // Accumulate with reverb output __m128i out = _mm_add_epi32(_mm_madd_epi16(_mm_adds_epi16(histDelay1, delay2out), rvbOutGains), mixOut); Store64SSE(pMixOut, out); pMixOut += 2; } Store64SSE(pReverb->LPHistory, lpHistory); pReverb->nDelayPos = delayPos; return; } #endif #ifdef ENABLE_MMX if(GetProcSupport() & PROCSUPPORT_MMX) { int delayPos = pReverb->nDelayPos & RVBDLY_MASK; __m64 rvbOutGains = Load64MMX(pReverb->RvbOutGains); __m64 difCoeffs = Load64MMX(pReverb->nDifCoeffs); __m64 decayLP = Load64MMX(pReverb->nDecayLP); __m64 lpHistory = Load64MMX(pReverb->LPHistory); while(nSamples--) { __m64 refIn = _mm_cvtsi32_si64(pRefOut->lr); // 16-bit stereo input pRefOut++; __m64 delay2 = _mm_unpacklo_pi32( _mm_cvtsi32_si64(pReverb->Delay2[DELAY_OFFSET(RVBDLY2L_LEN)].lr), _mm_cvtsi32_si64(pReverb->Delay2[DELAY_OFFSET(RVBDLY2R_LEN)].lr)); // Unsigned to avoid sign extension uint16 diff1L = pReverb->Diffusion1[DELAY_OFFSET(RVBDIF1L_LEN)].c.l; uint16 diff1R = pReverb->Diffusion1[DELAY_OFFSET(RVBDIF1R_LEN)].c.r; int32 diffusion1 = diff1L | (diff1R << 16); // diffusion1 history uint16 diff2L = pReverb->Diffusion2[DELAY_OFFSET(RVBDIF2L_LEN)].c.l; uint16 diff2R = pReverb->Diffusion2[DELAY_OFFSET(RVBDIF2R_LEN)].c.r; int32 diffusion2 = diff2L | (diff2R << 16); // diffusion2 history __m64 lpDecay = _mm_mulhi_pi16(_mm_subs_pi16(lpHistory, delay2), decayLP); lpHistory = _mm_adds_pi16(_mm_adds_pi16(lpDecay, lpDecay), delay2); // Low-passed decay // Apply decay gain __m64 histDecay = _mm_srai_pi32(_mm_madd_pi16(Load64MMX(pReverb->nDecayDC), lpHistory), 15); __m64 histDecayIn = _mm_adds_pi16(_mm_packs_pi32(histDecay, histDecay), _mm_srai_pi16(_mm_unpacklo_pi32(refIn, refIn), 2)); __m64 histDecayInDiff = _mm_subs_pi16(histDecayIn, _mm_mulhi_pi16(_mm_cvtsi32_si64(diffusion1), difCoeffs)); pReverb->Diffusion1[delayPos].lr = _mm_cvtsi64_si32(histDecayInDiff); __m64 delay1Out = _mm_adds_pi16(_mm_mulhi_pi16(difCoeffs, histDecayInDiff), _mm_cvtsi32_si64(diffusion1)); // Insert the diffusion output in the reverb delay line pReverb->Delay1[delayPos].lr = _mm_cvtsi64_si32(delay1Out); __m64 histDecayInDelay = _mm_adds_pi16(histDecayIn, _mm_unpacklo_pi32(delay1Out, delay1Out)); // Input to second diffuser __m64 delay1 = _mm_unpacklo_pi32( _mm_cvtsi32_si64(pReverb->Delay1[DELAY_OFFSET(RVBDLY1L_LEN)].lr), _mm_cvtsi32_si64(pReverb->Delay1[DELAY_OFFSET(RVBDLY1R_LEN)].lr)); __m64 delay1Gains = _mm_srai_pi32(_mm_madd_pi16(delay1, Load64MMX(pReverb->Dif2InGains)), 15); __m64 delay1GainsSat = _mm_packs_pi32(delay1Gains, delay1Gains); __m64 histDelay1 = _mm_subs_pi16(_mm_adds_pi16(histDecayInDelay, delay1), delay1GainsSat); // accumulate with reverb output __m64 diff2out = _mm_subs_pi16(delay1GainsSat, _mm_mulhi_pi16(_mm_cvtsi32_si64(diffusion2), difCoeffs)); __m64 diff2outCoeffs = _mm_mulhi_pi16(difCoeffs, diff2out); pReverb->Diffusion2[delayPos].lr = _mm_cvtsi64_si32(diff2out); __m64 mixOut = Load64MMX(pMixOut); __m64 delay2out = _mm_adds_pi16(diff2outCoeffs, _mm_cvtsi32_si64(diffusion2)); pReverb->Delay2[delayPos].lr = _mm_cvtsi64_si32(delay2out); delayPos = (delayPos + 1) & RVBDLY_MASK; // Accumulate with reverb output __m64 out = _mm_add_pi32(_mm_madd_pi16(_mm_adds_pi16(histDelay1, delay2out), rvbOutGains), mixOut); Store64MMX(pMixOut, out); pMixOut += 2; } Store64MMX(&pReverb->LPHistory[0].lr, lpHistory); pReverb->nDelayPos = delayPos; _mm_empty(); return; } #endif int delayPos = pReverb->nDelayPos & RVBDLY_MASK; while(nSamples--) { int16 refInL = pRefOut->c.l, refInR = pRefOut->c.r; pRefOut++; int32 delay2LL = pReverb->Delay2[DELAY_OFFSET(RVBDLY2L_LEN)].c.l, delay2LR = pReverb->Delay2[DELAY_OFFSET(RVBDLY2L_LEN)].c.r; int32 delay2RL = pReverb->Delay2[DELAY_OFFSET(RVBDLY2R_LEN)].c.l, delay2RR = pReverb->Delay2[DELAY_OFFSET(RVBDLY2R_LEN)].c.r; int32 diff1L = pReverb->Diffusion1[DELAY_OFFSET(RVBDIF1L_LEN)].c.l; int32 diff1R = pReverb->Diffusion1[DELAY_OFFSET(RVBDIF1R_LEN)].c.r; int32 diff2L = pReverb->Diffusion2[DELAY_OFFSET(RVBDIF2L_LEN)].c.l; int32 diff2R = pReverb->Diffusion2[DELAY_OFFSET(RVBDIF2R_LEN)].c.r; int32 lpDecayLL = Clamp16(pReverb->LPHistory[0].c.l - delay2LL) * pReverb->nDecayLP[0].c.l / 65536; int32 lpDecayLR = Clamp16(pReverb->LPHistory[0].c.r - delay2LR) * pReverb->nDecayLP[0].c.r / 65536; int32 lpDecayRL = Clamp16(pReverb->LPHistory[1].c.l - delay2RL) * pReverb->nDecayLP[1].c.l / 65536; int32 lpDecayRR = Clamp16(pReverb->LPHistory[1].c.r - delay2RR) * pReverb->nDecayLP[1].c.r / 65536; // Low-passed decay pReverb->LPHistory[0].c.l = mpt::saturate_cast(Clamp16(lpDecayLL + lpDecayLL) + delay2LL); pReverb->LPHistory[0].c.r = mpt::saturate_cast(Clamp16(lpDecayLR + lpDecayLR) + delay2LR); pReverb->LPHistory[1].c.l = mpt::saturate_cast(Clamp16(lpDecayRL + lpDecayRL) + delay2RL); pReverb->LPHistory[1].c.r = mpt::saturate_cast(Clamp16(lpDecayRR + lpDecayRR) + delay2RR); // Apply decay gain int32 histDecayL = Clamp16((int32)pReverb->nDecayDC[0].c.l * pReverb->LPHistory[0].c.l / (1 << 15)); int32 histDecayR = Clamp16((int32)pReverb->nDecayDC[1].c.r * pReverb->LPHistory[1].c.r / (1 << 15)); int32 histDecayInL = Clamp16(histDecayL + refInL / 4); int32 histDecayInR = Clamp16(histDecayR + refInR / 4); int32 histDecayInDiffL = Clamp16(histDecayInL - diff1L * pReverb->nDifCoeffs[0].c.l / 65536); int32 histDecayInDiffR = Clamp16(histDecayInR - diff1R * pReverb->nDifCoeffs[0].c.r / 65536); pReverb->Diffusion1[delayPos].c.l = static_cast(histDecayInDiffL); pReverb->Diffusion1[delayPos].c.r = static_cast(histDecayInDiffR); int32 delay1L = Clamp16(pReverb->nDifCoeffs[0].c.l * histDecayInDiffL / 65536 + diff1L); int32 delay1R = Clamp16(pReverb->nDifCoeffs[0].c.r * histDecayInDiffR / 65536 + diff1R); // Insert the diffusion output in the reverb delay line pReverb->Delay1[delayPos].c.l = static_cast(delay1L); pReverb->Delay1[delayPos].c.r = static_cast(delay1R); int32 histDecayInDelayL = Clamp16(histDecayInL + delay1L); int32 histDecayInDelayR = Clamp16(histDecayInR + delay1R); // Input to second diffuser int32 delay1LL = pReverb->Delay1[DELAY_OFFSET(RVBDLY1L_LEN)].c.l, delay1LR = pReverb->Delay1[DELAY_OFFSET(RVBDLY1L_LEN)].c.r; int32 delay1RL = pReverb->Delay1[DELAY_OFFSET(RVBDLY1R_LEN)].c.l, delay1RR = pReverb->Delay1[DELAY_OFFSET(RVBDLY1R_LEN)].c.r; int32 delay1GainsL = Clamp16((delay1LL * pReverb->Dif2InGains[0].c.l + delay1LR * pReverb->Dif2InGains[0].c.r) / (1 << 15)); int32 delay1GainsR = Clamp16((delay1RL * pReverb->Dif2InGains[1].c.l + delay1RR * pReverb->Dif2InGains[1].c.r) / (1 << 15)); // accumulate with reverb output int32 histDelay1LL = Clamp16(Clamp16(histDecayInDelayL + delay1LL) - delay1GainsL); int32 histDelay1LR = Clamp16(Clamp16(histDecayInDelayR + delay1LR) - delay1GainsR); int32 histDelay1RL = Clamp16(Clamp16(histDecayInDelayL + delay1RL) - delay1GainsL); int32 histDelay1RR = Clamp16(Clamp16(histDecayInDelayR + delay1RR) - delay1GainsR); int32 diff2outL = Clamp16(delay1GainsL - diff2L * pReverb->nDifCoeffs[0].c.l / 65536); int32 diff2outR = Clamp16(delay1GainsR - diff2R * pReverb->nDifCoeffs[0].c.r / 65536); int32 diff2outCoeffsL = pReverb->nDifCoeffs[0].c.l * diff2outL / 65536; int32 diff2outCoeffsR = pReverb->nDifCoeffs[0].c.r * diff2outR / 65536; pReverb->Diffusion2[delayPos].c.l = static_cast(diff2outL); pReverb->Diffusion2[delayPos].c.r = static_cast(diff2outR); int32 delay2outL = Clamp16(diff2outCoeffsL + diff2L); int32 delay2outR = Clamp16(diff2outCoeffsR + diff2R); pReverb->Delay2[delayPos].c.l = static_cast(delay2outL); pReverb->Delay2[delayPos].c.r = static_cast(delay2outR); delayPos = (delayPos + 1) & RVBDLY_MASK; // Accumulate with reverb output pMixOut[0] += Clamp16(histDelay1LL + delay2outL) * pReverb->RvbOutGains[0].c.l + Clamp16(histDelay1LR + delay2outR) * pReverb->RvbOutGains[0].c.r; pMixOut[1] += Clamp16(histDelay1RL + Clamp16(diff2outCoeffsL)) * pReverb->RvbOutGains[1].c.l + Clamp16(histDelay1RR + Clamp16(diff2outCoeffsR)) * pReverb->RvbOutGains[1].c.r; pMixOut += 2; } pReverb->nDelayPos = delayPos; #undef DELAY_OFFSET } #else MPT_MSVC_WORKAROUND_LNK4221(Reverb) #endif // NO_REVERB OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/sounddsp/DSP.cpp0000644000372100037210000002444713161656666017302 00000000000000/* * DSP.cpp * ----------- * Purpose: Mixing code for various DSPs (EQ, Mega-Bass, ...) * Notes : Ugh... This should really be removed at some point. * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "../soundlib/Sndfile.h" #include "../sounddsp/DSP.h" #include OPENMPT_NAMESPACE_BEGIN #ifndef NO_DSP // Bass Expansion #define DEFAULT_XBASS_RANGE 14 // (x+2)*20 Hz (320Hz) #define DEFAULT_XBASS_DEPTH 6 // 1+(3>>(x-4)) (+6dB) //////////////////////////////////////////////////////////////////// // DSP Effects internal state static void X86_StereoDCRemoval(int *, uint32 count, int32 &nDCRFlt_Y1l, int32 &nDCRFlt_X1l, int32 &nDCRFlt_Y1r, int32 &nDCRFlt_X1r); static void X86_MonoDCRemoval(int *, uint32 count, int32 &nDCRFlt_Y1l, int32 &nDCRFlt_X1l); /////////////////////////////////////////////////////////////////////////////////// // // Biquad setup // #define PI 3.14159265358979323f static inline float Sgn(float x) { return (x >= 0) ? 1.0f : -1.0f; } static void ShelfEQ(int32 scale, int32 &outA1, int32 &outB0, int32 &outB1, int32 F_c, int32 F_s, float gainDC, float gainFT, float gainPI) { float a1, b0, b1; float gainFT2, gainDC2, gainPI2; float alpha, beta0, beta1, rho; float wT, quad; wT = PI * F_c / F_s; gainPI2 = gainPI * gainPI; gainFT2 = gainFT * gainFT; gainDC2 = gainDC * gainDC; quad = gainPI2 + gainDC2 - (gainFT2*2); alpha = 0; if (quad != 0) { float lambda = (gainPI2 - gainDC2) / quad; alpha = (float)(lambda - Sgn(lambda)*sqrt(lambda*lambda - 1.0f)); } beta0 = 0.5f * ((gainDC + gainPI) + (gainDC - gainPI) * alpha); beta1 = 0.5f * ((gainDC - gainPI) + (gainDC + gainPI) * alpha); rho = (float)((sin((wT*0.5f) - (PI/4.0f))) / (sin((wT*0.5f) + (PI/4.0f)))); quad = 1.0f / (1.0f + rho*alpha); b0 = ((beta0 + rho*beta1) * quad); b1 = ((beta1 + rho*beta0) * quad); a1 = - ((rho + alpha) * quad); outA1 = Util::Round(a1 * scale); outB0 = Util::Round(b0 * scale); outB1 = Util::Round(b1 * scale); } CSurroundSettings::CSurroundSettings() : m_nProLogicDepth(12), m_nProLogicDelay(20) { } CMegaBassSettings::CMegaBassSettings() : m_nXBassDepth(DEFAULT_XBASS_DEPTH), m_nXBassRange(DEFAULT_XBASS_RANGE) { } CSurround::CSurround() { // Surround Encoding: 1 delay line + low-pass filter + high-pass filter nSurroundSize = 0; nSurroundPos = 0; nDolbyDepth = 0; // Surround Biquads nDolbyHP_Y1 = 0; nDolbyHP_X1 = 0; nDolbyLP_Y1 = 0; nDolbyHP_B0 = 0; nDolbyHP_B1 = 0; nDolbyHP_A1 = 0; nDolbyLP_B0 = 0; nDolbyLP_B1 = 0; nDolbyLP_A1 = 0; MemsetZero(SurroundBuffer); } CMegaBass::CMegaBass() { // Bass Expansion: low-pass filter nXBassFlt_Y1 = 0; nXBassFlt_X1 = 0; nXBassFlt_B0 = 0; nXBassFlt_B1 = 0; nXBassFlt_A1 = 0; // DC Removal Biquad nDCRFlt_Y1lf = 0; nDCRFlt_X1lf = 0; nDCRFlt_Y1rf = 0; nDCRFlt_X1rf = 0; nDCRFlt_Y1lb = 0; nDCRFlt_X1lb = 0; nDCRFlt_Y1rb = 0; nDCRFlt_X1rb = 0; } void CSurround::Initialize(bool bReset, DWORD MixingFreq) { MPT_UNREFERENCED_PARAMETER(bReset); if (!m_Settings.m_nProLogicDelay) m_Settings.m_nProLogicDelay = 20; // Pro-Logic Surround nSurroundPos = nSurroundSize = 0; { memset(SurroundBuffer, 0, sizeof(SurroundBuffer)); nSurroundSize = (MixingFreq * m_Settings.m_nProLogicDelay) / 1000; if (nSurroundSize > SURROUNDBUFFERSIZE) nSurroundSize = SURROUNDBUFFERSIZE; nDolbyDepth = m_Settings.m_nProLogicDepth; if (nDolbyDepth < 1) nDolbyDepth = 1; if (nDolbyDepth > 16) nDolbyDepth = 16; // Setup biquad filters ShelfEQ(1024, nDolbyHP_A1, nDolbyHP_B0, nDolbyHP_B1, 200, MixingFreq, 0, 0.5f, 1); ShelfEQ(1024, nDolbyLP_A1, nDolbyLP_B0, nDolbyLP_B1, 7000, MixingFreq, 1, 0.75f, 0); nDolbyHP_X1 = nDolbyHP_Y1 = 0; nDolbyLP_Y1 = 0; // Surround Level nDolbyHP_B0 = (nDolbyHP_B0 * nDolbyDepth) >> 5; nDolbyHP_B1 = (nDolbyHP_B1 * nDolbyDepth) >> 5; // +6dB nDolbyLP_B0 *= 2; nDolbyLP_B1 *= 2; } } void CMegaBass::Initialize(bool bReset, DWORD MixingFreq) { // Bass Expansion Reset { int32 a1 = 0, b0 = 1024, b1 = 0; int nXBassCutOff = 50 + (m_Settings.m_nXBassRange+2) * 20; int nXBassGain = m_Settings.m_nXBassDepth; nXBassGain = mpt::clamp(nXBassGain, 2, 8); nXBassCutOff = mpt::clamp(nXBassCutOff, 60, 600); ShelfEQ(1024, a1, b0, b1, nXBassCutOff, MixingFreq, 1.0f + (1.0f/16.0f) * (0x300 >> nXBassGain), 1.0f, 0.0000001f); if (nXBassGain > 5) { b0 >>= (nXBassGain-5); b1 >>= (nXBassGain-5); } nXBassFlt_A1 = a1; nXBassFlt_B0 = b0; nXBassFlt_B1 = b1; //Log("b0=%d b1=%d a1=%d\n", b0, b1, a1); } if (bReset) { nXBassFlt_X1 = 0; nXBassFlt_Y1 = 0; nDCRFlt_X1lf = 0; nDCRFlt_X1rf = 0; nDCRFlt_Y1lf = 0; nDCRFlt_Y1rf = 0; nDCRFlt_X1lb = 0; nDCRFlt_X1rb = 0; nDCRFlt_Y1lb = 0; nDCRFlt_Y1rb = 0; } } // 2-channel surround void CSurround::ProcessStereoSurround(int * MixSoundBuffer, int count) { int *pr = MixSoundBuffer, hy1 = nDolbyHP_Y1; for (int r=count; r; r--) { // Delay int secho = SurroundBuffer[nSurroundPos]; SurroundBuffer[nSurroundPos] = (pr[0]+pr[1]+256) >> 9; // High-pass int v0 = (nDolbyHP_B0 * secho + nDolbyHP_B1 * nDolbyHP_X1 + nDolbyHP_A1 * hy1) >> 10; nDolbyHP_X1 = secho; // Low-pass int v = (nDolbyLP_B0 * v0 + nDolbyLP_B1 * hy1 + nDolbyLP_A1 * nDolbyLP_Y1) >> (10-8); hy1 = v0; nDolbyLP_Y1 = v >> 8; // Add echo pr[0] += v; pr[1] -= v; if (++nSurroundPos >= nSurroundSize) nSurroundPos = 0; pr += 2; } nDolbyHP_Y1 = hy1; } // 4-channels surround void CSurround::ProcessQuadSurround(int * MixSoundBuffer, int * MixRearBuffer, int count) { int *pr = MixSoundBuffer, hy1 = nDolbyHP_Y1; for (int r=count; r; r--) { int vl = pr[0] >> 1; int vr = pr[1] >> 1; pr[(uint32)(MixRearBuffer-MixSoundBuffer)] += vl; pr[((uint32)(MixRearBuffer-MixSoundBuffer))+1] += vr; // Delay int secho = SurroundBuffer[nSurroundPos]; SurroundBuffer[nSurroundPos] = (vr+vl+256) >> 9; // High-pass int v0 = (nDolbyHP_B0 * secho + nDolbyHP_B1 * nDolbyHP_X1 + nDolbyHP_A1 * hy1) >> 10; nDolbyHP_X1 = secho; // Low-pass int v = (nDolbyLP_B0 * v0 + nDolbyLP_B1 * hy1 + nDolbyLP_A1 * nDolbyLP_Y1) >> (10-8); hy1 = v0; nDolbyLP_Y1 = v >> 8; // Add echo pr[(uint32)(MixRearBuffer-MixSoundBuffer)] += v; pr[((uint32)(MixRearBuffer-MixSoundBuffer))+1] += v; if (++nSurroundPos >= nSurroundSize) nSurroundPos = 0; pr += 2; } nDolbyHP_Y1 = hy1; } void CSurround::Process(int * MixSoundBuffer, int * MixRearBuffer, int count, uint32 nChannels) { if(nChannels >= 2) // Dolby Pro-Logic Surround { if (nChannels > 2) ProcessQuadSurround(MixSoundBuffer, MixRearBuffer, count); else ProcessStereoSurround(MixSoundBuffer, count); } } void CMegaBass::Process(int * MixSoundBuffer, int * MixRearBuffer, int count, uint32 nChannels) { if(nChannels >= 2) { X86_StereoDCRemoval(MixSoundBuffer, count, nDCRFlt_Y1lf, nDCRFlt_X1lf, nDCRFlt_Y1rf, nDCRFlt_X1rf); if(nChannels > 2) X86_StereoDCRemoval(MixSoundBuffer, count, nDCRFlt_Y1lb, nDCRFlt_X1lb, nDCRFlt_Y1rb, nDCRFlt_X1rb); int *px = MixSoundBuffer; int *py = MixRearBuffer; int x1 = nXBassFlt_X1; int y1 = nXBassFlt_Y1; if(nChannels > 2) for (int x=count; x; x--) { int x_m = (px[0]+px[1]+py[0]+py[1]+0x100)>>9; y1 = (nXBassFlt_B0 * x_m + nXBassFlt_B1 * x1 + nXBassFlt_A1 * y1) >> (10-8); x1 = x_m; px[0] += y1; px[1] += y1; py[0] += y1; py[1] += y1; y1 = (y1+0x80) >> 8; px += 2; py += 2; } else for (int x=count; x; x--) { int x_m = (px[0]+px[1]+0x100)>>9; y1 = (nXBassFlt_B0 * x_m + nXBassFlt_B1 * x1 + nXBassFlt_A1 * y1) >> (10-8); x1 = x_m; px[0] += y1; px[1] += y1; y1 = (y1+0x80) >> 8; px += 2; } nXBassFlt_X1 = x1; nXBassFlt_Y1 = y1; } else { X86_MonoDCRemoval(MixSoundBuffer, count, nDCRFlt_Y1lf, nDCRFlt_X1lf); int *px = MixSoundBuffer; int x1 = nXBassFlt_X1; int y1 = nXBassFlt_Y1; for (int x=count; x; x--) { int x_m = (px[0]+0x80)>>8; y1 = (nXBassFlt_B0 * x_m + nXBassFlt_B1 * x1 + nXBassFlt_A1 * y1) >> (10-8); x1 = x_m; px[0] += y1; y1 = (y1+0x40) >> 8; px++; } nXBassFlt_X1 = x1; nXBassFlt_Y1 = y1; } } ////////////////////////////////////////////////////////////////////////// // // DC Removal // #define DCR_AMOUNT 9 static void X86_StereoDCRemoval(int *pBuffer, uint32 nSamples, int32 &nDCRFlt_Y1l, int32 &nDCRFlt_X1l, int32 &nDCRFlt_Y1r, int32 &nDCRFlt_X1r) { int y1l = nDCRFlt_Y1l, x1l = nDCRFlt_X1l; int y1r = nDCRFlt_Y1r, x1r = nDCRFlt_X1r; while(nSamples--) { int inL = pBuffer[0]; int inR = pBuffer[1]; int diffL = x1l - inL; int diffR = x1r - inR; x1l = inL; x1r = inR; int outL = diffL / (1 << (DCR_AMOUNT + 1)) - diffL + y1l; int outR = diffR / (1 << (DCR_AMOUNT + 1)) - diffR + y1r; pBuffer[0] = outL; pBuffer[1] = outR; pBuffer += 2; y1l = outL - outL / (1 << DCR_AMOUNT); y1r = outR - outR / (1 << DCR_AMOUNT); } nDCRFlt_Y1l = y1l; nDCRFlt_X1l = x1l; nDCRFlt_Y1r = y1r; nDCRFlt_X1r = x1r; } static void X86_MonoDCRemoval(int *pBuffer, uint32 nSamples, int32 &nDCRFlt_Y1l, int32 &nDCRFlt_X1l) { int y1l = nDCRFlt_Y1l, x1l = nDCRFlt_X1l; while(nSamples--) { int inM = pBuffer[0]; int diff = x1l - inM; x1l = inM; pBuffer[0] = inM = diff / (1 << (DCR_AMOUNT + 1)) - diff + y1l; pBuffer++; y1l = inM - inM / (1 << DCR_AMOUNT); } nDCRFlt_Y1l = y1l; nDCRFlt_X1l = x1l; } ///////////////////////////////////////////////////////////////// // Clean DSP Effects interface // [XBass level 0(quiet)-100(loud)], [cutoff in Hz 20-100] void CMegaBass::SetXBassParameters(uint32 nDepth, uint32 nRange) { if (nDepth > 100) nDepth = 100; uint32 gain = nDepth / 20; if (gain > 4) gain = 4; m_Settings.m_nXBassDepth = 8 - gain; // filter attenuation 1/256 .. 1/16 uint32 range = nRange / 5; if (range > 5) range -= 5; else range = 0; if (nRange > 16) nRange = 16; m_Settings.m_nXBassRange = 21 - range; // filter average on 0.5-1.6ms } // [Surround level 0(quiet)-100(heavy)] [delay in ms, usually 5-50ms] void CSurround::SetSurroundParameters(uint32 nDepth, uint32 nDelay) { uint32 gain = (nDepth * 16) / 100; if (gain > 16) gain = 16; if (gain < 1) gain = 1; m_Settings.m_nProLogicDepth = gain; if (nDelay < 4) nDelay = 4; if (nDelay > 50) nDelay = 50; m_Settings.m_nProLogicDelay = nDelay; } #else MPT_MSVC_WORKAROUND_LNK4221(DSP) #endif // NO_DSP OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/sounddsp/AGC.h0000644000372100037210000000124213161656666016677 00000000000000/* * AGC.h * ----- * Purpose: Automatic Gain Control * Notes : Ugh... This should really be removed at some point. * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once OPENMPT_NAMESPACE_BEGIN #ifndef NO_AGC class CAGC { private: UINT m_nAGC; std::size_t m_nAGCRecoverCount; UINT m_Timeout; public: CAGC(); void Initialize(bool bReset, DWORD MixingFreq); public: void Process(int *MixSoundBuffer, int *RearSoundBuffer, std::size_t count, std::size_t nChannels); void Adjust(UINT oldVol, UINT newVol); }; #endif // NO_AGC OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/sounddsp/Reverb.h0000644000372100037210000002311613161656666017536 00000000000000/* * Reverb.h * -------- * Purpose: Mixing code for reverb. * Notes : Ugh... This should really be removed at some point. * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once #ifndef NO_REVERB #include "../soundlib/Mixer.h" // For MIXBUFFERSIZE OPENMPT_NAMESPACE_BEGIN //////////////////////////////////////////////////////////////////////// // Reverberation #define NUM_REVERBTYPES 29 const char *GetReverbPresetName(uint32 nPreset); ///////////////////////////////////////////////////////////////////////////// // // SW Reverb structures // // Length-1 (in samples) of the reflections delay buffer: 32K, 371ms@22kHz #define SNDMIX_REFLECTIONS_DELAY_MASK 0x1fff #define SNDMIX_PREDIFFUSION_DELAY_MASK 0x7f // 128 samples #define SNDMIX_REVERB_DELAY_MASK 0xfff // 4K samples (92ms @ 44kHz) union LR16 { struct { int16 l, r; } c; int32 lr; }; struct SWRvbReflection { uint32 Delay, DelayDest; LR16 Gains[2]; // g_ll, g_rl, g_lr, g_rr }; struct SWRvbRefDelay { uint32 nDelayPos, nPreDifPos, nRefOutPos; int32 lMasterGain; // reflections linear master gain LR16 nCoeffs; // room low-pass coefficients LR16 History; // room low-pass history LR16 nPreDifCoeffs; // prediffusion coefficients LR16 ReflectionsGain; // master reflections gain SWRvbReflection Reflections[8]; // Up to 8 SW Reflections LR16 RefDelayBuffer[SNDMIX_REFLECTIONS_DELAY_MASK + 1]; // reflections delay buffer LR16 PreDifBuffer[SNDMIX_PREDIFFUSION_DELAY_MASK + 1]; // pre-diffusion LR16 RefOut[SNDMIX_REVERB_DELAY_MASK + 1]; // stereo output of reflections }; // Late reverberation // Tank diffusers lengths #define RVBDIF1L_LEN (149*2) // 6.8ms #define RVBDIF1R_LEN (223*2) // 10.1ms #define RVBDIF2L_LEN (421*2) // 19.1ms #define RVBDIF2R_LEN (647*2) // 29.3ms // Tank delay lines lengths #define RVBDLY1L_LEN (683*2) // 30.9ms #define RVBDLY1R_LEN (811*2) // 36.7ms #define RVBDLY2L_LEN (773*2) // 35.1ms #define RVBDLY2R_LEN (1013*2) // 45.9ms // Tank delay lines mask #define RVBDLY_MASK 2047 // Min/Max reflections delay #define RVBMINREFDELAY 96 // 96 samples #define RVBMAXREFDELAY 7500 // 7500 samples // Min/Max reverb delay #define RVBMINRVBDELAY 128 // 256 samples (11.6ms @ 22kHz) #define RVBMAXRVBDELAY 3800 // 1900 samples (86ms @ 24kHz) struct SWLateReverb { uint32 nReverbDelay; // Reverb delay (in samples) uint32 nDelayPos; // Delay line position LR16 nDifCoeffs[2]; // Reverb diffusion LR16 nDecayDC[2]; // Reverb DC decay LR16 nDecayLP[2]; // Reverb HF decay LR16 LPHistory[2]; // Low-pass history LR16 Dif2InGains[2]; // 2nd diffuser input gains LR16 RvbOutGains[2]; // 4x2 Reverb output gains int32 lMasterGain; // late reverb master gain int32 lDummyAlign; // Tank Delay lines LR16 Diffusion1[RVBDLY_MASK + 1]; // {dif1_l, dif1_r} LR16 Diffusion2[RVBDLY_MASK + 1]; // {dif2_l, dif2_r} LR16 Delay1[RVBDLY_MASK + 1]; // {dly1_l, dly1_r} LR16 Delay2[RVBDLY_MASK + 1]; // {dly2_l, dly2_r} }; #define ENVIRONMENT_NUMREFLECTIONS 8 struct EnvironmentReflection { int16 GainLL, GainRR, GainLR, GainRL; // +/- 32K scale uint32 Delay; // In samples }; struct EnvironmentReverb { int32 ReverbLevel; // Late reverb gain (mB) int32 ReflectionsLevel; // Master reflections gain (mB) int32 RoomHF; // Room gain HF (mB) uint32 ReverbDecay; // Reverb tank decay (0-7fff scale) int32 PreDiffusion; // Reverb pre-diffusion amount (+/- 32K scale) int32 TankDiffusion; // Reverb tank diffusion (+/- 32K scale) uint32 ReverbDelay; // Reverb delay (in samples) float flReverbDamping; // HF tank gain [0.0, 1.0] int32 ReverbDecaySamples; // Reverb decay time (in samples) EnvironmentReflection Reflections[ENVIRONMENT_NUMREFLECTIONS]; }; class CReverbSettings { public: uint32 m_nReverbDepth; uint32 m_nReverbType; public: CReverbSettings(); }; class CReverb { public: CReverbSettings m_Settings; // Shared reverb state private: mixsample_t MixReverbBuffer[MIXBUFFERSIZE * 2]; public: mixsample_t gnRvbROfsVol, gnRvbLOfsVol; private: uint32 gnReverbSend; uint32 gnReverbSamples; uint32 gnReverbDecaySamples; // Internal reverb state bool g_bLastInPresent; bool g_bLastOutPresent; int g_nLastRvbIn_xl; int g_nLastRvbIn_xr; int g_nLastRvbIn_yl; int g_nLastRvbIn_yr; int g_nLastRvbOut_xl; int g_nLastRvbOut_xr; int32 gnDCRRvb_Y1[2]; int32 gnDCRRvb_X1[2]; // Reverb mix buffers SWRvbRefDelay g_RefDelay; SWLateReverb g_LateReverb; public: CReverb(); public: void Initialize(bool bReset, uint32 MixingFreq); // can be called multiple times or never (if no data is sent to reverb) mixsample_t *GetReverbSendBuffer(uint32 nSamples); // call once after all data has been sent. void Process(mixsample_t *MixSoundBuffer, uint32 nSamples); private: void Shutdown(); // Pre/Post resampling and filtering uint32 ReverbProcessPreFiltering1x(int32 *pWet, uint32 nSamples); uint32 ReverbProcessPreFiltering2x(int32 *pWet, uint32 nSamples); void ReverbProcessPostFiltering1x(const int32 *pRvb, int32 *pDry, uint32 nSamples); void ReverbProcessPostFiltering2x(const int32 *pRvb, int32 *pDry, uint32 nSamples); void ReverbDCRemoval(int32 *pBuffer, uint32 nSamples); void ReverbDryMix(int32 *pDry, int32 *pWet, int lDryVol, uint32 nSamples); // Process pre-diffusion and pre-delay static void ProcessPreDelay(SWRvbRefDelay *pPreDelay, const int32 *pIn, uint32 nSamples); // Process reflections static void ProcessReflections(SWRvbRefDelay *pPreDelay, LR16 *pRefOut, int32 *pMixOut, uint32 nSamples); // Process Late Reverb (SW Reflections): stereo reflections output, 32-bit reverb output, SW reverb gain static void ProcessLateReverb(SWLateReverb *pReverb, LR16 *pRefOut, int32 *pMixOut, uint32 nSamples); }; ///////////////////////////////////////////////////////////////////////////////// // // I3DL2 reverb presets // #define SNDMIX_REVERB_PRESET_DEFAULT \ -10000, 0, 1.00f,0.50f,-10000,0.020f,-10000,0.040f,100.0f,100.0f #define SNDMIX_REVERB_PRESET_GENERIC \ -1000, -100, 1.49f,0.83f, -2602,0.007f, 200,0.011f,100.0f,100.0f #define SNDMIX_REVERB_PRESET_PADDEDCELL \ -1000,-6000, 0.17f,0.10f, -1204,0.001f, 207,0.002f,100.0f,100.0f #define SNDMIX_REVERB_PRESET_ROOM \ -1000, -454, 0.40f,0.83f, -1646,0.002f, 53,0.003f,100.0f,100.0f #define SNDMIX_REVERB_PRESET_BATHROOM \ -1000,-1200, 1.49f,0.54f, -370,0.007f, 1030,0.011f,100.0f, 60.0f #define SNDMIX_REVERB_PRESET_LIVINGROOM \ -1000,-6000, 0.50f,0.10f, -1376,0.003f, -1104,0.004f,100.0f,100.0f #define SNDMIX_REVERB_PRESET_STONEROOM \ -1000, -300, 2.31f,0.64f, -711,0.012f, 83,0.017f,100.0f,100.0f #define SNDMIX_REVERB_PRESET_AUDITORIUM \ -1000, -476, 4.32f,0.59f, -789,0.020f, -289,0.030f,100.0f,100.0f #define SNDMIX_REVERB_PRESET_CONCERTHALL \ -1000, -500, 3.92f,0.70f, -1230,0.020f, -2,0.029f,100.0f,100.0f #define SNDMIX_REVERB_PRESET_CAVE \ -1000, 0, 2.91f,1.30f, -602,0.015f, -302,0.022f,100.0f,100.0f #define SNDMIX_REVERB_PRESET_ARENA \ -1000, -698, 7.24f,0.33f, -1166,0.020f, 16,0.030f,100.0f,100.0f #define SNDMIX_REVERB_PRESET_HANGAR \ -1000,-1000,10.05f,0.23f, -602,0.020f, 198,0.030f,100.0f,100.0f #define SNDMIX_REVERB_PRESET_CARPETEDHALLWAY \ -1000,-4000, 0.30f,0.10f, -1831,0.002f, -1630,0.030f,100.0f,100.0f #define SNDMIX_REVERB_PRESET_HALLWAY \ -1000, -300, 1.49f,0.59f, -1219,0.007f, 441,0.011f,100.0f,100.0f #define SNDMIX_REVERB_PRESET_STONECORRIDOR \ -1000, -237, 2.70f,0.79f, -1214,0.013f, 395,0.020f,100.0f,100.0f #define SNDMIX_REVERB_PRESET_ALLEY \ -1000, -270, 1.49f,0.86f, -1204,0.007f, -4,0.011f,100.0f,100.0f #define SNDMIX_REVERB_PRESET_FOREST \ -1000,-3300, 1.49f,0.54f, -2560,0.162f, -613,0.088f, 79.0f,100.0f #define SNDMIX_REVERB_PRESET_CITY \ -1000, -800, 1.49f,0.67f, -2273,0.007f, -2217,0.011f, 50.0f,100.0f #define SNDMIX_REVERB_PRESET_MOUNTAINS \ -1000,-2500, 1.49f,0.21f, -2780,0.300f, -2014,0.100f, 27.0f,100.0f #define SNDMIX_REVERB_PRESET_QUARRY \ -1000,-1000, 1.49f,0.83f,-10000,0.061f, 500,0.025f,100.0f,100.0f #define SNDMIX_REVERB_PRESET_PLAIN \ -1000,-2000, 1.49f,0.50f, -2466,0.179f, -2514,0.100f, 21.0f,100.0f #define SNDMIX_REVERB_PRESET_PARKINGLOT \ -1000, 0, 1.65f,1.50f, -1363,0.008f, -1153,0.012f,100.0f,100.0f #define SNDMIX_REVERB_PRESET_SEWERPIPE \ -1000,-1000, 2.81f,0.14f, 429,0.014f, 648,0.021f, 80.0f, 60.0f #define SNDMIX_REVERB_PRESET_UNDERWATER \ -1000,-4000, 1.49f,0.10f, -449,0.007f, 1700,0.011f,100.0f,100.0f // Examples simulating General MIDI 2'musical' reverb presets // // Name (Decay time) Description // // Small Room (1.1s) A small size room with a length of 5m or so. // Medium Room (1.3s) A medium size room with a length of 10m or so. // Large Room (1.5s) A large size room suitable for live performances. // Medium Hall (1.8s) A medium size concert hall. // Large Hall (1.8s) A large size concert hall suitable for a full orchestra. // Plate (1.3s) A plate reverb simulation. #define SNDMIX_REVERB_PRESET_SMALLROOM \ -1000, -600, 1.10f,0.83f, -400,0.005f, 500,0.010f,100.0f,100.0f #define SNDMIX_REVERB_PRESET_MEDIUMROOM \ -1000, -600, 1.30f,0.83f, -1000,0.010f, -200,0.020f,100.0f,100.0f #define SNDMIX_REVERB_PRESET_LARGEROOM \ -1000, -600, 1.50f,0.83f, -1600,0.020f, -1000,0.040f,100.0f,100.0f #define SNDMIX_REVERB_PRESET_MEDIUMHALL \ -1000, -600, 1.80f,0.70f, -1300,0.015f, -800,0.030f,100.0f,100.0f #define SNDMIX_REVERB_PRESET_LARGEHALL \ -1000, -600, 1.80f,0.70f, -2000,0.030f, -1400,0.060f,100.0f,100.0f #define SNDMIX_REVERB_PRESET_PLATE \ -1000, -200, 1.30f,0.90f, 0,0.002f, 0,0.010f,100.0f, 75.0f OPENMPT_NAMESPACE_END #endif // NO_REVERB libopenmpt-0.3.6+release.autotools/sounddsp/AGC.cpp0000644000372100037210000000635513161656666017244 00000000000000/* * AGC.cpp * ------- * Purpose: Automatic Gain Control * Notes : Ugh... This should really be removed at some point. * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "../soundlib/Sndfile.h" #include "../sounddsp/AGC.h" OPENMPT_NAMESPACE_BEGIN ////////////////////////////////////////////////////////////////////////////////// // Automatic Gain Control #ifndef NO_AGC #define AGC_PRECISION 10 #define AGC_UNITY (1 << AGC_PRECISION) // Limiter #define MIXING_LIMITMAX (0x08100000) #define MIXING_LIMITMIN (-MIXING_LIMITMAX) static UINT ProcessAGC(int *pBuffer, int *pRearBuffer, std::size_t nSamples, std::size_t nChannels, int nAGC) { if(nChannels == 1) { while(nSamples--) { int val = (int)(((int64)*pBuffer * (int32)nAGC) >> AGC_PRECISION); if(val < MIXING_LIMITMIN || val > MIXING_LIMITMAX) nAGC--; *pBuffer = val; pBuffer++; } } else { if(nChannels == 2) { while(nSamples--) { int fl = (int)(((int64)pBuffer[0] * (int32)nAGC) >> AGC_PRECISION); int fr = (int)(((int64)pBuffer[1] * (int32)nAGC) >> AGC_PRECISION); bool dec = false; dec = dec || (fl < MIXING_LIMITMIN || fl > MIXING_LIMITMAX); dec = dec || (fr < MIXING_LIMITMIN || fr > MIXING_LIMITMAX); if(dec) nAGC--; pBuffer[0] = fl; pBuffer[1] = fr; pBuffer += 2; } } else if(nChannels == 4) { while(nSamples--) { int fl = (int)(((int64)pBuffer[0] * (int32)nAGC) >> AGC_PRECISION); int fr = (int)(((int64)pBuffer[1] * (int32)nAGC) >> AGC_PRECISION); int rl = (int)(((int64)pRearBuffer[0] * (int32)nAGC) >> AGC_PRECISION); int rr = (int)(((int64)pRearBuffer[1] * (int32)nAGC) >> AGC_PRECISION); bool dec = false; dec = dec || (fl < MIXING_LIMITMIN || fl > MIXING_LIMITMAX); dec = dec || (fr < MIXING_LIMITMIN || fr > MIXING_LIMITMAX); dec = dec || (rl < MIXING_LIMITMIN || rl > MIXING_LIMITMAX); dec = dec || (rr < MIXING_LIMITMIN || rr > MIXING_LIMITMAX); if(dec) nAGC--; pBuffer[0] = fl; pBuffer[1] = fr; pRearBuffer[0] = rl; pRearBuffer[1] = rr; pBuffer += 2; pRearBuffer += 2; } } } return nAGC; } CAGC::CAGC() { Initialize(true, 44100); } void CAGC::Process(int *MixSoundBuffer, int *RearSoundBuffer, std::size_t count, std::size_t nChannels) { UINT agc = ProcessAGC(MixSoundBuffer, RearSoundBuffer, count, nChannels, m_nAGC); // Some kind custom law, so that the AGC stays quite stable, but slowly // goes back up if the sound level stays below a level inversely proportional // to the AGC level. (J'me comprends) if((agc >= m_nAGC) && (m_nAGC < AGC_UNITY)) { m_nAGCRecoverCount += count; if(m_nAGCRecoverCount >= m_Timeout) { m_nAGCRecoverCount = 0; m_nAGC++; } } else { m_nAGC = agc; m_nAGCRecoverCount = 0; } } void CAGC::Adjust(UINT oldVol, UINT newVol) { m_nAGC = m_nAGC * oldVol / newVol; if (m_nAGC > AGC_UNITY) m_nAGC = AGC_UNITY; } void CAGC::Initialize(bool bReset, DWORD MixingFreq) { if(bReset) { m_nAGC = AGC_UNITY; m_nAGCRecoverCount = 0; } m_Timeout = (MixingFreq >> (AGC_PRECISION-8)) >> 1; } #else MPT_MSVC_WORKAROUND_LNK4221(AGC) #endif // NO_AGC OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/sounddsp/DSP.h0000644000372100037210000000476613161656666016751 00000000000000/* * DSP.h * ----- * Purpose: Mixing code for various DSPs (EQ, Mega-Bass, ...) * Notes : Ugh... This should really be removed at some point. * Authors: Olivier Lapicque * OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once OPENMPT_NAMESPACE_BEGIN #ifndef NO_DSP // Buffer Sizes #define SURROUNDBUFFERSIZE 2048 // 50ms @ 48kHz class CSurroundSettings { public: uint32 m_nProLogicDepth; uint32 m_nProLogicDelay; public: CSurroundSettings(); }; class CMegaBassSettings { public: uint32 m_nXBassDepth; uint32 m_nXBassRange; public: CMegaBassSettings(); }; class CSurround { public: CSurroundSettings m_Settings; // Surround Encoding: 1 delay line + low-pass filter + high-pass filter int32 nSurroundSize; int32 nSurroundPos; int32 nDolbyDepth; // Surround Biquads int32 nDolbyHP_Y1; int32 nDolbyHP_X1; int32 nDolbyLP_Y1; int32 nDolbyHP_B0; int32 nDolbyHP_B1; int32 nDolbyHP_A1; int32 nDolbyLP_B0; int32 nDolbyLP_B1; int32 nDolbyLP_A1; int32 SurroundBuffer[SURROUNDBUFFERSIZE]; public: CSurround(); public: void SetSettings(const CSurroundSettings &settings) { m_Settings = settings; } // [XBass level 0(quiet)-100(loud)], [cutoff in Hz 10-100] bool SetXBassParameters(uint32 nDepth, uint32 nRange); // [Surround level 0(quiet)-100(heavy)] [delay in ms, usually 5-40ms] void SetSurroundParameters(uint32 nDepth, uint32 nDelay); void Initialize(bool bReset, DWORD MixingFreq); void Process(int * MixSoundBuffer, int * MixRearBuffer, int count, uint32 nChannels); private: void ProcessStereoSurround(int * MixSoundBuffer, int count); void ProcessQuadSurround(int * MixSoundBuffer, int * MixRearBuffer, int count); }; class CMegaBass { public: CMegaBassSettings m_Settings; // Bass Expansion: low-pass filter int32 nXBassFlt_Y1; int32 nXBassFlt_X1; int32 nXBassFlt_B0; int32 nXBassFlt_B1; int32 nXBassFlt_A1; // DC Removal Biquad int32 nDCRFlt_Y1lf; int32 nDCRFlt_X1lf; int32 nDCRFlt_Y1rf; int32 nDCRFlt_X1rf; int32 nDCRFlt_Y1lb; int32 nDCRFlt_X1lb; int32 nDCRFlt_Y1rb; int32 nDCRFlt_X1rb; public: CMegaBass(); public: void SetSettings(const CMegaBassSettings &settings) { m_Settings = settings; } // [XBass level 0(quiet)-100(loud)], [cutoff in Hz 10-100] void SetXBassParameters(uint32 nDepth, uint32 nRange); void Initialize(bool bReset, DWORD MixingFreq); void Process(int * MixSoundBuffer, int * MixRearBuffer, int count, uint32 nChannels); }; #endif // NO_DSP OPENMPT_NAMESPACE_END libopenmpt-0.3.6+release.autotools/m4/0000755000372100037210000000000013235362226014662 500000000000000libopenmpt-0.3.6+release.autotools/m4/ax_require_defined.m40000644000372100037210000000230113235362213020656 00000000000000# =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_require_defined.html # =========================================================================== # # SYNOPSIS # # AX_REQUIRE_DEFINED(MACRO) # # DESCRIPTION # # AX_REQUIRE_DEFINED is a simple helper for making sure other macros have # been defined and thus are available for use. This avoids random issues # where a macro isn't expanded. Instead the configure script emits a # non-fatal: # # ./configure: line 1673: AX_CFLAGS_WARN_ALL: command not found # # It's like AC_REQUIRE except it doesn't expand the required macro. # # Here's an example: # # AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG]) # # LICENSE # # Copyright (c) 2014 Mike Frysinger # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 1 AC_DEFUN([AX_REQUIRE_DEFINED], [dnl m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])]) ])dnl AX_REQUIRE_DEFINED libopenmpt-0.3.6+release.autotools/m4/emptydir0000644000372100037210000000000013235362176016354 00000000000000libopenmpt-0.3.6+release.autotools/m4/lt~obsolete.m40000644000372100037210000001377413235362213017426 00000000000000# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software # Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 5 lt~obsolete.m4 # These exist entirely to fool aclocal when bootstrapping libtool. # # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us # using a macro with the same name in our local m4/libtool.m4 it'll # pull the old libtool.m4 in (it doesn't see our shiny new m4_define # and doesn't know about Autoconf macros at all.) # # So we provide this file, which has a silly filename so it's always # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until # we give up compatibility with versions before 1.7, at which point # we need to keep only those names which we still refer to. # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) libopenmpt-0.3.6+release.autotools/m4/ltversion.m40000644000372100037210000000127313235362213017070 00000000000000# ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # @configure_input@ # serial 4179 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.4.6]) m4_define([LT_PACKAGE_REVISION], [2.4.6]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.4.6' macro_revision='2.4.6' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) libopenmpt-0.3.6+release.autotools/m4/ax_cxx_compile_stdcxx.m40000644000372100037210000003300013041743640021435 00000000000000# =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html # =========================================================================== # # SYNOPSIS # # AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional]) # # DESCRIPTION # # Check for baseline language coverage in the compiler for the specified # version of the C++ standard. If necessary, add switches to CXX and # CXXCPP to enable support. VERSION may be '11' (for the C++11 standard) # or '14' (for the C++14 standard). # # The second argument, if specified, indicates whether you insist on an # extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. # -std=c++11). If neither is specified, you get whatever works, with # preference for an extended mode. # # The third argument, if specified 'mandatory' or if left unspecified, # indicates that baseline support for the specified C++ standard is # required and that the macro should error out if no mode with that # support is found. If specified 'optional', then configuration proceeds # regardless, after defining HAVE_CXX${VERSION} if and only if a # supporting mode is found. # # LICENSE # # Copyright (c) 2008 Benjamin Kosnik # Copyright (c) 2012 Zack Weinberg # Copyright (c) 2013 Roy Stogner # Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov # Copyright (c) 2015 Paul Norman # Copyright (c) 2015 Moritz Klammler # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 4 dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro dnl (serial version number 13). AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl m4_if([$1], [11], [], [$1], [14], [], [$1], [17], [m4_fatal([support for C++17 not yet implemented in AX_CXX_COMPILE_STDCXX])], [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl m4_if([$2], [], [], [$2], [ext], [], [$2], [noext], [], [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true], [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], [$3], [optional], [ax_cxx_compile_cxx$1_required=false], [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) AC_LANG_PUSH([C++])dnl ac_success=no AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, ax_cv_cxx_compile_cxx$1, [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], [ax_cv_cxx_compile_cxx$1=yes], [ax_cv_cxx_compile_cxx$1=no])]) if test x$ax_cv_cxx_compile_cxx$1 = xyes; then ac_success=yes fi m4_if([$2], [noext], [], [dnl if test x$ac_success = xno; then for switch in -std=gnu++$1 -std=gnu++0x; do cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, $cachevar, [ac_save_CXX="$CXX" CXX="$CXX $switch" AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], [eval $cachevar=yes], [eval $cachevar=no]) CXX="$ac_save_CXX"]) if eval test x\$$cachevar = xyes; then CXX="$CXX $switch" if test -n "$CXXCPP" ; then CXXCPP="$CXXCPP $switch" fi ac_success=yes break fi done fi]) m4_if([$2], [ext], [], [dnl if test x$ac_success = xno; then dnl HP's aCC needs +std=c++11 according to: dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf dnl Cray's crayCC needs "-h std=c++11" for switch in -std=c++$1 -std=c++0x +std=c++$1 "-h std=c++$1"; do cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, $cachevar, [ac_save_CXX="$CXX" CXX="$CXX $switch" AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], [eval $cachevar=yes], [eval $cachevar=no]) CXX="$ac_save_CXX"]) if eval test x\$$cachevar = xyes; then CXX="$CXX $switch" if test -n "$CXXCPP" ; then CXXCPP="$CXXCPP $switch" fi ac_success=yes break fi done fi]) AC_LANG_POP([C++]) if test x$ax_cxx_compile_cxx$1_required = xtrue; then if test x$ac_success = xno; then AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.]) fi fi if test x$ac_success = xno; then HAVE_CXX$1=0 AC_MSG_NOTICE([No compiler with C++$1 support was found]) else HAVE_CXX$1=1 AC_DEFINE(HAVE_CXX$1,1, [define if the compiler supports basic C++$1 syntax]) fi AC_SUBST(HAVE_CXX$1) ]) dnl Test body for checking C++11 support m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 ) dnl Test body for checking C++14 support m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 ) dnl Tests for new features in C++11 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ // If the compiler admits that it is not ready for C++11, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" #elif __cplusplus < 201103L #error "This is not a C++11 compiler" #else namespace cxx11 { namespace test_static_assert { template struct check { static_assert(sizeof(int) <= sizeof(T), "not big enough"); }; } namespace test_final_override { struct Base { virtual void f() {} }; struct Derived : public Base { virtual void f() override {} }; } namespace test_double_right_angle_brackets { template < typename T > struct check {}; typedef check single_type; typedef check> double_type; typedef check>> triple_type; typedef check>>> quadruple_type; } namespace test_decltype { int f() { int a = 1; decltype(a) b = 2; return a + b; } } namespace test_type_deduction { template < typename T1, typename T2 > struct is_same { static const bool value = false; }; template < typename T > struct is_same { static const bool value = true; }; template < typename T1, typename T2 > auto add(T1 a1, T2 a2) -> decltype(a1 + a2) { return a1 + a2; } int test(const int c, volatile int v) { static_assert(is_same::value == true, ""); static_assert(is_same::value == false, ""); static_assert(is_same::value == false, ""); auto ac = c; auto av = v; auto sumi = ac + av + 'x'; auto sumf = ac + av + 1.0; static_assert(is_same::value == true, ""); static_assert(is_same::value == true, ""); static_assert(is_same::value == true, ""); static_assert(is_same::value == false, ""); static_assert(is_same::value == true, ""); return (sumf > 0.0) ? sumi : add(c, v); } } namespace test_noexcept { int f() { return 0; } int g() noexcept { return 0; } static_assert(noexcept(f()) == false, ""); static_assert(noexcept(g()) == true, ""); } namespace test_constexpr { template < typename CharT > unsigned long constexpr strlen_c_r(const CharT *const s, const unsigned long acc) noexcept { return *s ? strlen_c_r(s + 1, acc + 1) : acc; } template < typename CharT > unsigned long constexpr strlen_c(const CharT *const s) noexcept { return strlen_c_r(s, 0UL); } static_assert(strlen_c("") == 0UL, ""); static_assert(strlen_c("1") == 1UL, ""); static_assert(strlen_c("example") == 7UL, ""); static_assert(strlen_c("another\0example") == 7UL, ""); } namespace test_rvalue_references { template < int N > struct answer { static constexpr int value = N; }; answer<1> f(int&) { return answer<1>(); } answer<2> f(const int&) { return answer<2>(); } answer<3> f(int&&) { return answer<3>(); } void test() { int i = 0; const int c = 0; static_assert(decltype(f(i))::value == 1, ""); static_assert(decltype(f(c))::value == 2, ""); static_assert(decltype(f(0))::value == 3, ""); } } namespace test_uniform_initialization { struct test { static const int zero {}; static const int one {1}; }; static_assert(test::zero == 0, ""); static_assert(test::one == 1, ""); } namespace test_lambdas { void test1() { auto lambda1 = [](){}; auto lambda2 = lambda1; lambda1(); lambda2(); } int test2() { auto a = [](int i, int j){ return i + j; }(1, 2); auto b = []() -> int { return '0'; }(); auto c = [=](){ return a + b; }(); auto d = [&](){ return c; }(); auto e = [a, &b](int x) mutable { const auto identity = [](int y){ return y; }; for (auto i = 0; i < a; ++i) a += b--; return x + identity(a + b); }(0); return a + b + c + d + e; } int test3() { const auto nullary = [](){ return 0; }; const auto unary = [](int x){ return x; }; using nullary_t = decltype(nullary); using unary_t = decltype(unary); const auto higher1st = [](nullary_t f){ return f(); }; const auto higher2nd = [unary](nullary_t f1){ return [unary, f1](unary_t f2){ return f2(unary(f1())); }; }; return higher1st(nullary) + higher2nd(nullary)(unary); } } namespace test_variadic_templates { template struct sum; template struct sum { static constexpr auto value = N0 + sum::value; }; template <> struct sum<> { static constexpr auto value = 0; }; static_assert(sum<>::value == 0, ""); static_assert(sum<1>::value == 1, ""); static_assert(sum<23>::value == 23, ""); static_assert(sum<1, 2>::value == 3, ""); static_assert(sum<5, 5, 11>::value == 21, ""); static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); } // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function // because of this. namespace test_template_alias_sfinae { struct foo {}; template using member = typename T::member_type; template void func(...) {} template void func(member*) {} void test(); void test() { func(0); } } } // namespace cxx11 #endif // __cplusplus >= 201103L ]]) dnl Tests for new features in C++14 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[ // If the compiler admits that it is not ready for C++14, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" #elif __cplusplus < 201402L #error "This is not a C++14 compiler" #else namespace cxx14 { namespace test_polymorphic_lambdas { int test() { const auto lambda = [](auto&&... args){ const auto istiny = [](auto x){ return (sizeof(x) == 1UL) ? 1 : 0; }; const int aretiny[] = { istiny(args)... }; return aretiny[0]; }; return lambda(1, 1L, 1.0f, '1'); } } namespace test_binary_literals { constexpr auto ivii = 0b0000000000101010; static_assert(ivii == 42, "wrong value"); } namespace test_generalized_constexpr { template < typename CharT > constexpr unsigned long strlen_c(const CharT *const s) noexcept { auto length = 0UL; for (auto p = s; *p; ++p) ++length; return length; } static_assert(strlen_c("") == 0UL, ""); static_assert(strlen_c("x") == 1UL, ""); static_assert(strlen_c("test") == 4UL, ""); static_assert(strlen_c("another\0test") == 7UL, ""); } namespace test_lambda_init_capture { int test() { auto x = 0; const auto lambda1 = [a = x](int b){ return a + b; }; const auto lambda2 = [a = lambda1(x)](){ return a; }; return lambda2(); } } namespace test_digit_seperators { constexpr auto ten_million = 100'000'000; static_assert(ten_million == 100000000, ""); } namespace test_return_type_deduction { auto f(int& x) { return x; } decltype(auto) g(int& x) { return x; } template < typename T1, typename T2 > struct is_same { static constexpr auto value = false; }; template < typename T > struct is_same { static constexpr auto value = true; }; int test() { auto x = 0; static_assert(is_same::value, ""); static_assert(is_same::value, ""); return x; } } } // namespace cxx14 #endif // __cplusplus >= 201402L ]]) libopenmpt-0.3.6+release.autotools/m4/ltsugar.m40000644000372100037210000001044013235362213016520 00000000000000# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software # Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) # lt_join(SEP, ARG1, [ARG2...]) # ----------------------------- # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their # associated separator. # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier # versions in m4sugar had bugs. m4_define([lt_join], [m4_if([$#], [1], [], [$#], [2], [[$2]], [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) m4_define([_lt_join], [m4_if([$#$2], [2], [], [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) # lt_car(LIST) # lt_cdr(LIST) # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support # Autoconf-2.59, which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ # Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different # than defined and empty). # # This macro is needed until we can rely on Autoconf 2.62, since earlier # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. m4_define([lt_append], [m4_define([$1], m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) # ---------------------------------------------------------- # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. # Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], [m4_if(m4_eval([$# > 3]), [1], [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl [[m4_foreach([_Lt_prefix], [$2], [m4_foreach([_Lt_suffix], ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) # ----------------------------------------------------------------------- # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. m4_define([lt_if_append_uniq], [m4_ifdef([$1], [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], [lt_append([$1], [$2], [$3])$4], [$5])], [lt_append([$1], [$2], [$3])$4])]) # lt_dict_add(DICT, KEY, VALUE) # ----------------------------- m4_define([lt_dict_add], [m4_define([$1($2)], [$3])]) # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) # -------------------------------------------- m4_define([lt_dict_add_subkey], [m4_define([$1($2:$3)], [$4])]) # lt_dict_fetch(DICT, KEY, [SUBKEY]) # ---------------------------------- m4_define([lt_dict_fetch], [m4_ifval([$3], m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) # ----------------------------------------------------------------- m4_define([lt_if_dict_fetch], [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], [$5], [$6])]) # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) # -------------------------------------------------------------- m4_define([lt_dict_filter], [m4_if([$5], [], [], [lt_join(m4_quote(m4_default([$4], [[, ]])), lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ]) libopenmpt-0.3.6+release.autotools/m4/ax_append_flag.m40000644000372100037210000000533113235362213017772 00000000000000# =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_append_flag.html # =========================================================================== # # SYNOPSIS # # AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE]) # # DESCRIPTION # # FLAG is appended to the FLAGS-VARIABLE shell variable, with a space # added in between. # # If FLAGS-VARIABLE is not specified, the current language's flags (e.g. # CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains # FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly # FLAG. # # NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. # # LICENSE # # Copyright (c) 2008 Guido U. Draheim # Copyright (c) 2011 Maarten Bosmans # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, either version 3 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 6 AC_DEFUN([AX_APPEND_FLAG], [dnl AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_SET_IF AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])]) AS_VAR_SET_IF(FLAGS,[ AS_CASE([" AS_VAR_GET(FLAGS) "], [*" $1 "*], [AC_RUN_LOG([: FLAGS already contains $1])], [ AS_VAR_APPEND(FLAGS,[" $1"]) AC_RUN_LOG([: FLAGS="$FLAGS"]) ]) ], [ AS_VAR_SET(FLAGS,[$1]) AC_RUN_LOG([: FLAGS="$FLAGS"]) ]) AS_VAR_POPDEF([FLAGS])dnl ])dnl AX_APPEND_FLAG libopenmpt-0.3.6+release.autotools/m4/ax_check_compile_flag.m40000644000372100037210000000640213235362213021310 00000000000000# =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html # =========================================================================== # # SYNOPSIS # # AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) # # DESCRIPTION # # Check whether the given FLAG works with the current language's compiler # or gives an error. (Warnings, however, are ignored) # # ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on # success/failure. # # If EXTRA-FLAGS is defined, it is added to the current language's default # flags (e.g. CFLAGS) when the check is done. The check is thus made with # the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to # force the compiler to issue an error when a bad flag is given. # # INPUT gives an alternative input source to AC_COMPILE_IFELSE. # # NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this # macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG. # # LICENSE # # Copyright (c) 2008 Guido U. Draheim # Copyright (c) 2011 Maarten Bosmans # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, either version 3 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 4 AC_DEFUN([AX_CHECK_COMPILE_FLAG], [AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], [AS_VAR_SET(CACHEVAR,[yes])], [AS_VAR_SET(CACHEVAR,[no])]) _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) AS_VAR_IF(CACHEVAR,yes, [m4_default([$2], :)], [m4_default([$3], :)]) AS_VAR_POPDEF([CACHEVAR])dnl ])dnl AX_CHECK_COMPILE_FLAGS libopenmpt-0.3.6+release.autotools/m4/ax_prog_doxygen.m40000644000372100037210000005004213041741307020235 00000000000000# =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_prog_doxygen.html # =========================================================================== # # SYNOPSIS # # DX_INIT_DOXYGEN(PROJECT-NAME, [DOXYFILE-PATH], [OUTPUT-DIR], ...) # DX_DOXYGEN_FEATURE(ON|OFF) # DX_DOT_FEATURE(ON|OFF) # DX_HTML_FEATURE(ON|OFF) # DX_CHM_FEATURE(ON|OFF) # DX_CHI_FEATURE(ON|OFF) # DX_MAN_FEATURE(ON|OFF) # DX_RTF_FEATURE(ON|OFF) # DX_XML_FEATURE(ON|OFF) # DX_PDF_FEATURE(ON|OFF) # DX_PS_FEATURE(ON|OFF) # # DESCRIPTION # # The DX_*_FEATURE macros control the default setting for the given # Doxygen feature. Supported features are 'DOXYGEN' itself, 'DOT' for # generating graphics, 'HTML' for plain HTML, 'CHM' for compressed HTML # help (for MS users), 'CHI' for generating a seperate .chi file by the # .chm file, and 'MAN', 'RTF', 'XML', 'PDF' and 'PS' for the appropriate # output formats. The environment variable DOXYGEN_PAPER_SIZE may be # specified to override the default 'a4wide' paper size. # # By default, HTML, PDF and PS documentation is generated as this seems to # be the most popular and portable combination. MAN pages created by # Doxygen are usually problematic, though by picking an appropriate subset # and doing some massaging they might be better than nothing. CHM and RTF # are specific for MS (note that you can't generate both HTML and CHM at # the same time). The XML is rather useless unless you apply specialized # post-processing to it. # # The macros mainly control the default state of the feature. The use can # override the default by specifying --enable or --disable. The macros # ensure that contradictory flags are not given (e.g., # --enable-doxygen-html and --enable-doxygen-chm, # --enable-doxygen-anything with --disable-doxygen, etc.) Finally, each # feature will be automatically disabled (with a warning) if the required # programs are missing. # # Once all the feature defaults have been specified, call DX_INIT_DOXYGEN # with the following parameters: a one-word name for the project for use # as a filename base etc., an optional configuration file name (the # default is '$(srcdir)/Doxyfile', the same as Doxygen's default), and an # optional output directory name (the default is 'doxygen-doc'). To run # doxygen multiple times for different configuration files and output # directories provide more parameters: the second, forth, sixth, etc # parameter are configuration file names and the third, fifth, seventh, # etc parameter are output directories. No checking is done to catch # duplicates. # # Automake Support # # The DX_RULES substitution can be used to add all needed rules to the # Makefile. Note that this is a substitution without being a variable: # only the @DX_RULES@ syntax will work. # # The provided targets are: # # doxygen-doc: Generate all doxygen documentation. # # doxygen-run: Run doxygen, which will generate some of the # documentation (HTML, CHM, CHI, MAN, RTF, XML) # but will not do the post processing required # for the rest of it (PS, PDF). # # doxygen-ps: Generate doxygen PostScript documentation. # # doxygen-pdf: Generate doxygen PDF documentation. # # Note that by default these are not integrated into the automake targets. # If doxygen is used to generate man pages, you can achieve this # integration by setting man3_MANS to the list of man pages generated and # then adding the dependency: # # $(man3_MANS): doxygen-doc # # This will cause make to run doxygen and generate all the documentation. # # The following variable is intended for use in Makefile.am: # # DX_CLEANFILES = everything to clean. # # Then add this variable to MOSTLYCLEANFILES. # # LICENSE # # Copyright (c) 2009 Oren Ben-Kiki # Copyright (c) 2015 Olaf Mandel # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 20 ## ----------## ## Defaults. ## ## ----------## DX_ENV="" AC_DEFUN([DX_FEATURE_doc], ON) AC_DEFUN([DX_FEATURE_dot], OFF) AC_DEFUN([DX_FEATURE_man], OFF) AC_DEFUN([DX_FEATURE_html], ON) AC_DEFUN([DX_FEATURE_chm], OFF) AC_DEFUN([DX_FEATURE_chi], OFF) AC_DEFUN([DX_FEATURE_rtf], OFF) AC_DEFUN([DX_FEATURE_xml], OFF) AC_DEFUN([DX_FEATURE_pdf], ON) AC_DEFUN([DX_FEATURE_ps], ON) ## --------------- ## ## Private macros. ## ## --------------- ## # DX_ENV_APPEND(VARIABLE, VALUE) # ------------------------------ # Append VARIABLE="VALUE" to DX_ENV for invoking doxygen and add it # as a substitution (but not a Makefile variable). The substitution # is skipped if the variable name is VERSION. AC_DEFUN([DX_ENV_APPEND], [AC_SUBST([DX_ENV], ["$DX_ENV $1='$2'"])dnl m4_if([$1], [VERSION], [], [AC_SUBST([$1], [$2])dnl AM_SUBST_NOTMAKE([$1])])dnl ]) # DX_DIRNAME_EXPR # --------------- # Expand into a shell expression prints the directory part of a path. AC_DEFUN([DX_DIRNAME_EXPR], [[expr ".$1" : '\(\.\)[^/]*$' \| "x$1" : 'x\(.*\)/[^/]*$']]) # DX_IF_FEATURE(FEATURE, IF-ON, IF-OFF) # ------------------------------------- # Expands according to the M4 (static) status of the feature. AC_DEFUN([DX_IF_FEATURE], [ifelse(DX_FEATURE_$1, ON, [$2], [$3])]) # DX_REQUIRE_PROG(VARIABLE, PROGRAM) # ---------------------------------- # Require the specified program to be found for the DX_CURRENT_FEATURE to work. AC_DEFUN([DX_REQUIRE_PROG], [ AC_PATH_TOOL([$1], [$2]) if test "$DX_FLAG_[]DX_CURRENT_FEATURE$$1" = 1; then AC_MSG_WARN([$2 not found - will not DX_CURRENT_DESCRIPTION]) AC_SUBST(DX_FLAG_[]DX_CURRENT_FEATURE, 0) fi ]) # DX_TEST_FEATURE(FEATURE) # ------------------------ # Expand to a shell expression testing whether the feature is active. AC_DEFUN([DX_TEST_FEATURE], [test "$DX_FLAG_$1" = 1]) # DX_CHECK_DEPEND(REQUIRED_FEATURE, REQUIRED_STATE) # ------------------------------------------------- # Verify that a required features has the right state before trying to turn on # the DX_CURRENT_FEATURE. AC_DEFUN([DX_CHECK_DEPEND], [ test "$DX_FLAG_$1" = "$2" \ || AC_MSG_ERROR([doxygen-DX_CURRENT_FEATURE ifelse([$2], 1, requires, contradicts) doxygen-DX_CURRENT_FEATURE]) ]) # DX_CLEAR_DEPEND(FEATURE, REQUIRED_FEATURE, REQUIRED_STATE) # ---------------------------------------------------------- # Turn off the DX_CURRENT_FEATURE if the required feature is off. AC_DEFUN([DX_CLEAR_DEPEND], [ test "$DX_FLAG_$1" = "$2" || AC_SUBST(DX_FLAG_[]DX_CURRENT_FEATURE, 0) ]) # DX_FEATURE_ARG(FEATURE, DESCRIPTION, # CHECK_DEPEND, CLEAR_DEPEND, # REQUIRE, DO-IF-ON, DO-IF-OFF) # -------------------------------------------- # Parse the command-line option controlling a feature. CHECK_DEPEND is called # if the user explicitly turns the feature on (and invokes DX_CHECK_DEPEND), # otherwise CLEAR_DEPEND is called to turn off the default state if a required # feature is disabled (using DX_CLEAR_DEPEND). REQUIRE performs additional # requirement tests (DX_REQUIRE_PROG). Finally, an automake flag is set and # DO-IF-ON or DO-IF-OFF are called according to the final state of the feature. AC_DEFUN([DX_ARG_ABLE], [ AC_DEFUN([DX_CURRENT_FEATURE], [$1]) AC_DEFUN([DX_CURRENT_DESCRIPTION], [$2]) AC_ARG_ENABLE(doxygen-$1, [AS_HELP_STRING(DX_IF_FEATURE([$1], [--disable-doxygen-$1], [--enable-doxygen-$1]), DX_IF_FEATURE([$1], [don't $2], [$2]))], [ case "$enableval" in #( y|Y|yes|Yes|YES) AC_SUBST([DX_FLAG_$1], 1) $3 ;; #( n|N|no|No|NO) AC_SUBST([DX_FLAG_$1], 0) ;; #( *) AC_MSG_ERROR([invalid value '$enableval' given to doxygen-$1]) ;; esac ], [ AC_SUBST([DX_FLAG_$1], [DX_IF_FEATURE([$1], 1, 0)]) $4 ]) if DX_TEST_FEATURE([$1]); then $5 : fi if DX_TEST_FEATURE([$1]); then $6 : else $7 : fi ]) ## -------------- ## ## Public macros. ## ## -------------- ## # DX_XXX_FEATURE(DEFAULT_STATE) # ----------------------------- AC_DEFUN([DX_DOXYGEN_FEATURE], [AC_DEFUN([DX_FEATURE_doc], [$1])]) AC_DEFUN([DX_DOT_FEATURE], [AC_DEFUN([DX_FEATURE_dot], [$1])]) AC_DEFUN([DX_MAN_FEATURE], [AC_DEFUN([DX_FEATURE_man], [$1])]) AC_DEFUN([DX_HTML_FEATURE], [AC_DEFUN([DX_FEATURE_html], [$1])]) AC_DEFUN([DX_CHM_FEATURE], [AC_DEFUN([DX_FEATURE_chm], [$1])]) AC_DEFUN([DX_CHI_FEATURE], [AC_DEFUN([DX_FEATURE_chi], [$1])]) AC_DEFUN([DX_RTF_FEATURE], [AC_DEFUN([DX_FEATURE_rtf], [$1])]) AC_DEFUN([DX_XML_FEATURE], [AC_DEFUN([DX_FEATURE_xml], [$1])]) AC_DEFUN([DX_XML_FEATURE], [AC_DEFUN([DX_FEATURE_xml], [$1])]) AC_DEFUN([DX_PDF_FEATURE], [AC_DEFUN([DX_FEATURE_pdf], [$1])]) AC_DEFUN([DX_PS_FEATURE], [AC_DEFUN([DX_FEATURE_ps], [$1])]) # DX_INIT_DOXYGEN(PROJECT, [CONFIG-FILE], [OUTPUT-DOC-DIR], ...) # -------------------------------------------------------------- # PROJECT also serves as the base name for the documentation files. # The default CONFIG-FILE is "$(srcdir)/Doxyfile" and OUTPUT-DOC-DIR is # "doxygen-doc". # More arguments are interpreted as interleaved CONFIG-FILE and # OUTPUT-DOC-DIR values. AC_DEFUN([DX_INIT_DOXYGEN], [ # Files: AC_SUBST([DX_PROJECT], [$1]) AC_SUBST([DX_CONFIG], ['ifelse([$2], [], [$(srcdir)/Doxyfile], [$2])']) AC_SUBST([DX_DOCDIR], ['ifelse([$3], [], [doxygen-doc], [$3])']) m4_if(m4_eval(3 < m4_count($@)), 1, [m4_for([DX_i], 4, m4_count($@), 2, [AC_SUBST([DX_CONFIG]m4_eval(DX_i[/2]), 'm4_default_nblank_quoted(m4_argn(DX_i, $@), [$(srcdir)/Doxyfile])')])])dnl m4_if(m4_eval(3 < m4_count($@)), 1, [m4_for([DX_i], 5, m4_count($@,), 2, [AC_SUBST([DX_DOCDIR]m4_eval([(]DX_i[-1)/2]), 'm4_default_nblank_quoted(m4_argn(DX_i, $@), [doxygen-doc])')])])dnl m4_define([DX_loop], m4_dquote(m4_if(m4_eval(3 < m4_count($@)), 1, [m4_for([DX_i], 4, m4_count($@), 2, [, m4_eval(DX_i[/2])])], [])))dnl # Environment variables used inside doxygen.cfg: DX_ENV_APPEND(SRCDIR, $srcdir) DX_ENV_APPEND(PROJECT, $DX_PROJECT) DX_ENV_APPEND(VERSION, $PACKAGE_VERSION) # Doxygen itself: DX_ARG_ABLE(doc, [generate any doxygen documentation], [], [], [DX_REQUIRE_PROG([DX_DOXYGEN], doxygen) DX_REQUIRE_PROG([DX_PERL], perl)], [DX_ENV_APPEND(PERL_PATH, $DX_PERL)]) # Dot for graphics: DX_ARG_ABLE(dot, [generate graphics for doxygen documentation], [DX_CHECK_DEPEND(doc, 1)], [DX_CLEAR_DEPEND(doc, 1)], [DX_REQUIRE_PROG([DX_DOT], dot)], [DX_ENV_APPEND(HAVE_DOT, YES) DX_ENV_APPEND(DOT_PATH, [`DX_DIRNAME_EXPR($DX_DOT)`])], [DX_ENV_APPEND(HAVE_DOT, NO)]) # Man pages generation: DX_ARG_ABLE(man, [generate doxygen manual pages], [DX_CHECK_DEPEND(doc, 1)], [DX_CLEAR_DEPEND(doc, 1)], [], [DX_ENV_APPEND(GENERATE_MAN, YES)], [DX_ENV_APPEND(GENERATE_MAN, NO)]) # RTF file generation: DX_ARG_ABLE(rtf, [generate doxygen RTF documentation], [DX_CHECK_DEPEND(doc, 1)], [DX_CLEAR_DEPEND(doc, 1)], [], [DX_ENV_APPEND(GENERATE_RTF, YES)], [DX_ENV_APPEND(GENERATE_RTF, NO)]) # XML file generation: DX_ARG_ABLE(xml, [generate doxygen XML documentation], [DX_CHECK_DEPEND(doc, 1)], [DX_CLEAR_DEPEND(doc, 1)], [], [DX_ENV_APPEND(GENERATE_XML, YES)], [DX_ENV_APPEND(GENERATE_XML, NO)]) # (Compressed) HTML help generation: DX_ARG_ABLE(chm, [generate doxygen compressed HTML help documentation], [DX_CHECK_DEPEND(doc, 1)], [DX_CLEAR_DEPEND(doc, 1)], [DX_REQUIRE_PROG([DX_HHC], hhc)], [DX_ENV_APPEND(HHC_PATH, $DX_HHC) DX_ENV_APPEND(GENERATE_HTML, YES) DX_ENV_APPEND(GENERATE_HTMLHELP, YES)], [DX_ENV_APPEND(GENERATE_HTMLHELP, NO)]) # Seperate CHI file generation. DX_ARG_ABLE(chi, [generate doxygen seperate compressed HTML help index file], [DX_CHECK_DEPEND(chm, 1)], [DX_CLEAR_DEPEND(chm, 1)], [], [DX_ENV_APPEND(GENERATE_CHI, YES)], [DX_ENV_APPEND(GENERATE_CHI, NO)]) # Plain HTML pages generation: DX_ARG_ABLE(html, [generate doxygen plain HTML documentation], [DX_CHECK_DEPEND(doc, 1) DX_CHECK_DEPEND(chm, 0)], [DX_CLEAR_DEPEND(doc, 1) DX_CLEAR_DEPEND(chm, 0)], [], [DX_ENV_APPEND(GENERATE_HTML, YES)], [DX_TEST_FEATURE(chm) || DX_ENV_APPEND(GENERATE_HTML, NO)]) # PostScript file generation: DX_ARG_ABLE(ps, [generate doxygen PostScript documentation], [DX_CHECK_DEPEND(doc, 1)], [DX_CLEAR_DEPEND(doc, 1)], [DX_REQUIRE_PROG([DX_LATEX], latex) DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex) DX_REQUIRE_PROG([DX_DVIPS], dvips) DX_REQUIRE_PROG([DX_EGREP], egrep)]) # PDF file generation: DX_ARG_ABLE(pdf, [generate doxygen PDF documentation], [DX_CHECK_DEPEND(doc, 1)], [DX_CLEAR_DEPEND(doc, 1)], [DX_REQUIRE_PROG([DX_PDFLATEX], pdflatex) DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex) DX_REQUIRE_PROG([DX_EGREP], egrep)]) # LaTeX generation for PS and/or PDF: if DX_TEST_FEATURE(ps) || DX_TEST_FEATURE(pdf); then DX_ENV_APPEND(GENERATE_LATEX, YES) else DX_ENV_APPEND(GENERATE_LATEX, NO) fi # Paper size for PS and/or PDF: AC_ARG_VAR(DOXYGEN_PAPER_SIZE, [a4wide (default), a4, letter, legal or executive]) case "$DOXYGEN_PAPER_SIZE" in #( "") AC_SUBST(DOXYGEN_PAPER_SIZE, "") ;; #( a4wide|a4|letter|legal|executive) DX_ENV_APPEND(PAPER_SIZE, $DOXYGEN_PAPER_SIZE) ;; #( *) AC_MSG_ERROR([unknown DOXYGEN_PAPER_SIZE='$DOXYGEN_PAPER_SIZE']) ;; esac # Rules: AS_IF([[test $DX_FLAG_html -eq 1]], [[DX_SNIPPET_html="## ------------------------------- ## ## Rules specific for HTML output. ## ## ------------------------------- ## DX_CLEAN_HTML = \$(DX_DOCDIR)/html]dnl m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\ \$(DX_DOCDIR]DX_i[)/html]])[ "]], [[DX_SNIPPET_html=""]]) AS_IF([[test $DX_FLAG_chi -eq 1]], [[DX_SNIPPET_chi=" DX_CLEAN_CHI = \$(DX_DOCDIR)/\$(PACKAGE).chi]dnl m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\ \$(DX_DOCDIR]DX_i[)/\$(PACKAGE).chi]])["]], [[DX_SNIPPET_chi=""]]) AS_IF([[test $DX_FLAG_chm -eq 1]], [[DX_SNIPPET_chm="## ------------------------------ ## ## Rules specific for CHM output. ## ## ------------------------------ ## DX_CLEAN_CHM = \$(DX_DOCDIR)/chm]dnl m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\ \$(DX_DOCDIR]DX_i[)/chm]])[\ ${DX_SNIPPET_chi} "]], [[DX_SNIPPET_chm=""]]) AS_IF([[test $DX_FLAG_man -eq 1]], [[DX_SNIPPET_man="## ------------------------------ ## ## Rules specific for MAN output. ## ## ------------------------------ ## DX_CLEAN_MAN = \$(DX_DOCDIR)/man]dnl m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\ \$(DX_DOCDIR]DX_i[)/man]])[ "]], [[DX_SNIPPET_man=""]]) AS_IF([[test $DX_FLAG_rtf -eq 1]], [[DX_SNIPPET_rtf="## ------------------------------ ## ## Rules specific for RTF output. ## ## ------------------------------ ## DX_CLEAN_RTF = \$(DX_DOCDIR)/rtf]dnl m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\ \$(DX_DOCDIR]DX_i[)/rtf]])[ "]], [[DX_SNIPPET_rtf=""]]) AS_IF([[test $DX_FLAG_xml -eq 1]], [[DX_SNIPPET_xml="## ------------------------------ ## ## Rules specific for XML output. ## ## ------------------------------ ## DX_CLEAN_XML = \$(DX_DOCDIR)/xml]dnl m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\ \$(DX_DOCDIR]DX_i[)/xml]])[ "]], [[DX_SNIPPET_xml=""]]) AS_IF([[test $DX_FLAG_ps -eq 1]], [[DX_SNIPPET_ps="## ----------------------------- ## ## Rules specific for PS output. ## ## ----------------------------- ## DX_CLEAN_PS = \$(DX_DOCDIR)/\$(PACKAGE).ps]dnl m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\ \$(DX_DOCDIR]DX_i[)/\$(PACKAGE).ps]])[ DX_PS_GOAL = doxygen-ps doxygen-ps: \$(DX_CLEAN_PS) ]m4_foreach([DX_i], [DX_loop], [[\$(DX_DOCDIR]DX_i[)/\$(PACKAGE).ps: \$(DX_DOCDIR]DX_i[)/\$(PACKAGE).tag \$(DX_V_LATEX)cd \$(DX_DOCDIR]DX_i[)/latex; \\ rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \\ \$(DX_LATEX) refman.tex; \\ \$(DX_MAKEINDEX) refman.idx; \\ \$(DX_LATEX) refman.tex; \\ countdown=5; \\ while \$(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \\ refman.log > /dev/null 2>&1 \\ && test \$\$countdown -gt 0; do \\ \$(DX_LATEX) refman.tex; \\ countdown=\`expr \$\$countdown - 1\`; \\ done; \\ \$(DX_DVIPS) -o ../\$(PACKAGE).ps refman.dvi ]])["]], [[DX_SNIPPET_ps=""]]) AS_IF([[test $DX_FLAG_pdf -eq 1]], [[DX_SNIPPET_pdf="## ------------------------------ ## ## Rules specific for PDF output. ## ## ------------------------------ ## DX_CLEAN_PDF = \$(DX_DOCDIR)/\$(PACKAGE).pdf]dnl m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\ \$(DX_DOCDIR]DX_i[)/\$(PACKAGE).pdf]])[ DX_PDF_GOAL = doxygen-pdf doxygen-pdf: \$(DX_CLEAN_PDF) ]m4_foreach([DX_i], [DX_loop], [[\$(DX_DOCDIR]DX_i[)/\$(PACKAGE).pdf: \$(DX_DOCDIR]DX_i[)/\$(PACKAGE).tag \$(DX_V_LATEX)cd \$(DX_DOCDIR]DX_i[)/latex; \\ rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \\ \$(DX_PDFLATEX) refman.tex; \\ \$(DX_MAKEINDEX) refman.idx; \\ \$(DX_PDFLATEX) refman.tex; \\ countdown=5; \\ while \$(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \\ refman.log > /dev/null 2>&1 \\ && test \$\$countdown -gt 0; do \\ \$(DX_PDFLATEX) refman.tex; \\ countdown=\`expr \$\$countdown - 1\`; \\ done; \\ mv refman.pdf ../\$(PACKAGE).pdf ]])["]], [[DX_SNIPPET_pdf=""]]) AS_IF([[test $DX_FLAG_ps -eq 1 -o $DX_FLAG_pdf -eq 1]], [[DX_SNIPPET_latex="## ------------------------------------------------- ## ## Rules specific for LaTeX (shared for PS and PDF). ## ## ------------------------------------------------- ## DX_V_LATEX = \$(_DX_v_LATEX_\$(V)) _DX_v_LATEX_ = \$(_DX_v_LATEX_\$(AM_DEFAULT_VERBOSITY)) _DX_v_LATEX_0 = @echo \" LATEX \" \$][@; DX_CLEAN_LATEX = \$(DX_DOCDIR)/latex]dnl m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\ \$(DX_DOCDIR]DX_i[)/latex]])[ "]], [[DX_SNIPPET_latex=""]]) AS_IF([[test $DX_FLAG_doc -eq 1]], [[DX_SNIPPET_doc="## --------------------------------- ## ## Format-independent Doxygen rules. ## ## --------------------------------- ## ${DX_SNIPPET_html}\ ${DX_SNIPPET_chm}\ ${DX_SNIPPET_man}\ ${DX_SNIPPET_rtf}\ ${DX_SNIPPET_xml}\ ${DX_SNIPPET_ps}\ ${DX_SNIPPET_pdf}\ ${DX_SNIPPET_latex}\ DX_V_DXGEN = \$(_DX_v_DXGEN_\$(V)) _DX_v_DXGEN_ = \$(_DX_v_DXGEN_\$(AM_DEFAULT_VERBOSITY)) _DX_v_DXGEN_0 = @echo \" DXGEN \" \$<; .PHONY: doxygen-run doxygen-doc \$(DX_PS_GOAL) \$(DX_PDF_GOAL) .INTERMEDIATE: doxygen-run \$(DX_PS_GOAL) \$(DX_PDF_GOAL) doxygen-run:]m4_foreach([DX_i], [DX_loop], [[ \$(DX_DOCDIR]DX_i[)/\$(PACKAGE).tag]])[ doxygen-doc: doxygen-run \$(DX_PS_GOAL) \$(DX_PDF_GOAL) ]m4_foreach([DX_i], [DX_loop], [[\$(DX_DOCDIR]DX_i[)/\$(PACKAGE).tag: \$(DX_CONFIG]DX_i[) \$(pkginclude_HEADERS) \$(A""M_V_at)rm -rf \$(DX_DOCDIR]DX_i[) \$(DX_V_DXGEN)\$(DX_ENV) DOCDIR=\$(DX_DOCDIR]DX_i[) \$(DX_DOXYGEN) \$(DX_CONFIG]DX_i[) \$(A""M_V_at)echo Timestamp >\$][@ ]])dnl [DX_CLEANFILES = \\] m4_foreach([DX_i], [DX_loop], [[ \$(DX_DOCDIR]DX_i[)/doxygen_sqlite3.db \\ \$(DX_DOCDIR]DX_i[)/\$(PACKAGE).tag \\ ]])dnl [ -r \\ \$(DX_CLEAN_HTML) \\ \$(DX_CLEAN_CHM) \\ \$(DX_CLEAN_CHI) \\ \$(DX_CLEAN_MAN) \\ \$(DX_CLEAN_RTF) \\ \$(DX_CLEAN_XML) \\ \$(DX_CLEAN_PS) \\ \$(DX_CLEAN_PDF) \\ \$(DX_CLEAN_LATEX)"]], [[DX_SNIPPET_doc=""]]) AC_SUBST([DX_RULES], ["${DX_SNIPPET_doc}"])dnl AM_SUBST_NOTMAKE([DX_RULES]) #For debugging: #echo DX_FLAG_doc=$DX_FLAG_doc #echo DX_FLAG_dot=$DX_FLAG_dot #echo DX_FLAG_man=$DX_FLAG_man #echo DX_FLAG_html=$DX_FLAG_html #echo DX_FLAG_chm=$DX_FLAG_chm #echo DX_FLAG_chi=$DX_FLAG_chi #echo DX_FLAG_rtf=$DX_FLAG_rtf #echo DX_FLAG_xml=$DX_FLAG_xml #echo DX_FLAG_pdf=$DX_FLAG_pdf #echo DX_FLAG_ps=$DX_FLAG_ps #echo DX_ENV=$DX_ENV ]) libopenmpt-0.3.6+release.autotools/m4/pkg.m40000644000372100037210000002400513235362213015622 00000000000000dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- dnl serial 11 (pkg-config-0.29) dnl dnl Copyright © 2004 Scott James Remnant . dnl Copyright © 2012-2015 Dan Nicholson dnl dnl This program is free software; you can redistribute it and/or modify dnl it under the terms of the GNU General Public License as published by dnl the Free Software Foundation; either version 2 of the License, or dnl (at your option) any later version. dnl dnl This program is distributed in the hope that it will be useful, but dnl WITHOUT ANY WARRANTY; without even the implied warranty of dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU dnl General Public License for more details. dnl dnl You should have received a copy of the GNU General Public License dnl along with this program; if not, write to the Free Software dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA dnl 02111-1307, USA. dnl dnl As a special exception to the GNU General Public License, if you dnl distribute this file as part of a program that contains a dnl configuration script generated by Autoconf, you may include it under dnl the same distribution terms that you use for the rest of that dnl program. dnl PKG_PREREQ(MIN-VERSION) dnl ----------------------- dnl Since: 0.29 dnl dnl Verify that the version of the pkg-config macros are at least dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's dnl installed version of pkg-config, this checks the developer's version dnl of pkg.m4 when generating configure. dnl dnl To ensure that this macro is defined, also add: dnl m4_ifndef([PKG_PREREQ], dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) dnl dnl See the "Since" comment for each macro you use to see what version dnl of the macros you require. m4_defun([PKG_PREREQ], [m4_define([PKG_MACROS_VERSION], [0.29]) m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) ])dnl PKG_PREREQ dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) dnl ---------------------------------- dnl Since: 0.16 dnl dnl Search for the pkg-config tool and set the PKG_CONFIG variable to dnl first found in the path. Checks that the version of pkg-config found dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is dnl used since that's the first version where most current features of dnl pkg-config existed. AC_DEFUN([PKG_PROG_PKG_CONFIG], [m4_pattern_forbid([^_?PKG_[A-Z_]+$]) m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) fi if test -n "$PKG_CONFIG"; then _pkg_min_version=m4_default([$1], [0.9.0]) AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) PKG_CONFIG="" fi fi[]dnl ])dnl PKG_PROG_PKG_CONFIG dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl ------------------------------------------------------------------- dnl Since: 0.18 dnl dnl Check to see whether a particular set of modules exists. Similar to dnl PKG_CHECK_MODULES(), but does not set variables or print errors. dnl dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) dnl only at the first occurence in configure.ac, so if the first place dnl it's called might be skipped (such as if it is within an "if", you dnl have to call PKG_CHECK_EXISTS manually AC_DEFUN([PKG_CHECK_EXISTS], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl if test -n "$PKG_CONFIG" && \ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then m4_default([$2], [:]) m4_ifvaln([$3], [else $3])dnl fi]) dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) dnl --------------------------------------------- dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting dnl pkg_failed based on the result. m4_define([_PKG_CONFIG], [if test -n "$$1"; then pkg_cv_[]$1="$$1" elif test -n "$PKG_CONFIG"; then PKG_CHECK_EXISTS([$3], [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes ], [pkg_failed=yes]) else pkg_failed=untried fi[]dnl ])dnl _PKG_CONFIG dnl _PKG_SHORT_ERRORS_SUPPORTED dnl --------------------------- dnl Internal check to see if pkg-config supports short errors. AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], [AC_REQUIRE([PKG_PROG_PKG_CONFIG]) if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi[]dnl ])dnl _PKG_SHORT_ERRORS_SUPPORTED dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], dnl [ACTION-IF-NOT-FOUND]) dnl -------------------------------------------------------------- dnl Since: 0.4.0 dnl dnl Note that if there is a possibility the first call to dnl PKG_CHECK_MODULES might not happen, you should be sure to include an dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac AC_DEFUN([PKG_CHECK_MODULES], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no AC_MSG_CHECKING([for $1]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS and $1[]_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details.]) if test $pkg_failed = yes; then AC_MSG_RESULT([no]) _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` else $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD m4_default([$4], [AC_MSG_ERROR( [Package requirements ($2) were not met: $$1_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. _PKG_TEXT])[]dnl ]) elif test $pkg_failed = untried; then AC_MSG_RESULT([no]) m4_default([$4], [AC_MSG_FAILURE( [The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. _PKG_TEXT To get pkg-config, see .])[]dnl ]) else $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS $1[]_LIBS=$pkg_cv_[]$1[]_LIBS AC_MSG_RESULT([yes]) $3 fi[]dnl ])dnl PKG_CHECK_MODULES dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], dnl [ACTION-IF-NOT-FOUND]) dnl --------------------------------------------------------------------- dnl Since: 0.29 dnl dnl Checks for existence of MODULES and gathers its build flags with dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags dnl and VARIABLE-PREFIX_LIBS from --libs. dnl dnl Note that if there is a possibility the first call to dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to dnl include an explicit call to PKG_PROG_PKG_CONFIG in your dnl configure.ac. AC_DEFUN([PKG_CHECK_MODULES_STATIC], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl _save_PKG_CONFIG=$PKG_CONFIG PKG_CONFIG="$PKG_CONFIG --static" PKG_CHECK_MODULES($@) PKG_CONFIG=$_save_PKG_CONFIG[]dnl ])dnl PKG_CHECK_MODULES_STATIC dnl PKG_INSTALLDIR([DIRECTORY]) dnl ------------------------- dnl Since: 0.27 dnl dnl Substitutes the variable pkgconfigdir as the location where a module dnl should install pkg-config .pc files. By default the directory is dnl $libdir/pkgconfig, but the default can be changed by passing dnl DIRECTORY. The user can override through the --with-pkgconfigdir dnl parameter. AC_DEFUN([PKG_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([pkgconfigdir], [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, [with_pkgconfigdir=]pkg_default) AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ])dnl PKG_INSTALLDIR dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) dnl -------------------------------- dnl Since: 0.27 dnl dnl Substitutes the variable noarch_pkgconfigdir as the location where a dnl module should install arch-independent pkg-config .pc files. By dnl default the directory is $datadir/pkgconfig, but the default can be dnl changed by passing DIRECTORY. The user can override through the dnl --with-noarch-pkgconfigdir parameter. AC_DEFUN([PKG_NOARCH_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([noarch-pkgconfigdir], [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, [with_noarch_pkgconfigdir=]pkg_default) AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ])dnl PKG_NOARCH_INSTALLDIR dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl ------------------------------------------- dnl Since: 0.28 dnl dnl Retrieves the value of the pkg-config variable for the given module. AC_DEFUN([PKG_CHECK_VAR], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl _PKG_CONFIG([$1], [variable="][$3]["], [$2]) AS_VAR_COPY([$1], [pkg_cv_][$1]) AS_VAR_IF([$1], [""], [$5], [$4])dnl ])dnl PKG_CHECK_VAR libopenmpt-0.3.6+release.autotools/m4/libtool.m40000644000372100037210000112617113235362213016515 00000000000000# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. m4_define([_LT_COPYING], [dnl # Copyright (C) 2014 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program or library that is built # using GNU Libtool, you may include this file under the same # distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . ]) # serial 58 LT_INIT # LT_PREREQ(VERSION) # ------------------ # Complain and exit if this libtool version is less that VERSION. m4_defun([LT_PREREQ], [m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, [m4_default([$3], [m4_fatal([Libtool version $1 or higher is required], 63)])], [$2])]) # _LT_CHECK_BUILDDIR # ------------------ # Complain if the absolute build directory name contains unusual characters m4_defun([_LT_CHECK_BUILDDIR], [case `pwd` in *\ * | *\ *) AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; esac ]) # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], [AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl AC_BEFORE([$0], [LTDL_INIT])dnl m4_require([_LT_CHECK_BUILDDIR])dnl dnl Autoconf doesn't catch unexpanded LT_ macros by default: m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 dnl unless we require an AC_DEFUNed macro: AC_REQUIRE([LTOPTIONS_VERSION])dnl AC_REQUIRE([LTSUGAR_VERSION])dnl AC_REQUIRE([LTVERSION_VERSION])dnl AC_REQUIRE([LTOBSOLETE_VERSION])dnl m4_require([_LT_PROG_LTMAIN])dnl _LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' AC_SUBST(LIBTOOL)dnl _LT_SETUP # Only expand once: m4_define([LT_INIT]) ])# LT_INIT # Old names: AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PROG_LIBTOOL], []) dnl AC_DEFUN([AM_PROG_LIBTOOL], []) # _LT_PREPARE_CC_BASENAME # ----------------------- m4_defun([_LT_PREPARE_CC_BASENAME], [ # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in @S|@*""; do case $cc_temp in compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } ])# _LT_PREPARE_CC_BASENAME # _LT_CC_BASENAME(CC) # ------------------- # It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME, # but that macro is also expanded into generated libtool script, which # arranges for $SED and $ECHO to be set by different means. m4_defun([_LT_CC_BASENAME], [m4_require([_LT_PREPARE_CC_BASENAME])dnl AC_REQUIRE([_LT_DECL_SED])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl func_cc_basename $1 cc_basename=$func_cc_basename_result ]) # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set # sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} ])# _LT_FILEUTILS_DEFAULTS # _LT_SETUP # --------- m4_defun([_LT_SETUP], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl _LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl dnl _LT_DECL([], [build_alias], [0], [The build system])dnl _LT_DECL([], [build], [0])dnl _LT_DECL([], [build_os], [0])dnl dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl dnl AC_REQUIRE([AC_PROG_LN_S])dnl test -z "$LN_S" && LN_S="ln -s" _LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl dnl AC_REQUIRE([LT_CMD_MAX_LEN])dnl _LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl m4_require([_LT_CMD_RELOAD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_WITH_SYSROOT])dnl m4_require([_LT_CMD_TRUNCATE])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi ]) if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi _LT_CHECK_OBJDIR m4_require([_LT_TAG_COMPILER])dnl case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a '.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld old_CC=$CC old_CFLAGS=$CFLAGS # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o _LT_CC_BASENAME([$compiler]) # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then _LT_PATH_MAGIC fi ;; esac # Use C for the default configuration in the libtool script LT_SUPPORTED_TAG([CC]) _LT_LANG_C_CONFIG _LT_LANG_DEFAULT_CONFIG _LT_CONFIG_COMMANDS ])# _LT_SETUP # _LT_PREPARE_SED_QUOTE_VARS # -------------------------- # Define a few sed substitution that help us do robust quoting. m4_defun([_LT_PREPARE_SED_QUOTE_VARS], [# Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\([["`\\]]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ]) # _LT_PROG_LTMAIN # --------------- # Note that this code is called both from 'configure', and 'config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, # 'config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) ltmain=$ac_aux_dir/ltmain.sh ])# _LT_PROG_LTMAIN ## ------------------------------------- ## ## Accumulate code for creating libtool. ## ## ------------------------------------- ## # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS # in macros and then make a single call at the end using the 'libtool' # label. # _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) # ---------------------------------------- # Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL_INIT], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_INIT], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_INIT]) # _LT_CONFIG_LIBTOOL([COMMANDS]) # ------------------------------ # Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) # _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) # ----------------------------------------------------- m4_defun([_LT_CONFIG_SAVE_COMMANDS], [_LT_CONFIG_LIBTOOL([$1]) _LT_CONFIG_LIBTOOL_INIT([$2]) ]) # _LT_FORMAT_COMMENT([COMMENT]) # ----------------------------- # Add leading comment marks to the start of each line, and a trailing # full-stop to the whole comment if one is not present already. m4_define([_LT_FORMAT_COMMENT], [m4_ifval([$1], [ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) )]) ## ------------------------ ## ## FIXME: Eliminate VARNAME ## ## ------------------------ ## # _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) # ------------------------------------------------------------------- # CONFIGNAME is the name given to the value in the libtool script. # VARNAME is the (base) name used in the configure script. # VALUE may be 0, 1 or 2 for a computed quote escaped value based on # VARNAME. Any other value will be used directly. m4_define([_LT_DECL], [lt_if_append_uniq([lt_decl_varnames], [$2], [, ], [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], [m4_ifval([$1], [$1], [$2])]) lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) m4_ifval([$4], [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) lt_dict_add_subkey([lt_decl_dict], [$2], [tagged?], [m4_ifval([$5], [yes], [no])])]) ]) # _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) # -------------------------------------------------------- m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) # lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_tag_varnames], [_lt_decl_filter([tagged?], [yes], $@)]) # _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) # --------------------------------------------------------- m4_define([_lt_decl_filter], [m4_case([$#], [0], [m4_fatal([$0: too few arguments: $#])], [1], [m4_fatal([$0: too few arguments: $#: $1])], [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], [lt_dict_filter([lt_decl_dict], $@)])[]dnl ]) # lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) # -------------------------------------------------- m4_define([lt_decl_quote_varnames], [_lt_decl_filter([value], [1], $@)]) # lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_dquote_varnames], [_lt_decl_filter([value], [2], $@)]) # lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_varnames_tagged], [m4_assert([$# <= 2])dnl _$0(m4_quote(m4_default([$1], [[, ]])), m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) m4_define([_lt_decl_varnames_tagged], [m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) # lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_all_varnames], [_$0(m4_quote(m4_default([$1], [[, ]])), m4_if([$2], [], m4_quote(lt_decl_varnames), m4_quote(m4_shift($@))))[]dnl ]) m4_define([_lt_decl_all_varnames], [lt_join($@, lt_decl_varnames_tagged([$1], lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl ]) # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ # Quote a variable value, and forward it to 'config.status' so that its # declaration there will have the same value as in 'configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) # _LT_CONFIG_STATUS_DECLARATIONS # ------------------------------ # We delimit libtool config variables with single quotes, so when # we write them to config.status, we have to be sure to quote all # embedded single quotes properly. In configure, this macro expands # each variable declared with _LT_DECL (and _LT_TAGDECL) into: # # ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], [m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAGS # ---------------- # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl available_tags='_LT_TAGS'dnl ]) # _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) # ----------------------------------- # Extract the dictionary values for VARNAME (optionally with TAG) and # expand to a commented shell variable setting: # # # Some comment about what VAR is for. # visible_name=$lt_internal_name m4_define([_LT_LIBTOOL_DECLARE], [_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [description])))[]dnl m4_pushdef([_libtool_name], m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), [0], [_libtool_name=[$]$1], [1], [_libtool_name=$lt_[]$1], [2], [_libtool_name=$lt_[]$1], [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl ]) # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables # suitable for insertion in the LIBTOOL CONFIG section of the 'libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], [m4_foreach([_lt_var], m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAG_VARS(TAG) # ------------------------- m4_define([_LT_LIBTOOL_TAG_VARS], [m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) # _LT_TAGVAR(VARNAME, [TAGNAME]) # ------------------------------ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # _LT_CONFIG_COMMANDS # ------------------- # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations # into 'config.status', and then the shell code to quote escape them in # for loops in 'config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], dnl If the libtool generation code has been placed in $CONFIG_LT, dnl instead of duplicating it all over again into config.status, dnl then we will have config.status run $CONFIG_LT later, so it dnl needs to know what name is stored there: [AC_CONFIG_COMMANDS([libtool], [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], dnl If the libtool generation code is destined for config.status, dnl expand the accumulated commands and init code now: [AC_CONFIG_COMMANDS([libtool], [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) ])#_LT_CONFIG_COMMANDS # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], [ # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' _LT_CONFIG_STATUS_DECLARATIONS LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$[]1 _LTECHO_EOF' } # Quote evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done _LT_OUTPUT_LIBTOOL_INIT ]) # _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) # ------------------------------------ # Generate a child script FILE with all initialization necessary to # reuse the environment learned by the parent script, and make the # file executable. If COMMENT is supplied, it is inserted after the # '#!' sequence but before initialization text begins. After this # macro, additional text can be appended to FILE to form the body of # the child script. The macro ends with non-zero status if the # file could not be fully written (such as if the disk is full). m4_ifdef([AS_INIT_GENERATED], [m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], [m4_defun([_LT_GENERATED_FILE_INIT], [m4_require([AS_PREPARE])]dnl [m4_pushdef([AS_MESSAGE_LOG_FD])]dnl [lt_write_fail=0 cat >$1 <<_ASEOF || lt_write_fail=1 #! $SHELL # Generated by $as_me. $2 SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$1 <<\_ASEOF || lt_write_fail=1 AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 _ASEOF test 0 = "$lt_write_fail" && chmod +x $1[]dnl m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT # LT_OUTPUT # --------- # This macro allows early generation of the libtool script (before # AC_OUTPUT is called), incase it is used in configure for compilation # tests. AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} AC_MSG_NOTICE([creating $CONFIG_LT]) _LT_GENERATED_FILE_INIT(["$CONFIG_LT"], [# Run this file to recreate a libtool stub with the current configuration.]) cat >>"$CONFIG_LT" <<\_LTEOF lt_cl_silent=false exec AS_MESSAGE_LOG_FD>>config.log { echo AS_BOX([Running $as_me.]) } >&AS_MESSAGE_LOG_FD lt_cl_help="\ '$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. Usage: $[0] [[OPTIONS]] -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files Report bugs to ." lt_cl_version="\ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. Copyright (C) 2011 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." while test 0 != $[#] do case $[1] in --version | --v* | -V ) echo "$lt_cl_version"; exit 0 ;; --help | --h* | -h ) echo "$lt_cl_help"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --quiet | --q* | --silent | --s* | -q ) lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] Try '$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] Try '$[0] --help' for more information.]) ;; esac shift done if $lt_cl_silent; then exec AS_MESSAGE_FD>/dev/null fi _LTEOF cat >>"$CONFIG_LT" <<_LTEOF _LT_OUTPUT_LIBTOOL_COMMANDS_INIT _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AC_MSG_NOTICE([creating $ofile]) _LT_OUTPUT_LIBTOOL_COMMANDS AS_EXIT(0) _LTEOF chmod +x "$CONFIG_LT" # configure is writing to config.log, but config.lt does its own redirection, # appending to config.log, which fails on DOS, as config.log is still kept # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. lt_cl_success=: test yes = "$silent" && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false exec AS_MESSAGE_LOG_FD>>config.log $lt_cl_success || AS_EXIT(1) ])# LT_OUTPUT # _LT_CONFIG(TAG) # --------------- # If TAG is the built-in tag, create an initial libtool script with a # default configuration from the untagged config vars. Otherwise add code # to config.status for appending the configuration named by TAG from the # matching tagged config vars. m4_defun([_LT_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi cfgfile=${ofile}T trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. # Written by Gordon Matzigkeit, 1996 _LT_COPYING _LT_LIBTOOL_TAGS # Configured defaults for sys_lib_dlsearch_path munging. : \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG _LT_EOF cat <<'_LT_EOF' >> "$cfgfile" # ### BEGIN FUNCTIONS SHARED WITH CONFIGURE _LT_PREPARE_MUNGE_PATH_LIST _LT_PREPARE_CC_BASENAME # ### END FUNCTIONS SHARED WITH CONFIGURE _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac _LT_PROG_LTMAIN # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ], [cat <<_LT_EOF >> "$ofile" dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded dnl in a comment (ie after a #). # ### BEGIN LIBTOOL TAG CONFIG: $1 _LT_LIBTOOL_TAG_VARS(_LT_TAG) # ### END LIBTOOL TAG CONFIG: $1 _LT_EOF ])dnl /m4_if ], [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS ])# _LT_CONFIG # LT_SUPPORTED_TAG(TAG) # --------------------- # Trace this macro to discover what tags are supported by the libtool # --tag option, using: # autoconf --trace 'LT_SUPPORTED_TAG:$1' AC_DEFUN([LT_SUPPORTED_TAG], []) # C support is built-in for now m4_define([_LT_LANG_C_enabled], []) m4_define([_LT_TAGS], []) # LT_LANG(LANG) # ------------- # Enable libtool support for the given language if not already enabled. AC_DEFUN([LT_LANG], [AC_BEFORE([$0], [LT_OUTPUT])dnl m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], [Go], [_LT_LANG(GO)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], [Windows Resource], [_LT_LANG(RC)], [m4_ifdef([_LT_LANG_]$1[_CONFIG], [_LT_LANG($1)], [m4_fatal([$0: unsupported language: "$1"])])])dnl ])# LT_LANG # _LT_LANG(LANGNAME) # ------------------ m4_defun([_LT_LANG], [m4_ifdef([_LT_LANG_]$1[_enabled], [], [LT_SUPPORTED_TAG([$1])dnl m4_append([_LT_TAGS], [$1 ])dnl m4_define([_LT_LANG_]$1[_enabled], [])dnl _LT_LANG_$1_CONFIG($1)])dnl ])# _LT_LANG m4_ifndef([AC_PROG_GO], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_GO. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_GO], [AC_LANG_PUSH(Go)dnl AC_ARG_VAR([GOC], [Go compiler command])dnl AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl _AC_ARG_VAR_LDFLAGS()dnl AC_CHECK_TOOL(GOC, gccgo) if test -z "$GOC"; then if test -n "$ac_tool_prefix"; then AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) fi fi if test -z "$GOC"; then AC_CHECK_PROG(GOC, gccgo, gccgo, false) fi ])#m4_defun ])#m4_ifndef # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], [AC_PROVIDE_IFELSE([AC_PROG_CXX], [LT_LANG(CXX)], [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) AC_PROVIDE_IFELSE([AC_PROG_F77], [LT_LANG(F77)], [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) AC_PROVIDE_IFELSE([AC_PROG_FC], [LT_LANG(FC)], [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal dnl pulling things in needlessly. AC_PROVIDE_IFELSE([AC_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([LT_PROG_GCJ], [LT_LANG(GCJ)], [m4_ifdef([AC_PROG_GCJ], [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([A][M_PROG_GCJ], [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) AC_PROVIDE_IFELSE([AC_PROG_GO], [LT_LANG(GO)], [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) ])# _LT_LANG_DEFAULT_CONFIG # Obsolete macros: AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_CXX], []) dnl AC_DEFUN([AC_LIBTOOL_F77], []) dnl AC_DEFUN([AC_LIBTOOL_FC], []) dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) dnl AC_DEFUN([AC_LIBTOOL_RC], []) # _LT_TAG_COMPILER # ---------------- m4_defun([_LT_TAG_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl _LT_DECL([LTCC], [CC], [1], [A C compiler])dnl _LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl _LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl _LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC ])# _LT_TAG_COMPILER # _LT_COMPILER_BOILERPLATE # ------------------------ # Check for compiler boilerplate output or warnings with # the simple compiler test code. m4_defun([_LT_COMPILER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ])# _LT_COMPILER_BOILERPLATE # _LT_LINKER_BOILERPLATE # ---------------------- # Check for linker boilerplate output or warnings with # the simple link test code. m4_defun([_LT_LINKER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ])# _LT_LINKER_BOILERPLATE # _LT_REQUIRED_DARWIN_CHECKS # ------------------------- m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ case $host_os in rhapsody* | darwin*) AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) AC_CHECK_TOOL([LIPO], [lipo], [:]) AC_CHECK_TOOL([OTOOL], [otool], [:]) AC_CHECK_TOOL([OTOOL64], [otool64], [:]) _LT_DECL([], [DSYMUTIL], [1], [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) _LT_DECL([], [NMEDIT], [1], [Tool to change global to local symbols on Mac OS X]) _LT_DECL([], [LIPO], [1], [Tool to manipulate fat objects and archives on Mac OS X]) _LT_DECL([], [OTOOL], [1], [ldd/readelf like tool for Mach-O binaries on Mac OS X]) _LT_DECL([], [OTOOL64], [1], [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -rf libconftest.dylib* rm -f conftest.* fi]) AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) LDFLAGS=$save_LDFLAGS ]) AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], [lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM ]) case $host_os in rhapsody* | darwin1.[[012]]) _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; 10.[[012]][[,.]]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi if test yes = "$lt_cv_ld_exported_symbols_list"; then _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' fi if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ]) # _LT_DARWIN_LINKER_FEATURES([TAG]) # --------------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ m4_require([_LT_REQUIRED_DARWIN_CHECKS]) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported if test yes = "$lt_cv_ld_force_load"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) else _LT_TAGVAR(whole_archive_flag_spec, $1)='' fi _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" m4_if([$1], [CXX], [ if test yes != "$lt_cv_apple_cc_single_mod"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" fi ],[]) else _LT_TAGVAR(ld_shlibs, $1)=no fi ]) # _LT_SYS_MODULE_PATH_AIX([TAGNAME]) # ---------------------------------- # Links a minimal program and checks the executable # for the system default hardcoded library path. In most cases, # this is /usr/lib:/lib, but when the MPI compilers are used # the location of the communication and MPI libs are included too. # If we don't find anything, use the default library path according # to the aix ld manual. # Store the results from the different compilers for each TAGNAME. # Allow to override them for all tags through lt_cv_aix_libpath. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ lt_aix_libpath_sed='[ /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }]' _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib fi ]) aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) fi ])# _LT_SYS_MODULE_PATH_AIX # _LT_SHELL_INIT(ARG) # ------------------- m4_define([_LT_SHELL_INIT], [m4_divert_text([M4SH-INIT], [$1 ])])# _LT_SHELL_INIT # _LT_PROG_ECHO_BACKSLASH # ----------------------- # Find how we can fake an echo command that does not interpret backslash. # In particular, with Autoconf 2.60 or later we add some code to the start # of the generated configure script that will find a shell with a builtin # printf (that we can use as an echo command). m4_defun([_LT_PROG_ECHO_BACKSLASH], [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO AC_MSG_CHECKING([how to print strings]) # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $[]1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } case $ECHO in printf*) AC_MSG_RESULT([printf]) ;; print*) AC_MSG_RESULT([print -r]) ;; *) AC_MSG_RESULT([cat]) ;; esac m4_ifdef([_AS_DETECT_SUGGESTED], [_AS_DETECT_SUGGESTED([ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test "X`printf %s $ECHO`" = "X$ECHO" \ || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) ])# _LT_PROG_ECHO_BACKSLASH # _LT_WITH_SYSROOT # ---------------- AC_DEFUN([_LT_WITH_SYSROOT], [AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], [AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], [Search for dependent libraries within DIR (or the compiler's sysroot if not specified).])], [], [with_sysroot=no]) dnl lt_sysroot will always be passed unquoted. We quote it here dnl in case the user passed a directory name. lt_sysroot= case $with_sysroot in #( yes) if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) AC_MSG_RESULT([$with_sysroot]) AC_MSG_ERROR([The sysroot must be an absolute path.]) ;; esac AC_MSG_RESULT([${lt_sysroot:-no}]) _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl [dependent libraries, and where our libraries should be installed.])]) # _LT_ENABLE_LOCK # --------------- m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test no = "$enable_libtool_lock" || enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out what ABI is being produced by ac_compile, and set mode # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; *ELF-64*) HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test yes = "$lt_cv_prog_gnu_ld"; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; mips64*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then emul=elf case `/usr/bin/file conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; *64-bit*) emul="${emul}64" ;; esac case `/usr/bin/file conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; *LSB*) emul="${emul}ltsmip" ;; esac case `/usr/bin/file conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; esac LD="${LD-ld} -m $emul" fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. Note that the listed cases only cover the # situations where additional linker options are needed (such as when # doing 32-bit compilation for a host where ld defaults to 64-bit, or # vice versa); the common cases where no linker options are needed do # not appear in the list. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `/usr/bin/file conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*linux*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*linux*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD=${LD-ld}_sol2 fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks=$enable_libtool_lock ])# _LT_ENABLE_LOCK # _LT_PROG_AR # ----------- m4_defun([_LT_PROG_AR], [AC_CHECK_TOOLS(AR, [ar], false) : ${AR=ar} : ${AR_FLAGS=cru} _LT_DECL([], [AR], [1], [The archiver]) _LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [lt_cv_ar_at_file=no AC_COMPILE_IFELSE([AC_LANG_PROGRAM], [echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([lt_ar_try]) if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a AC_TRY_EVAL([lt_ar_try]) if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a ]) ]) if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi _LT_DECL([], [archiver_list_spec], [1], [How to feed a file listing to the archiver]) ])# _LT_PROG_AR # _LT_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], [_LT_PROG_AR AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: _LT_DECL([], [STRIP], [1], [A symbol stripping program]) AC_CHECK_TOOL(RANLIB, ranlib, :) test -z "$RANLIB" && RANLIB=: _LT_DECL([], [RANLIB], [1], [Commands used to install an old-style archive]) # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in bitrig* | openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac _LT_DECL([], [old_postinstall_cmds], [2]) _LT_DECL([], [old_postuninstall_cmds], [2]) _LT_TAGDECL([], [old_archive_cmds], [2], [Commands used to build an old-style archive]) _LT_DECL([], [lock_old_archive_extraction], [0], [Whether to use a lock for old archive extraction]) ])# _LT_CMD_OLD_ARCHIVE # _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------------------- # Check whether the given compiler option works AC_DEFUN([_LT_COMPILER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi fi $RM conftest* ]) if test yes = "[$]$2"; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) fi ])# _LT_COMPILER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) # _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------- # Check whether the given linker option works AC_DEFUN([_LT_LINKER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $3" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&AS_MESSAGE_LOG_FD $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi else $2=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS ]) if test yes = "[$]$2"; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) fi ])# _LT_LINKER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) # LT_CMD_MAX_LEN #--------------- AC_DEFUN([LT_CMD_MAX_LEN], [AC_REQUIRE([AC_CANONICAL_HOST])dnl # find the maximum length of command line arguments AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 teststring=ABCD case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test X`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test 17 != "$i" # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac ]) if test -n "$lt_cv_sys_max_cmd_len"; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) fi max_cmd_len=$lt_cv_sys_max_cmd_len _LT_DECL([], [max_cmd_len], [0], [What is the maximum length of a command?]) ])# LT_CMD_MAX_LEN # Old name: AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) # _LT_HEADER_DLFCN # ---------------- m4_defun([_LT_HEADER_DLFCN], [AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl ])# _LT_HEADER_DLFCN # _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test yes = "$cross_compiling"; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF [#line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; }] _LT_EOF if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; x$lt_dlunknown|x*) $3 ;; esac else : # compilation failed $3 fi fi rm -fr conftest* ])# _LT_TRY_DLOPEN_SELF # LT_SYS_DLOPEN_SELF # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test yes != "$enable_dlopen"; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen=load_add_on lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen=dlopen lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[ lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; tpf*) # Don't try to run any link tests for TPF. We know it's impossible # because TPF is a cross-compiler, and we know how we open DSOs. lt_cv_dlopen=dlopen lt_cv_dlopen_libs= lt_cv_dlopen_self=no ;; *) AC_CHECK_FUNC([shl_load], [lt_cv_dlopen=shl_load], [AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen=dlopen], [AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl], [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld]) ]) ]) ]) ]) ]) ;; esac if test no = "$lt_cv_dlopen"; then enable_dlopen=no else enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS=$CPPFLAGS test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS=$LDFLAGS wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS=$LIBS LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], lt_cv_dlopen_self, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ]) fi CPPFLAGS=$save_CPPFLAGS LDFLAGS=$save_LDFLAGS LIBS=$save_LIBS ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi _LT_DECL([dlopen_support], [enable_dlopen], [0], [Whether dlopen is supported]) _LT_DECL([dlopen_self], [enable_dlopen_self], [0], [Whether dlopen of programs is supported]) _LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], [Whether dlopen of statically linked programs is supported]) ])# LT_SYS_DLOPEN_SELF # Old name: AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) # _LT_COMPILER_C_O([TAGNAME]) # --------------------------- # Check to see if options -c and -o are simultaneously supported by compiler. # This macro does not hard code the compiler like AC_PROG_CC_C_O. m4_defun([_LT_COMPILER_C_O], [m4_require([_LT_DECL_SED])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi chmod u+w . 2>&AS_MESSAGE_LOG_FD $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* ]) _LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], [Does compiler simultaneously support -c and -o options?]) ])# _LT_COMPILER_C_O # _LT_COMPILER_FILE_LOCKS([TAGNAME]) # ---------------------------------- # Check to see if we can do hard links to lock some files if needed m4_defun([_LT_COMPILER_FILE_LOCKS], [m4_require([_LT_ENABLE_LOCK])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) hard_links=nottested if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) if test no = "$hard_links"; then AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe]) need_locks=warn fi else need_locks=no fi _LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) ])# _LT_COMPILER_FILE_LOCKS # _LT_CHECK_OBJDIR # ---------------- m4_defun([_LT_CHECK_OBJDIR], [AC_CACHE_CHECK([for objdir], [lt_cv_objdir], [rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null]) objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/", [Define to the sub-directory where libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR # _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) # -------------------------------------- # Check hardcoding attributes. m4_defun([_LT_LINKER_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then # We can hardcode non-existent directories. if test no != "$_LT_TAGVAR(hardcode_direct, $1)" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" && test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. _LT_TAGVAR(hardcode_action, $1)=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. _LT_TAGVAR(hardcode_action, $1)=unsupported fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) if test relink = "$_LT_TAGVAR(hardcode_action, $1)" || test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi _LT_TAGDECL([], [hardcode_action], [0], [How to hardcode a shared library path into an executable]) ])# _LT_LINKER_HARDCODE_LIBPATH # _LT_CMD_STRIPLIB # ---------------- m4_defun([_LT_CMD_STRIPLIB], [m4_require([_LT_DECL_EGREP]) striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP"; then striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) ])# _LT_CMD_STRIPLIB # _LT_PREPARE_MUNGE_PATH_LIST # --------------------------- # Make sure func_munge_path_list() is defined correctly. m4_defun([_LT_PREPARE_MUNGE_PATH_LIST], [[# func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x@S|@2 in x) ;; *:) eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\" ;; x:*) eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\" ;; *::*) eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\" ;; *) eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\" ;; esac } ]])# _LT_PREPARE_PATH_LIST # _LT_SYS_DYNAMIC_LINKER([TAG]) # ----------------------------- # PORTME Fill in your ld.so characteristics m4_defun([_LT_SYS_DYNAMIC_LINKER], [AC_REQUIRE([AC_CANONICAL_HOST])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ if test yes = "$GCC"; then case $host_os in darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;; *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary... lt_tmp_lt_search_path_spec= lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` # ...but if some path component already ends with the multilib dir we assume # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). case "$lt_multi_os_dir; $lt_search_path_spec " in "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) lt_multi_os_dir= ;; esac for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" elif test -n "$lt_multi_os_dir"; then test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS = " "; FS = "/|\n";} { lt_foo = ""; lt_count = 0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo = "/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[[lt_foo]]++; } if (lt_freq[[lt_foo]] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi]) library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown AC_ARG_VAR([LT_SYS_LIBRARY_PATH], [User-defined run-time library search path.]) case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[[4-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a[(]lib.so.V[)]' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[[45]]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[[23]].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[[01]]* | freebsdelf3.[[01]]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[[3-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], [lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], [lt_cv_shlibpath_overrides_runpath=yes])]) LDFLAGS=$save_LDFLAGS libdir=$save_libdir ]) shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac AC_MSG_RESULT([$dynamic_linker]) test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH _LT_DECL([], [variables_saved_for_relink], [1], [Variables whose values should be saved in libtool wrapper scripts and restored at link time]) _LT_DECL([], [need_lib_prefix], [0], [Do we need the "lib" prefix for modules?]) _LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) _LT_DECL([], [version_type], [0], [Library versioning type]) _LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) _LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) _LT_DECL([], [shlibpath_overrides_runpath], [0], [Is shlibpath searched before the hard-coded library search path?]) _LT_DECL([], [libname_spec], [1], [Format of library name prefix]) _LT_DECL([], [library_names_spec], [1], [[List of archive names. First name is the real one, the rest are links. The last name is the one that the linker finds with -lNAME]]) _LT_DECL([], [soname_spec], [1], [[The coded name of the library, if different from the real name]]) _LT_DECL([], [install_override_mode], [1], [Permission mode override for installation of shared libraries]) _LT_DECL([], [postinstall_cmds], [2], [Command to use after installation of a shared archive]) _LT_DECL([], [postuninstall_cmds], [2], [Command to use after uninstallation of a shared archive]) _LT_DECL([], [finish_cmds], [2], [Commands used to finish a libtool library installation in a directory]) _LT_DECL([], [finish_eval], [1], [[As "finish_cmds", except a single script fragment to be evaled but not shown]]) _LT_DECL([], [hardcode_into_libs], [0], [Whether we should hardcode library paths into libraries]) _LT_DECL([], [sys_lib_search_path_spec], [2], [Compile-time system search path for libraries]) _LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2], [Detected run-time system search path for libraries]) _LT_DECL([], [configure_time_lt_sys_library_path], [2], [Explicit LT_SYS_LIBRARY_PATH set during ./configure time]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- # find a file program that can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$1"; then lt_cv_path_MAGIC_CMD=$ac_dir/"$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac]) MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else AC_MSG_RESULT(no) fi _LT_DECL([], [MAGIC_CMD], [0], [Used to examine libraries when file_magic_cmd begins with "file"])dnl ])# _LT_PATH_TOOL_PREFIX # Old name: AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- # find a file program that can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) else MAGIC_CMD=: fi fi ])# _LT_PATH_MAGIC # LT_PATH_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([LT_PATH_LD], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PROG_ECHO_BACKSLASH])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test no = "$withval" || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &1 conftest.i cat conftest.i conftest.i >conftest2.i : ${lt_DD:=$DD} AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd], [if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: fi]) rm -f conftest.i conftest2.i conftest.out]) ])# _LT_PATH_DD # _LT_CMD_TRUNCATE # ---------------- # find command to truncate a binary pipe m4_defun([_LT_CMD_TRUNCATE], [m4_require([_LT_PATH_DD]) AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin], [printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i lt_cv_truncate_bin= if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" fi rm -f conftest.i conftest2.i conftest.out test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"]) _LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1], [Command to truncate a binary pipe]) ])# _LT_CMD_TRUNCATE # _LT_CHECK_MAGIC_METHOD # ---------------------- # how to check for library dependencies # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_MAGIC_METHOD], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) AC_CACHE_CHECK([how to recognize dependent libraries], lt_cv_deplibs_check_method, [lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # that responds to the $file_magic_cmd with a given extended regex. # If you have 'file' or equivalent on your system and you're not sure # whether 'pass_all' will *always* work, you probably want this one. case $host_os in aix[[4-9]]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[[45]]*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[[3-9]]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd* | bitrig*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; os2*) lt_cv_deplibs_check_method=pass_all ;; esac ]) file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown _LT_DECL([], [deplibs_check_method], [1], [Method to check whether dependent libraries are shared objects]) _LT_DECL([], [file_magic_cmd], [1], [Command to use when deplibs_check_method = "file_magic"]) _LT_DECL([], [file_magic_glob], [1], [How to find potential files when deplibs_check_method = "file_magic"]) _LT_DECL([], [want_nocaseglob], [1], [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) ])# _LT_CHECK_MAGIC_METHOD # LT_PATH_NM # ---------- # find the pathname to a BSD- or MS-compatible name lister AC_DEFUN([LT_PATH_NM], [AC_REQUIRE([AC_PROG_CC])dnl AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM=$NM else lt_nm_to_check=${ac_tool_prefix}nm if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. tmp_nm=$ac_dir/$lt_tmp_nm if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then # Check to see if the nm accepts a BSD-compat flag. # Adding the 'sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty case $build_os in mingw*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} fi]) if test no != "$lt_cv_path_NM"; then NM=$lt_cv_path_NM else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: ;; esac fi AC_SUBST([DUMPBIN]) if test : != "$DUMPBIN"; then NM=$DUMPBIN fi fi test -z "$NM" && NM=nm AC_SUBST([NM]) _LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], [lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) cat conftest.out >&AS_MESSAGE_LOG_FD if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest*]) ])# LT_PATH_NM # Old names: AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_PROG_NM], []) dnl AC_DEFUN([AC_PROG_NM], []) # _LT_CHECK_SHAREDLIB_FROM_LINKLIB # -------------------------------- # how to determine the name of the shared library # associated with a specific link library. # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) m4_require([_LT_DECL_DLLTOOL]) AC_CACHE_CHECK([how to associate runtime and link libraries], lt_cv_sharedlib_from_linklib_cmd, [lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh; # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac ]) sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO _LT_DECL([], [sharedlib_from_linklib_cmd], [1], [Command to associate shared and link libraries]) ])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB # _LT_PATH_MANIFEST_TOOL # ---------------------- # locate the manifest tool m4_defun([_LT_PATH_MANIFEST_TOOL], [AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], [lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&AS_MESSAGE_LOG_FD if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest*]) if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl ])# _LT_PATH_MANIFEST_TOOL # _LT_DLL_DEF_P([FILE]) # --------------------- # True iff FILE is a Windows DLL '.def' file. # Keep in sync with func_dll_def_p in the libtool script AC_DEFUN([_LT_DLL_DEF_P], [dnl test DEF = "`$SED -n dnl -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl -e q dnl Only consider the first "real" line $1`" dnl ])# _LT_DLL_DEF_P # LT_LIB_M # -------- # check for math library AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw) AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) AC_CHECK_LIB(m, cos, LIBM=-lm) ;; esac AC_SUBST([LIBM]) ])# LT_LIB_M # Old name: AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_CHECK_LIBM], []) # _LT_COMPILER_NO_RTTI([TAGNAME]) # ------------------------------- m4_defun([_LT_COMPILER_NO_RTTI], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= if test yes = "$GCC"; then case $cc_basename in nvcc*) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; *) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; esac _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], lt_cv_prog_compiler_rtti_exceptions, [-fno-rtti -fno-exceptions], [], [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) fi _LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], [Compiler flag to turn off builtin functions]) ])# _LT_COMPILER_NO_RTTI # _LT_CMD_GLOBAL_SYMBOLS # ---------------------- m4_defun([_LT_CMD_GLOBAL_SYMBOLS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([LT_PATH_NM])dnl AC_REQUIRE([LT_PATH_LD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_TAG_COMPILER])dnl # Check for command to grab the raw symbol name followed by C symbol from nm. AC_MSG_CHECKING([command to parse $NM output from $compiler object]) AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [ # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[[BCDEGRST]]' # Regexp to match symbols that can be accessed directly from C. sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[[BCDT]]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) if test ia64 = "$host_cpu"; then symcode='[[ABCDEGRST]]' fi ;; irix* | nonstopux*) symcode='[[BCDEGRST]]' ;; osf*) symcode='[[BCDEGQRST]]' ;; solaris*) symcode='[[BDRT]]' ;; sco3.2v5*) symcode='[[DT]]' ;; sysv4.2uw2*) symcode='[[DT]]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[[ABDT]]' ;; sysv4) symcode='[[DFNSTU]]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[[ABCDGIRSTW]]' ;; esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" lt_c_name_lib_hook="\ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" else # Disable hooks by default. lt_cv_sys_global_symbol_to_import= lt_cdecl_hook= lt_c_name_hook= lt_c_name_lib_hook= fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ " /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ " /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ " {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ " s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT@&t@_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT@&t@_DLSYM_CONST #else # define LT@&t@_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT@&t@_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= fi done ]) if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then AC_MSG_RESULT(failed) else AC_MSG_RESULT(ok) fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then nm_file_list_spec='@' fi _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) _LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1], [Transform the output of nm into a list of symbols to manually relocate]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) _LT_DECL([nm_interface], [lt_cv_nm_interface], [1], [The name lister interface]) _LT_DECL([], [nm_file_list_spec], [1], [Specify filename containing input files for $NM]) ]) # _LT_CMD_GLOBAL_SYMBOLS # _LT_COMPILER_PIC([TAGNAME]) # --------------------------- m4_defun([_LT_COMPILER_PIC], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_wl, $1)= _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)= m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else case $host_os in aix[[4-9]]*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; dgux*) case $cc_basename in ec++*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; ghcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' if test ia64 != "$host_cpu"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # KAI C++ Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64, which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL 8.0, 9.0 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; cxx*) # Digital/Compaq C++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; lcc*) # Lucid _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ], [ if test yes = "$GCC"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' case $cc_basename in nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; hpux9* | hpux10* | hpux11*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC (with -KPIC) is the default. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64, which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # Lahey Fortran 8.1. lf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ;; nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; tcc*) # Fabrice Bellard et al's Tiny C Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; ccc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; *Sun\ F* | *Sun*Fortran*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; *Intel*\ [[CF]]*Compiler*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; *Portland\ Group*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; esac ;; newsos6) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All OSF/1 code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; rdos*) _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; solaris*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; *) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; esac ;; sunos4*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; unicos*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; uts4*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ]) case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ;; esac AC_CACHE_CHECK([for $compiler option to produce PIC], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) _LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) # # Check to make sure the PIC flag actually works. # if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], [Additional compiler flags for building library objects]) _LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], [How to pass a linker flag through the compiler]) # # Check to make sure the static flag actually works. # wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), $lt_tmp_static_flag, [], [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], [Compiler flag to prevent dynamic linking]) ])# _LT_COMPILER_PIC # _LT_LINKER_SHLIBS([TAGNAME]) # ---------------------------- # See if the linker supports building shared libraries. m4_defun([_LT_LINKER_SHLIBS], [AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) m4_if([$1], [CXX], [ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] case $host_os in aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl*) _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] ;; esac ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac ], [ runpath_var= _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_cmds, $1)= _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(old_archive_from_new_cmds, $1)= _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= _LT_TAGVAR(thread_safe_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ' (' and ')$', so one must not match beginning or # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', # as well as any symbol that contains 'd'. _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd* | bitrig*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test yes = "$with_gnu_ld"; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test yes = "$lt_use_gnu_ld_interface"; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='$wl' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken if test ia64 != "$host_cpu"; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test linux-dietlibc = "$host_os"; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; nagfor*) # NAGFOR 5.3 tmp_sharedflag='-Wl,-shared' ;; xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in tcc*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; sunos4*) _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_TAGVAR(hardcode_minus_L, $1)=yes if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported fi ;; aix[[4-9]]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # traditional, no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no ;; esac if test yes = "$GCC"; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi ;; esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag="$shared_flag "'$wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; bsdi[[45]]*) _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; hpux9*) if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; hpux10*) if test yes,no = "$GCC,$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes fi ;; hpux11*) if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) m4_if($1, [], [ # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) _LT_LINKER_OPTION([if $CC understands -b], _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) ;; esac fi if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], [lt_cv_irix_exported_symbol], [save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" AC_LINK_IFELSE( [AC_LANG_SOURCE( [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], [C++], [[int foo (void) { return 0; }]], [Fortran 77], [[ subroutine foo end]], [Fortran], [[ subroutine foo end]])])], [lt_cv_irix_exported_symbol=yes], [lt_cv_irix_exported_symbol=no]) LDFLAGS=$save_LDFLAGS]) if test yes = "$lt_cv_irix_exported_symbol"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi _LT_TAGVAR(link_all_deplibs, $1)=no else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes ;; linux*) case $cc_basename in tcc*) # Fabrice Bellard et al's Tiny C Compiler _LT_TAGVAR(ld_shlibs, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *nto* | *qnx*) ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' fi else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; osf3*) if test yes = "$GCC"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test yes = "$GCC"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test yes = "$GCC"; then wlarc='$wl' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='$wl' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. GCC discards it without '$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test yes = "$GCC"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes ;; sunos4*) if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4) case $host_vendor in sni) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' _LT_TAGVAR(hardcode_direct, $1)=no ;; motorola) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4.3*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes _LT_TAGVAR(ld_shlibs, $1)=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(ld_shlibs, $1)=no ;; esac if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld _LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl _LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl _LT_DECL([], [extract_expsyms_cmds], [2], [The commands to extract the exported symbol list from a shared archive]) # # Do we need to explicitly link libc? # case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes if test yes,yes = "$GCC,$enable_shared"; then case $_LT_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. AC_CACHE_CHECK([whether -lc should be explicitly linked in], [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), [$RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if AC_TRY_EVAL(ac_compile) 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) _LT_TAGVAR(allow_undefined_flag, $1)= if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) then lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no else lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes fi _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* ]) _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) ;; esac fi ;; esac _LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], [Whether or not to add -lc for building shared libraries]) _LT_TAGDECL([allow_libtool_libs_with_static_runtimes], [enable_shared_with_static_runtimes], [0], [Whether or not to disallow shared libs when runtime libs are static]) _LT_TAGDECL([], [export_dynamic_flag_spec], [1], [Compiler flag to allow reflexive dlopens]) _LT_TAGDECL([], [whole_archive_flag_spec], [1], [Compiler flag to generate shared objects directly from archives]) _LT_TAGDECL([], [compiler_needs_object], [1], [Whether the compiler copes with passing no objects directly]) _LT_TAGDECL([], [old_archive_from_new_cmds], [2], [Create an old-style archive from a shared archive]) _LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], [Create a temporary old-style archive to link instead of a shared archive]) _LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) _LT_TAGDECL([], [archive_expsym_cmds], [2]) _LT_TAGDECL([], [module_cmds], [2], [Commands used to build a loadable module if different from building a shared archive.]) _LT_TAGDECL([], [module_expsym_cmds], [2]) _LT_TAGDECL([], [with_gnu_ld], [1], [Whether we are building with GNU ld or not]) _LT_TAGDECL([], [allow_undefined_flag], [1], [Flag that allows shared libraries with undefined symbols to be built]) _LT_TAGDECL([], [no_undefined_flag], [1], [Flag that enforces no undefined symbols]) _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary and the resulting library dependency is "absolute", i.e impossible to change by setting $shlibpath_var if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_shlibpath_var], [0], [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_automatic], [0], [Set to "yes" if building a shared library automatically hardcodes DIR into the library and all subsequent libraries and executables linked against it]) _LT_TAGDECL([], [inherit_rpath], [0], [Set to yes if linker adds runtime paths of dependent libraries to runtime path list]) _LT_TAGDECL([], [link_all_deplibs], [0], [Whether libtool must link a program against all its dependency libraries]) _LT_TAGDECL([], [always_export_symbols], [0], [Set to "yes" if exported symbols are required]) _LT_TAGDECL([], [export_symbols_cmds], [2], [The commands to list exported symbols]) _LT_TAGDECL([], [exclude_expsyms], [1], [Symbols that should not be listed in the preloaded symbols]) _LT_TAGDECL([], [include_expsyms], [1], [Symbols that must always be exported]) _LT_TAGDECL([], [prelink_cmds], [2], [Commands necessary for linking programs (against libraries) with templates]) _LT_TAGDECL([], [postlink_cmds], [2], [Commands necessary for finishing linking programs]) _LT_TAGDECL([], [file_list_spec], [1], [Specify filename containing input files]) dnl FIXME: Not yet implemented dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], dnl [Compiler flag to generate thread safe objects]) ])# _LT_LINKER_SHLIBS # _LT_LANG_C_CONFIG([TAG]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to 'libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl lt_save_CC=$CC AC_LANG_PUSH(C) # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' _LT_TAG_COMPILER # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB # Report what library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP CC=$lt_save_CC ])# _LT_LANG_C_CONFIG # _LT_LANG_CXX_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to 'libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl if test -n "$CXX" && ( test no != "$CXX" && ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || (test g++ != "$CXX"))); then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes fi AC_LANG_PUSH(C++) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_caught_CXX_error"; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi if test yes = "$GXX"; then # Set up default GNU C++ configuration LT_PATH_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test yes = "$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='$wl' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) _LT_TAGVAR(ld_shlibs, $1)=yes case $host_os in aix3*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no ;; esac if test yes = "$GXX"; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag=$shared_flag' $wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_TAGVAR(always_export_symbols, $1)=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. # The "-G" linker flag allows undefined symbols. _LT_TAGVAR(no_undefined_flag, $1)='-bernotok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl*) # Native MSVC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ func_to_tool_file "$lt_outputfile"~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; hpux9*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; hpux10*|hpux11*) if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ;; cxx*) # Compaq C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; m88k*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) _LT_TAGVAR(ld_shlibs, $1)=yes ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; cxx*) case $host in osf3*) _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ $RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes,no = "$GXX,$with_gnu_ld"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' case $host in osf3*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test yes,no = "$GXX,$with_gnu_ld"; then _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ '"$_LT_TAGVAR(old_archive_cmds, $1)" _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ '"$_LT_TAGVAR(reload_cmds, $1)" ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no _LT_TAGVAR(GCC, $1)=$GXX _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test yes != "$_lt_caught_CXX_error" AC_LANG_POP ])# _LT_LANG_CXX_CONFIG # _LT_FUNC_STRIPNAME_CNF # ---------------------- # func_stripname_cnf prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # # This function is identical to the (non-XSI) version of func_stripname, # except this one can be used by m4 code that may be executed by configure, # rather than the libtool script. m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl AC_REQUIRE([_LT_DECL_SED]) AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) func_stripname_cnf () { case @S|@2 in .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;; *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;; esac } # func_stripname_cnf ])# _LT_FUNC_STRIPNAME_CNF # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. m4_defun([_LT_SYS_HIDDEN_LIBDEPS], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl # Dependencies to place before and after the object being linked: _LT_TAGVAR(predep_objects, $1)= _LT_TAGVAR(postdep_objects, $1)= _LT_TAGVAR(predeps, $1)= _LT_TAGVAR(postdeps, $1)= _LT_TAGVAR(compiler_lib_search_path, $1)= dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each dnl tag define a new lt_????_link_test_code variable, dnl but it's only used here... m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF int a; void foo (void) { a = 0; } _LT_EOF ], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF ], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer*4 a a=0 return end _LT_EOF ], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer a a=0 return end _LT_EOF ], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF public class foo { private int a; public void bar (void) { a = 0; } }; _LT_EOF ], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF package foo func foo() { } _LT_EOF ]) _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac dnl Parse the compiler output and extract the necessary dnl objects, libraries and library flags. if AC_TRY_EVAL(ac_compile); then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case $prev$p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test x-L = "$p" || test x-R = "$p"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test no = "$pre_test_object_deps_done"; then case $prev in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p else _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then _LT_TAGVAR(postdeps, $1)=$prev$p else _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test no = "$pre_test_object_deps_done"; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then _LT_TAGVAR(predep_objects, $1)=$p else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then _LT_TAGVAR(postdep_objects, $1)=$p else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling $1 test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken m4_if([$1], [CXX], [case $host_os in interix[[3-9]]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. _LT_TAGVAR(predep_objects,$1)= _LT_TAGVAR(postdep_objects,$1)= _LT_TAGVAR(postdeps,$1)= ;; esac ]) case " $_LT_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) _LT_TAGDECL([], [predep_objects], [1], [Dependencies to place before and after the objects being linked to create a shared library]) _LT_TAGDECL([], [postdep_objects], [1]) _LT_TAGDECL([], [predeps], [1]) _LT_TAGDECL([], [postdeps], [1]) _LT_TAGDECL([], [compiler_lib_search_path], [1], [The library search path used internally by the compiler when linking a shared library]) ])# _LT_SYS_HIDDEN_LIBDEPS # _LT_LANG_F77_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_LANG_PUSH(Fortran 77) if test -z "$F77" || test no = "$F77"; then _lt_disable_F77=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for f77 test sources. ac_ext=f # Object file extension for compiled f77 test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_disable_F77"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${F77-"f77"} CFLAGS=$FFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) GCC=$G77 if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)=$G77 _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test yes != "$_lt_disable_F77" AC_LANG_POP ])# _LT_LANG_F77_CONFIG # _LT_LANG_FC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_LANG_PUSH(Fortran) if test -z "$FC" || test no = "$FC"; then _lt_disable_FC=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for fc test sources. ac_ext=${ac_fc_srcext-f} # Object file extension for compiled fc test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_disable_FC"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${FC-"f95"} CFLAGS=$FCFLAGS compiler=$CC GCC=$ac_cv_fc_compiler_gnu _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test yes != "$_lt_disable_FC" AC_LANG_POP ])# _LT_LANG_FC_CONFIG # _LT_LANG_GCJ_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE # Source file extension for Java test sources. ac_ext=java # Object file extension for compiled Java test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} CFLAGS=$GCJFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GCJ_CONFIG # _LT_LANG_GO_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Go compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GO_CONFIG], [AC_REQUIRE([LT_PROG_GO])dnl AC_LANG_SAVE # Source file extension for Go test sources. ac_ext=go # Object file extension for compiled Go test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="package main; func main() { }" # Code to be used in simple link tests lt_simple_link_test_code='package main; func main() { }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GOC-"gccgo"} CFLAGS=$GOFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # Go did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GO_CONFIG # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code=$lt_simple_compile_test_code # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC= CC=${RC-"windres"} CFLAGS= compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes if test -n "$compiler"; then : _LT_CONFIG($1) fi GCC=$lt_save_GCC AC_LANG_RESTORE CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_RC_CONFIG # LT_PROG_GCJ # ----------- AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) # Old name: AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) # LT_PROG_GO # ---------- AC_DEFUN([LT_PROG_GO], [AC_CHECK_TOOL(GOC, gccgo,) ]) # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) ]) # Old name: AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_RC], []) # _LT_DECL_EGREP # -------------- # If we don't have a new enough Autoconf to choose the best grep # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_EGREP], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_REQUIRE([AC_PROG_FGREP])dnl test -z "$GREP" && GREP=grep _LT_DECL([], [GREP], [1], [A grep program that handles long lines]) _LT_DECL([], [EGREP], [1], [An ERE matcher]) _LT_DECL([], [FGREP], [1], [A literal string matcher]) dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too AC_SUBST([GREP]) ]) # _LT_DECL_OBJDUMP # -------------- # If we don't have a new enough Autoconf to choose the best objdump # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_OBJDUMP], [AC_CHECK_TOOL(OBJDUMP, objdump, false) test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) AC_SUBST([OBJDUMP]) ]) # _LT_DECL_DLLTOOL # ---------------- # Ensure DLLTOOL variable is set. m4_defun([_LT_DECL_DLLTOOL], [AC_CHECK_TOOL(DLLTOOL, dlltool, false) test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program]) AC_SUBST([DLLTOOL]) ]) # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates # as few characters as possible. Prefer GNU sed if found. m4_defun([_LT_DECL_SED], [AC_PROG_SED test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" _LT_DECL([], [SED], [1], [A sed program that does not truncate output]) _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ])# _LT_DECL_SED m4_ifndef([AC_PROG_SED], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_SED. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_SED], [AC_MSG_CHECKING([for a sed that does not truncate output]) AC_CACHE_VAL(lt_cv_path_SED, [# Loop through the user's path and test for sed and gsed. # Then use that list of sed's as ones to test for truncation. as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do test ! -f "$lt_ac_sed" && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in # Check for GNU sed and select it if it is found. if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then lt_cv_path_SED=$lt_ac_sed break fi while true; do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough test 10 -lt "$lt_ac_count" && break lt_ac_count=`expr $lt_ac_count + 1` if test "$lt_ac_count" -gt "$lt_ac_max"; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi done done ]) SED=$lt_cv_path_SED AC_SUBST([SED]) AC_MSG_RESULT([$SED]) ])#AC_PROG_SED ])#m4_ifndef # Old name: AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_SED], []) # _LT_CHECK_SHELL_FEATURES # ------------------------ # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], [if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi _LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac _LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES # _LT_PATH_CONVERSION_FUNCTIONS # ----------------------------- # Determine what file name conversion functions should be used by # func_to_host_file (and, implicitly, by func_to_host_path). These are needed # for certain cross-compile configurations and native mingw. m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_MSG_CHECKING([how to convert $build file names to $host format]) AC_CACHE_VAL(lt_cv_to_host_file_cmd, [case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac ]) to_host_file_cmd=$lt_cv_to_host_file_cmd AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) _LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], [0], [convert $build file names to $host format])dnl AC_MSG_CHECKING([how to convert $build file names to toolchain format]) AC_CACHE_VAL(lt_cv_to_tool_file_cmd, [#assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac ]) to_tool_file_cmd=$lt_cv_to_tool_file_cmd AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) _LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], [0], [convert $build files to toolchain format])dnl ])# _LT_PATH_CONVERSION_FUNCTIONS libopenmpt-0.3.6+release.autotools/m4/ax_cxx_compile_stdcxx_11.m40000644000372100037210000000321213041743640021740 00000000000000# ============================================================================ # http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html # ============================================================================ # # SYNOPSIS # # AX_CXX_COMPILE_STDCXX_11([ext|noext], [mandatory|optional]) # # DESCRIPTION # # Check for baseline language coverage in the compiler for the C++11 # standard; if necessary, add switches to CXX and CXXCPP to enable # support. # # This macro is a convenience alias for calling the AX_CXX_COMPILE_STDCXX # macro with the version set to C++11. The two optional arguments are # forwarded literally as the second and third argument respectively. # Please see the documentation for the AX_CXX_COMPILE_STDCXX macro for # more information. If you want to use this macro, you also need to # download the ax_cxx_compile_stdcxx.m4 file. # # LICENSE # # Copyright (c) 2008 Benjamin Kosnik # Copyright (c) 2012 Zack Weinberg # Copyright (c) 2013 Roy Stogner # Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov # Copyright (c) 2015 Paul Norman # Copyright (c) 2015 Moritz Klammler # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 17 AX_REQUIRE_DEFINED([AX_CXX_COMPILE_STDCXX]) AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [AX_CXX_COMPILE_STDCXX([11], [$1], [$2])]) libopenmpt-0.3.6+release.autotools/m4/ax_cflags_warn_all.m40000644000372100037210000001170113235362213020646 00000000000000# =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_cflags_warn_all.html # =========================================================================== # # SYNOPSIS # # AX_CFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])] # AX_CXXFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])] # AX_FCFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])] # # DESCRIPTION # # Try to find a compiler option that enables most reasonable warnings. # # For the GNU compiler it will be -Wall (and -ansi -pedantic) The result # is added to the shellvar being CFLAGS, CXXFLAGS, or FCFLAGS by default. # # Currently this macro knows about the GCC, Solaris, Digital Unix, AIX, # HP-UX, IRIX, NEC SX-5 (Super-UX 10), Cray J90 (Unicos 10.0.0.8), and # Intel compilers. For a given compiler, the Fortran flags are much more # experimental than their C equivalents. # # - $1 shell-variable-to-add-to : CFLAGS, CXXFLAGS, or FCFLAGS # - $2 add-value-if-not-found : nothing # - $3 action-if-found : add value to shellvariable # - $4 action-if-not-found : nothing # # NOTE: These macros depend on AX_APPEND_FLAG. # # LICENSE # # Copyright (c) 2008 Guido U. Draheim # Copyright (c) 2010 Rhys Ulerich # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; either version 3 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 15 AC_DEFUN([AX_FLAGS_WARN_ALL],[dnl AS_VAR_PUSHDEF([FLAGS],[_AC_LANG_PREFIX[]FLAGS])dnl AS_VAR_PUSHDEF([VAR],[ac_cv_[]_AC_LANG_ABBREV[]flags_warn_all])dnl AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for maximum warnings], VAR,[VAR="no, unknown" ac_save_[]FLAGS="$[]FLAGS" for ac_arg dnl in "-warn all % -warn all" dnl Intel "-pedantic % -Wall" dnl GCC "-xstrconst % -v" dnl Solaris C "-std1 % -verbose -w0 -warnprotos" dnl Digital Unix "-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" dnl AIX "-ansi -ansiE % -fullwarn" dnl IRIX "+ESlit % +w1" dnl HP-UX C "-Xc % -pvctl[,]fullmsg" dnl NEC SX-5 (Super-UX 10) "-h conform % -h msglevel 2" dnl Cray C (Unicos) # do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` AC_COMPILE_IFELSE([AC_LANG_PROGRAM], [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) done FLAGS="$ac_save_[]FLAGS" ]) AS_VAR_POPDEF([FLAGS])dnl AX_REQUIRE_DEFINED([AX_APPEND_FLAG]) case ".$VAR" in .ok|.ok,*) m4_ifvaln($3,$3) ;; .|.no|.no,*) m4_default($4,[m4_ifval($2,[AX_APPEND_FLAG([$2], [$1])])]) ;; *) m4_default($3,[AX_APPEND_FLAG([$VAR], [$1])]) ;; esac AS_VAR_POPDEF([VAR])dnl ])dnl AX_FLAGS_WARN_ALL dnl implementation tactics: dnl the for-argument contains a list of options. The first part of dnl these does only exist to detect the compiler - usually it is dnl a global option to enable -ansi or -extrawarnings. All other dnl compilers will fail about it. That was needed since a lot of dnl compilers will give false positives for some option-syntax dnl like -Woption or -Xoption as they think of it is a pass-through dnl to later compile stages or something. The "%" is used as a dnl delimiter. A non-option comment can be given after "%%" marks dnl which will be shown but not added to the respective C/CXXFLAGS. AC_DEFUN([AX_CFLAGS_WARN_ALL],[dnl AC_LANG_PUSH([C]) AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4]) AC_LANG_POP([C]) ]) AC_DEFUN([AX_CXXFLAGS_WARN_ALL],[dnl AC_LANG_PUSH([C++]) AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4]) AC_LANG_POP([C++]) ]) AC_DEFUN([AX_FCFLAGS_WARN_ALL],[dnl AC_LANG_PUSH([Fortran]) AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4]) AC_LANG_POP([Fortran]) ]) libopenmpt-0.3.6+release.autotools/m4/ltoptions.m40000644000372100037210000003426213235362213017102 00000000000000# Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software # Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 8 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option '$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl 'shared' nor 'disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4], [_LT_WITH_AIX_SONAME([aix])]) ]) ])# _LT_SET_OPTIONS ## --------------------------------- ## ## Macros to handle LT_INIT options. ## ## --------------------------------- ## # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [1], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the 'shared' and # 'disable-shared' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS=$lt_save_ifs ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the 'static' and # 'disable-static' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS=$lt_save_ifs ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the 'fast-install' # and 'disable-fast-install' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS=$lt_save_ifs ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_AIX_SONAME([DEFAULT]) # ---------------------------------- # implement the --with-aix-soname flag, and support the `aix-soname=aix' # and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT # is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. m4_define([_LT_WITH_AIX_SONAME], [m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[[5-9]]*,yes) AC_MSG_CHECKING([which variant of shared library versioning to provide]) AC_ARG_WITH([aix-soname], [AS_HELP_STRING([--with-aix-soname=aix|svr4|both], [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], [case $withval in aix|svr4|both) ;; *) AC_MSG_ERROR([Unknown argument to --with-aix-soname]) ;; esac lt_cv_with_aix_soname=$with_aix_soname], [AC_CACHE_VAL([lt_cv_with_aix_soname], [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) with_aix_soname=$lt_cv_with_aix_soname]) AC_MSG_RESULT([$with_aix_soname]) if test aix != "$with_aix_soname"; then # For the AIX way of multilib, we name the shared archive member # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, # the AIX toolchain works better with OBJECT_MODE set (default 32). if test 64 = "${OBJECT_MODE-32}"; then shared_archive_member_spec=shr_64 else shared_archive_member_spec=shr fi fi ;; *) with_aix_soname=aix ;; esac _LT_DECL([], [shared_archive_member_spec], [0], [Shared archive member basename, for filename based shared library versioning on AIX])dnl ])# _LT_WITH_AIX_SONAME LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])]) LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])]) LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --with-pic flag, and support the 'pic-only' and 'no-pic' # LT_INIT options. # MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS=$lt_save_ifs ;; esac], [pic_mode=m4_default([$1], [default])]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) ## ----------------- ## ## LTDL_INIT Options ## ## ----------------- ## m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) libopenmpt-0.3.6+release.autotools/examples/0000755000372100037210000000000013235362226016160 500000000000000libopenmpt-0.3.6+release.autotools/examples/libopenmpt_example_c_mem.c0000644000372100037210000001500013051352114023253 00000000000000/* * libopenmpt_example_c_mem.c * -------------------------- * Purpose: libopenmpt C API example * Notes : PortAudio is used for sound output. * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ /* * Usage: libopenmpt_example_c_mem SOMEMODULE */ #include #include #include #include #include #include #include #define BUFFERSIZE 480 #define SAMPLERATE 48000 static int16_t left[BUFFERSIZE]; static int16_t right[BUFFERSIZE]; static int16_t * const buffers[2] = { left, right }; static void libopenmpt_example_logfunc( const char * message, void * userdata ) { (void)userdata; if ( message ) { fprintf( stderr, "openmpt: %s\n", message ); } } static int libopenmpt_example_errfunc( int error, void * userdata ) { (void)userdata; (void)error; return OPENMPT_ERROR_FUNC_RESULT_DEFAULT & ~OPENMPT_ERROR_FUNC_RESULT_LOG; } static void libopenmpt_example_print_error( const char * func_name, int mod_err, const char * mod_err_str ) { if ( !func_name ) { func_name = "unknown function"; } if ( mod_err == OPENMPT_ERROR_OUT_OF_MEMORY ) { mod_err_str = openmpt_error_string( mod_err ); if ( !mod_err_str ) { fprintf( stderr, "Error: %s\n", "OPENMPT_ERROR_OUT_OF_MEMORY" ); } else { fprintf( stderr, "Error: %s\n", mod_err_str ); openmpt_free_string( mod_err_str ); mod_err_str = NULL; } } else { if ( !mod_err_str ) { mod_err_str = openmpt_error_string( mod_err ); if ( !mod_err_str ) { fprintf( stderr, "Error: %s failed.\n", func_name ); } else { fprintf( stderr, "Error: %s failed: %s\n", func_name, mod_err_str ); } openmpt_free_string( mod_err_str ); mod_err_str = NULL; } fprintf( stderr, "Error: %s failed: %s\n", func_name, mod_err_str ); } } typedef struct blob_t { size_t size; void * data; } blob_t; static void free_blob( blob_t * blob ) { if ( blob ) { if ( blob->data ) { free( blob->data ); blob->data = 0; } blob->size = 0; free( blob ); } } #if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) ) static blob_t * load_file( const wchar_t * filename ) { #else static blob_t * load_file( const char * filename ) { #endif blob_t * result = 0; blob_t * blob = 0; FILE * file = 0; long tell_result = 0; blob = malloc( sizeof( blob_t ) ); if ( !blob ) { goto fail; } memset( blob, 0, sizeof( blob_t ) ); #if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) ) file = _wfopen( filename, L"rb" ); #else file = fopen( filename, "rb" ); #endif if ( !file ) { goto fail; } if ( fseek( file, 0, SEEK_END ) != 0 ) { goto fail; } tell_result = ftell( file ); if ( tell_result < 0 ) { goto fail; } if ( (unsigned long)tell_result > SIZE_MAX ) { goto fail; } blob->size = (size_t)tell_result; if ( fseek( file, 0, SEEK_SET ) != 0 ) { goto fail; } blob->data = malloc( blob->size ); if ( !blob->data ) { goto fail; } memset( blob->data, 0, blob->size ); if ( fread( blob->data, 1, blob->size, file ) != blob->size ) { goto fail; } result = blob; blob = 0; goto cleanup; fail: result = 0; cleanup: if ( blob ) { free_blob( blob ); blob = 0; } if ( file ) { fclose( file ); file = 0; } return result; } #if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) ) int wmain( int argc, wchar_t * argv[] ) { #else int main( int argc, char * argv[] ) { #endif int result = 0; blob_t * blob = 0; openmpt_module * mod = 0; int mod_err = OPENMPT_ERROR_OK; const char * mod_err_str = NULL; size_t count = 0; PaError pa_error = paNoError; int pa_initialized = 0; PaStream * stream = 0; if ( argc != 2 ) { fprintf( stderr, "Error: %s\n", "Wrong invocation. Use 'libopenmpt_example_c_mem SOMEMODULE'." ); goto fail; } #if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) ) if ( wcslen( argv[1] ) == 0 ) { fprintf( stderr, "Error: %s\n", "Wrong invocation. Use 'libopenmpt_example_c_mem SOMEMODULE'." ); goto fail; } #else if ( strlen( argv[1] ) == 0 ) { fprintf( stderr, "Error: %s\n", "Wrong invocation. Use 'libopenmpt_example_c_mem SOMEMODULE'." ); goto fail; } #endif blob = load_file( argv[1] ); if ( !blob ) { fprintf( stderr, "Error: %s\n", "load_file() failed." ); goto fail; } mod = openmpt_module_create_from_memory2( blob->data, blob->size, &libopenmpt_example_logfunc, NULL, &libopenmpt_example_errfunc, NULL, &mod_err, &mod_err_str, NULL ); if ( !mod ) { libopenmpt_example_print_error( "openmpt_module_create_from_memory2()", mod_err, mod_err_str ); openmpt_free_string( mod_err_str ); mod_err_str = NULL; goto fail; } pa_error = Pa_Initialize(); if ( pa_error != paNoError ) { fprintf( stderr, "Error: %s\n", "Pa_Initialize() failed." ); goto fail; } pa_initialized = 1; pa_error = Pa_OpenDefaultStream( &stream, 0, 2, paInt16 | paNonInterleaved, SAMPLERATE, paFramesPerBufferUnspecified, NULL, NULL ); if ( pa_error != paNoError ) { fprintf( stderr, "Error: %s\n", "Pa_OpenStream() failed." ); goto fail; } if ( !stream ) { fprintf( stderr, "Error: %s\n", "Pa_OpenStream() failed." ); goto fail; } pa_error = Pa_StartStream( stream ); if ( pa_error != paNoError ) { fprintf( stderr, "Error: %s\n", "Pa_StartStream() failed." ); goto fail; } while ( 1 ) { openmpt_module_error_clear( mod ); count = openmpt_module_read_stereo( mod, SAMPLERATE, BUFFERSIZE, left, right ); mod_err = openmpt_module_error_get_last( mod ); mod_err_str = openmpt_module_error_get_last_message( mod ); if ( mod_err != OPENMPT_ERROR_OK ) { libopenmpt_example_print_error( "openmpt_module_read_stereo()", mod_err, mod_err_str ); openmpt_free_string( mod_err_str ); mod_err_str = NULL; } if ( count == 0 ) { break; } pa_error = Pa_WriteStream( stream, buffers, (unsigned long)count ); if ( pa_error == paOutputUnderflowed ) { pa_error = paNoError; } if ( pa_error != paNoError ) { fprintf( stderr, "Error: %s\n", "Pa_WriteStream() failed." ); goto fail; } } result = 0; goto cleanup; fail: result = 1; cleanup: if ( stream ) { if ( Pa_IsStreamActive( stream ) == 1 ) { Pa_StopStream( stream ); } Pa_CloseStream( stream ); stream = 0; } if ( pa_initialized ) { Pa_Terminate(); pa_initialized = 0; } if ( mod ) { openmpt_module_destroy( mod ); mod = 0; } if ( blob ) { free_blob( blob ); blob = 0; } return result; } libopenmpt-0.3.6+release.autotools/examples/libopenmpt_example_cxx.cpp0000644000372100037210000000523613231376354023363 00000000000000/* * libopenmpt_example_cxx.cpp * -------------------------- * Purpose: libopenmpt C++ API example * Notes : PortAudio C++ is used for sound output. * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ /* * Usage: libopenmpt_example_cxx SOMEMODULE */ #include #include #include #include #include #include #include #include #if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) ) #if defined( __GNUC__ ) // mingw-w64 g++ does only default to special C linkage for "main", but not for "wmain" (see ). extern "C" int wmain( int argc, wchar_t * argv[] ) { #else int wmain( int argc, wchar_t * argv[] ) { #endif #else int main( int argc, char * argv[] ) { #endif try { if ( argc != 2 ) { throw std::runtime_error( "Usage: libopenmpt_example_cxx SOMEMODULE" ); } const std::size_t buffersize = 480; #if defined( LIBOPENMPT_QUIRK_NO_CSTDINT ) const openmpt::std::int32_t samplerate = 48000; #else const std::int32_t samplerate = 48000; #endif std::vector left( buffersize ); std::vector right( buffersize ); const float * const buffers[2] = { left.data(), right.data() }; std::ifstream file( argv[1], std::ios::binary ); openmpt::module mod( file ); portaudio::AutoSystem portaudio_initializer; portaudio::System & portaudio = portaudio::System::instance(); portaudio::DirectionSpecificStreamParameters outputstream_parameters( portaudio.defaultOutputDevice(), 2, portaudio::FLOAT32, false, portaudio.defaultOutputDevice().defaultHighOutputLatency(), 0 ); portaudio::StreamParameters stream_parameters( portaudio::DirectionSpecificStreamParameters::null(), outputstream_parameters, samplerate, paFramesPerBufferUnspecified, paNoFlag ); portaudio::BlockingStream stream( stream_parameters ); stream.start(); while ( true ) { std::size_t count = mod.read( samplerate, buffersize, left.data(), right.data() ); if ( count == 0 ) { break; } try { stream.write( buffers, static_cast( count ) ); } catch ( const portaudio::PaException & pa_exception ) { if ( pa_exception.paError() != paOutputUnderflowed ) { throw; } } } stream.stop(); } catch ( const std::bad_alloc & ) { std::cerr << "Error: " << std::string( "out of memory" ) << std::endl; return 1; } catch ( const std::exception & e ) { std::cerr << "Error: " << std::string( e.what() ? e.what() : "unknown error" ) << std::endl; return 1; } return 0; } libopenmpt-0.3.6+release.autotools/examples/.clang-format0000644000372100037210000000370212662770510020457 00000000000000AccessModifierOffset: -2 AlignAfterOpenBracket: true AlignConsecutiveAssignments: false AlignEscapedNewlinesLeft: true AlignOperands: true AlignTrailingComments: false AllowAllParametersOfDeclarationOnNextLine: false AllowShortBlocksOnASingleLine: false AllowShortCaseLabelsOnASingleLine: false AllowShortFunctionsOnASingleLine: All AllowShortIfStatementsOnASingleLine: false AllowShortLoopsOnASingleLine: false AlwaysBreakAfterDefinitionReturnType: None AlwaysBreakBeforeMultilineStrings: false AlwaysBreakTemplateDeclarations: false BinPackArguments: false BinPackParameters: false BreakBeforeBinaryOperators: None BreakBeforeBraces: Attach BreakBeforeTernaryOperators: false BreakConstructorInitializersBeforeComma: true ColumnLimit: 0 CommentPragmas: '^ IWYU pragma:' ConstructorInitializerAllOnOneLineOrOnePerLine: true ConstructorInitializerIndentWidth: 2 ContinuationIndentWidth: 2 Cpp11BracedListStyle: false DerivePointerAlignment: false DisableFormat: false ExperimentalAutoDetectBinPacking: false ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] IndentCaseLabels: false IndentWidth: 2 IndentWrappedFunctionNames: false KeepEmptyLinesAtTheStartOfBlocks: true Language: Cpp MacroBlockBegin: '' MacroBlockEnd: '' MaxEmptyLinesToKeep: 3 NamespaceIndentation: None ObjCBlockIndentWidth: 2 ObjCSpaceAfterProperty: false ObjCSpaceBeforeProtocolList: true PenaltyBreakBeforeFirstCallParameter: 1 PenaltyBreakComment: 60 PenaltyBreakFirstLessLess: 120 PenaltyBreakString: 1000 PenaltyExcessCharacter: 1000000 PenaltyReturnTypeOnItsOwnLine: 200 PointerAlignment: Middle SpaceAfterCStyleCast: false SpaceBeforeAssignmentOperators: true SpaceBeforeParens: ControlStatements SpaceInEmptyParentheses: false SpacesBeforeTrailingComments: 1 SpacesInAngles: false SpacesInContainerLiterals: true SpacesInCStyleCastParentheses: false SpacesInParentheses: true SpacesInSquareBrackets: false Standard: Cpp03 TabWidth: 2 UseTab: ForIndentation libopenmpt-0.3.6+release.autotools/examples/libopenmpt_example_c.c0000644000372100037210000001216613051352114022427 00000000000000/* * libopenmpt_example_c.c * ---------------------- * Purpose: libopenmpt C API example * Notes : PortAudio is used for sound output. * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ /* * Usage: libopenmpt_example_c SOMEMODULE */ #include #include #include #include #include #include #include #include #define BUFFERSIZE 480 #define SAMPLERATE 48000 static int16_t left[BUFFERSIZE]; static int16_t right[BUFFERSIZE]; static int16_t * const buffers[2] = { left, right }; static void libopenmpt_example_logfunc( const char * message, void * userdata ) { (void)userdata; if ( message ) { fprintf( stderr, "openmpt: %s\n", message ); } } static int libopenmpt_example_errfunc( int error, void * userdata ) { (void)userdata; (void)error; return OPENMPT_ERROR_FUNC_RESULT_DEFAULT & ~OPENMPT_ERROR_FUNC_RESULT_LOG; } static void libopenmpt_example_print_error( const char * func_name, int mod_err, const char * mod_err_str ) { if ( !func_name ) { func_name = "unknown function"; } if ( mod_err == OPENMPT_ERROR_OUT_OF_MEMORY ) { mod_err_str = openmpt_error_string( mod_err ); if ( !mod_err_str ) { fprintf( stderr, "Error: %s\n", "OPENMPT_ERROR_OUT_OF_MEMORY" ); } else { fprintf( stderr, "Error: %s\n", mod_err_str ); openmpt_free_string( mod_err_str ); mod_err_str = NULL; } } else { if ( !mod_err_str ) { mod_err_str = openmpt_error_string( mod_err ); if ( !mod_err_str ) { fprintf( stderr, "Error: %s failed.\n", func_name ); } else { fprintf( stderr, "Error: %s failed: %s\n", func_name, mod_err_str ); } openmpt_free_string( mod_err_str ); mod_err_str = NULL; } fprintf( stderr, "Error: %s failed: %s\n", func_name, mod_err_str ); } } #if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) ) int wmain( int argc, wchar_t * argv[] ) { #else int main( int argc, char * argv[] ) { #endif int result = 0; FILE * file = 0; openmpt_module * mod = 0; int mod_err = OPENMPT_ERROR_OK; const char * mod_err_str = NULL; size_t count = 0; PaError pa_error = paNoError; int pa_initialized = 0; PaStream * stream = 0; if ( argc != 2 ) { fprintf( stderr, "Error: %s\n", "Wrong invocation. Use 'libopenmpt_example_c SOMEMODULE'." ); goto fail; } #if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) ) if ( wcslen( argv[1] ) == 0 ) { fprintf( stderr, "Error: %s\n", "Wrong invocation. Use 'libopenmpt_example_c SOMEMODULE'." ); goto fail; } file = _wfopen( argv[1], L"rb" ); #else if ( strlen( argv[1] ) == 0 ) { fprintf( stderr, "Error: %s\n", "Wrong invocation. Use 'libopenmpt_example_c SOMEMODULE'." ); goto fail; } file = fopen( argv[1], "rb" ); #endif if ( !file ) { fprintf( stderr, "Error: %s\n", "fopen() failed." ); goto fail; } mod = openmpt_module_create2( openmpt_stream_get_file_callbacks(), file, &libopenmpt_example_logfunc, NULL, &libopenmpt_example_errfunc, NULL, &mod_err, &mod_err_str, NULL ); if ( !mod ) { libopenmpt_example_print_error( "openmpt_module_create2()", mod_err, mod_err_str ); openmpt_free_string( mod_err_str ); mod_err_str = NULL; goto fail; } openmpt_module_set_error_func( mod, NULL, NULL ); pa_error = Pa_Initialize(); if ( pa_error != paNoError ) { fprintf( stderr, "Error: %s\n", "Pa_Initialize() failed." ); goto fail; } pa_initialized = 1; pa_error = Pa_OpenDefaultStream( &stream, 0, 2, paInt16 | paNonInterleaved, SAMPLERATE, paFramesPerBufferUnspecified, NULL, NULL ); if ( pa_error != paNoError ) { fprintf( stderr, "Error: %s\n", "Pa_OpenStream() failed." ); goto fail; } if ( !stream ) { fprintf( stderr, "Error: %s\n", "Pa_OpenStream() failed." ); goto fail; } pa_error = Pa_StartStream( stream ); if ( pa_error != paNoError ) { fprintf( stderr, "Error: %s\n", "Pa_StartStream() failed." ); goto fail; } while ( 1 ) { openmpt_module_error_clear( mod ); count = openmpt_module_read_stereo( mod, SAMPLERATE, BUFFERSIZE, left, right ); mod_err = openmpt_module_error_get_last( mod ); mod_err_str = openmpt_module_error_get_last_message( mod ); if ( mod_err != OPENMPT_ERROR_OK ) { libopenmpt_example_print_error( "openmpt_module_read_stereo()", mod_err, mod_err_str ); openmpt_free_string( mod_err_str ); mod_err_str = NULL; } if ( count == 0 ) { break; } pa_error = Pa_WriteStream( stream, buffers, (unsigned long)count ); if ( pa_error == paOutputUnderflowed ) { pa_error = paNoError; } if ( pa_error != paNoError ) { fprintf( stderr, "Error: %s\n", "Pa_WriteStream() failed." ); goto fail; } } result = 0; goto cleanup; fail: result = 1; cleanup: if ( stream ) { if ( Pa_IsStreamActive( stream ) == 1 ) { Pa_StopStream( stream ); } Pa_CloseStream( stream ); stream = 0; } if ( pa_initialized ) { Pa_Terminate(); pa_initialized = 0; } if ( mod ) { openmpt_module_destroy( mod ); mod = 0; } if ( file ) { fclose( file ); file = 0; } return result; } libopenmpt-0.3.6+release.autotools/examples/libopenmpt_example_c_stdout.c0000644000372100037210000001077613051352114024036 00000000000000/* * libopenmpt_example_c_stdout.c * ----------------------------- * Purpose: libopenmpt C API simple example * Notes : This example writes raw 48000Hz / stereo / 16bit native endian PCM data to stdout. * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ /* * Usage: libopenmpt_example_c_stdout SOMEMODULE | aplay --file-type raw --format=dat */ #include #include #include #include #include #include #include #include #include #define BUFFERSIZE 480 #define SAMPLERATE 48000 static void libopenmpt_example_logfunc( const char * message, void * userdata ) { (void)userdata; if ( message ) { fprintf( stderr, "openmpt: %s\n", message ); } } static int libopenmpt_example_errfunc( int error, void * userdata ) { (void)userdata; (void)error; return OPENMPT_ERROR_FUNC_RESULT_DEFAULT & ~OPENMPT_ERROR_FUNC_RESULT_LOG; } static void libopenmpt_example_print_error( const char * func_name, int mod_err, const char * mod_err_str ) { if ( !func_name ) { func_name = "unknown function"; } if ( mod_err == OPENMPT_ERROR_OUT_OF_MEMORY ) { mod_err_str = openmpt_error_string( mod_err ); if ( !mod_err_str ) { fprintf( stderr, "Error: %s\n", "OPENMPT_ERROR_OUT_OF_MEMORY" ); } else { fprintf( stderr, "Error: %s\n", mod_err_str ); openmpt_free_string( mod_err_str ); mod_err_str = NULL; } } else { if ( !mod_err_str ) { mod_err_str = openmpt_error_string( mod_err ); if ( !mod_err_str ) { fprintf( stderr, "Error: %s failed.\n", func_name ); } else { fprintf( stderr, "Error: %s failed: %s\n", func_name, mod_err_str ); } openmpt_free_string( mod_err_str ); mod_err_str = NULL; } fprintf( stderr, "Error: %s failed: %s\n", func_name, mod_err_str ); } } static ssize_t xwrite( int fd, const void * buffer, size_t size ) { size_t written = 0; ssize_t retval = 0; while ( written < size ) { retval = write( fd, (const char *)buffer + written, size - written ); if ( retval < 0 ) { if ( errno != EINTR ) { break; } retval = 0; } written += retval; } return written; } static int16_t buffer[BUFFERSIZE * 2]; #if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) ) int wmain( int argc, wchar_t * argv[] ) { #else int main( int argc, char * argv[] ) { #endif int result = 0; FILE * file = 0; openmpt_module * mod = 0; int mod_err = OPENMPT_ERROR_OK; const char * mod_err_str = NULL; size_t count = 0; size_t written = 0; if ( argc != 2 ) { fprintf( stderr, "Error: %s\n", "Wrong invocation. Use 'libopenmpt_example_c_stdout SOMEMODULE'." ); goto fail; } #if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) ) if ( wcslen( argv[1] ) == 0 ) { fprintf( stderr, "Error: %s\n", "Wrong invocation. Use 'libopenmpt_example_c_stdout SOMEMODULE'." ); goto fail; } file = _wfopen( argv[1], L"rb" ); #else if ( strlen( argv[1] ) == 0 ) { fprintf( stderr, "Error: %s\n", "Wrong invocation. Use 'libopenmpt_example_c_stdout SOMEMODULE'." ); goto fail; } file = fopen( argv[1], "rb" ); #endif if ( !file ) { fprintf( stderr, "Error: %s\n", "fopen() failed." ); goto fail; } mod = openmpt_module_create2( openmpt_stream_get_file_callbacks(), file, &libopenmpt_example_logfunc, NULL, &libopenmpt_example_errfunc, NULL, &mod_err, &mod_err_str, NULL ); if ( !mod ) { libopenmpt_example_print_error( "openmpt_module_create2()", mod_err, mod_err_str ); openmpt_free_string( mod_err_str ); mod_err_str = NULL; goto fail; } while ( 1 ) { openmpt_module_error_clear( mod ); count = openmpt_module_read_interleaved_stereo( mod, SAMPLERATE, BUFFERSIZE, buffer ); mod_err = openmpt_module_error_get_last( mod ); mod_err_str = openmpt_module_error_get_last_message( mod ); if ( mod_err != OPENMPT_ERROR_OK ) { libopenmpt_example_print_error( "openmpt_module_read_interleaved_stereo()", mod_err, mod_err_str ); openmpt_free_string( mod_err_str ); mod_err_str = NULL; } if ( count == 0 ) { break; } written = xwrite( STDOUT_FILENO, buffer, count * 2 * sizeof( int16_t ) ); if ( written == 0 ) { fprintf( stderr, "Error: %s\n", "write() failed." ); goto fail; } } result = 0; goto cleanup; fail: result = 1; cleanup: if ( mod ) { openmpt_module_destroy( mod ); mod = 0; } if ( file ) { fclose( file ); file = 0; } return result; } libopenmpt-0.3.6+release.autotools/examples/libopenmpt_example_c_unsafe.c0000644000372100037210000000351613051352114023767 00000000000000/* * libopenmpt_example_c_unsafe.c * ----------------------------- * Purpose: libopenmpt C API simplified example * Notes : PortAudio is used for sound output. * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ /* * Usage: libopenmpt_example_c_unsafe SOMEMODULE * CAUTION: This simple example does no error cheking at all. */ #include #include #include #include #include #include #include #include #define BUFFERSIZE 480 #define SAMPLERATE 48000 static int16_t left[BUFFERSIZE]; static int16_t right[BUFFERSIZE]; static int16_t * const buffers[2] = { left, right }; #if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) ) int wmain( int argc, wchar_t * argv[] ) { #else int main( int argc, char * argv[] ) { #endif FILE * file = 0; openmpt_module * mod = 0; size_t count = 0; PaStream * stream = 0; (void)argc; #if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) ) file = _wfopen( argv[1], L"rb" ); #else file = fopen( argv[1], "rb" ); #endif mod = openmpt_module_create2( openmpt_stream_get_file_callbacks(), file, NULL, NULL, NULL, NULL, NULL, NULL, NULL ); fclose( file ); Pa_Initialize(); Pa_OpenDefaultStream( &stream, 0, 2, paInt16 | paNonInterleaved, SAMPLERATE, paFramesPerBufferUnspecified, NULL, NULL ); Pa_StartStream( stream ); while ( 1 ) { count = openmpt_module_read_stereo( mod, SAMPLERATE, BUFFERSIZE, left, right ); if ( count == 0 ) { break; } Pa_WriteStream( stream, buffers, (unsigned long)count ); } Pa_StopStream( stream ); Pa_CloseStream( stream ); Pa_Terminate(); openmpt_module_destroy( mod ); return 0; } libopenmpt-0.3.6+release.autotools/examples/libopenmpt_example_c_probe.c0000644000372100037210000001201513157740470023624 00000000000000/* * libopenmpt_example_c_probe.c * ---------------------------- * Purpose: libopenmpt C API probing example * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ /* * Usage: libopenmpt_example_c_probe SOMEMODULE ... * Returns 0 on successful probing for all files. * Returns 1 on failed probing for 1 or more files. * Returns 2 on error. */ #define LIBOPENMPT_EXAMPLE_PROBE_RESULT_BINARY 1 #define LIBOPENMPT_EXAMPLE_PROBE_RESULT_FLOAT 2 #define LIBOPENMPT_EXAMPLE_PROBE_RESULT LIBOPENMPT_EXAMPLE_PROBE_RESULT_BINARY #include #include #include #include #include #include #include static void libopenmpt_example_logfunc( const char * message, void * userdata ) { (void)userdata; if ( message ) { fprintf( stderr, "%s\n", message ); } } #if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) ) static int probe_file( const wchar_t * filename ) { #else static int probe_file( const char * filename ) { #endif int result = 0; int mod_err = OPENMPT_ERROR_OK; FILE * file = NULL; #if ( LIBOPENMPT_EXAMPLE_PROBE_RESULT == LIBOPENMPT_EXAMPLE_PROBE_RESULT_BINARY ) int result_binary = 0; int probe_file_header_result = OPENMPT_PROBE_FILE_HEADER_RESULT_FAILURE; const char * probe_file_header_result_str = NULL; #endif #if ( LIBOPENMPT_EXAMPLE_PROBE_RESULT == LIBOPENMPT_EXAMPLE_PROBE_RESULT_FLOAT ) double probability = 0.0; #endif #if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) ) if ( wcslen( filename ) == 0 ) { fprintf( stderr, "Error: %s\n", "Wrong invocation. Use 'libopenmpt_example_c_probe SOMEMODULE'." ); goto fail; } #else if ( strlen( filename ) == 0 ) { fprintf( stderr, "Error: %s\n", "Wrong invocation. Use 'libopenmpt_example_c_probe SOMEMODULE'." ); goto fail; } #endif #if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) ) file = _wfopen( filename, L"rb" ); #else file = fopen( filename, "rb" ); #endif if ( !file ) { fprintf( stderr, "Error: %s\n", "fopen() failed." ); goto fail; } #if ( LIBOPENMPT_EXAMPLE_PROBE_RESULT == LIBOPENMPT_EXAMPLE_PROBE_RESULT_BINARY ) probe_file_header_result = openmpt_probe_file_header_from_stream( OPENMPT_PROBE_FILE_HEADER_FLAGS_DEFAULT, openmpt_stream_get_file_callbacks(), file, &libopenmpt_example_logfunc, NULL, &openmpt_error_func_default, NULL, &mod_err, NULL ); probe_file_header_result_str = NULL; result_binary = 0; switch ( probe_file_header_result ) { case OPENMPT_PROBE_FILE_HEADER_RESULT_SUCCESS: probe_file_header_result_str = "Success "; result_binary = 1; break; case OPENMPT_PROBE_FILE_HEADER_RESULT_FAILURE: probe_file_header_result_str = "Failure "; result_binary = 0; break; case OPENMPT_PROBE_FILE_HEADER_RESULT_WANTMOREDATA: probe_file_header_result_str = "WantMoreData"; result_binary = 0; break; case OPENMPT_PROBE_FILE_HEADER_RESULT_ERROR: result_binary = 0; fprintf( stderr, "Error: %s\n", "openmpt_probe_file_header() failed." ); goto fail; break; default: result_binary = 0; fprintf( stderr, "Error: %s\n", "openmpt_probe_file_header() failed." ); goto fail; break; } #if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) ) fprintf( stdout, "%s - %ls\n", probe_file_header_result_str, filename ); #else fprintf( stdout, "%s - %s\n", probe_file_header_result_str, filename ); #endif if ( result_binary ) { result = 0; } else { result = 1; } #elif ( LIBOPENMPT_EXAMPLE_PROBE_RESULT == LIBOPENMPT_EXAMPLE_PROBE_RESULT_FLOAT ) probability = openmpt_could_open_probability2( openmpt_stream_get_file_callbacks(), file, 0.25, &libopenmpt_example_logfunc, NULL, &openmpt_error_func_default, NULL, &mod_err, NULL ); #if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) ) fprintf( stdout, "%s: %f - %ls\n", "Result", probability, filename ); #else fprintf( stdout, "%s: %f - %s\n", "Result", probability, filename ); #endif if ( probability >= 0.5 ) { result = 0; } else { result = 1; } #else #error "LIBOPENMPT_EXAMPLE_PROBE_RESULT is wrong" #endif goto cleanup; fail: result = 2; cleanup: if ( file ) { fclose( file ); file = 0; } return result; } #if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) ) int wmain( int argc, wchar_t * argv[] ) { #else int main( int argc, char * argv[] ) { #endif int global_result = 0; if ( argc <= 1 ) { fprintf( stderr, "Error: %s\n", "Wrong invocation. Use 'libopenmpt_example_c_probe SOMEMODULE ...'." ); goto fail; } for ( int i = 1; i < argc; ++i ) { int result = probe_file( argv[i] ); if ( result > global_result ) { global_result = result; } } goto cleanup; fail: global_result = 2; cleanup: return global_result; } libopenmpt-0.3.6+release.autotools/Makefile.in0000644000372100037210000245032613235362221016336 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = $(am__EXEEXT_1) check_PROGRAMS = $(am__EXEEXT_2) $(am__EXEEXT_3) $(am__EXEEXT_4) \ $(am__EXEEXT_5) @ENABLE_TESTS_TRUE@TESTS = libopenmpttest$(EXEEXT) @ENABLE_EXAMPLES_TRUE@am__append_1 = libopenmpt_example_c_stdout \ @ENABLE_EXAMPLES_TRUE@ libopenmpt_example_c_probe @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIO_TRUE@am__append_2 = libopenmpt_example_c \ @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIO_TRUE@ libopenmpt_example_c_mem \ @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIO_TRUE@ libopenmpt_example_c_unsafe @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIOCPP_TRUE@am__append_3 = libopenmpt_example_cxx @ENABLE_LIBOPENMPT_MODPLUG_TRUE@am__append_4 = libopenmpt_modplug.la @ENABLE_LIBMODPLUG_TRUE@am__append_5 = libmodplug/libmodplug.pc @ENABLE_LIBMODPLUG_TRUE@am__append_6 = libmodplug.la @ENABLE_LIBMODPLUG_TRUE@am__append_7 = libmodplug/modplug.h libmodplug/sndfile.h libmodplug/stdafx.h @ENABLE_TESTS_TRUE@am__append_8 = libopenmpttest @ENABLE_OPENMPT123_TRUE@am__append_9 = bin/openmpt123 subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_append_flag.m4 \ $(top_srcdir)/m4/ax_cflags_warn_all.m4 \ $(top_srcdir)/m4/ax_check_compile_flag.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/ax_prog_doxygen.m4 \ $(top_srcdir)/m4/ax_require_defined.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ $(am__configure_deps) $(dist_doc_DATA) $(nobase_dist_doc_DATA) \ $(am__nobase_include_HEADERS_DIST) $(am__DIST_COMMON) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = libopenmpt/libopenmpt.pc libmodplug/libmodplug.pc \ Doxyfile CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \ "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(docdir)" \ "$(DESTDIR)$(docdir)" "$(DESTDIR)$(pkgconfigdir)" \ "$(DESTDIR)$(includedir)" LTLIBRARIES = $(lib_LTLIBRARIES) @ENABLE_LIBMODPLUG_TRUE@libmodplug_la_DEPENDENCIES = libopenmpt.la am__libmodplug_la_SOURCES_DIST = libopenmpt/libopenmpt_modplug.c \ libopenmpt/libopenmpt_modplug_cpp.cpp am__dirstamp = $(am__leading_dot)dirstamp @ENABLE_LIBMODPLUG_TRUE@am_libmodplug_la_OBJECTS = libopenmpt/libmodplug_la-libopenmpt_modplug.lo \ @ENABLE_LIBMODPLUG_TRUE@ libopenmpt/libmodplug_la-libopenmpt_modplug_cpp.lo libmodplug_la_OBJECTS = $(am_libmodplug_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libmodplug_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ $(libmodplug_la_CXXFLAGS) $(CXXFLAGS) $(libmodplug_la_LDFLAGS) \ $(LDFLAGS) -o $@ @ENABLE_LIBMODPLUG_TRUE@am_libmodplug_la_rpath = -rpath $(libdir) am__DEPENDENCIES_1 = libopenmpt_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) am__objects_1 = common/libopenmpt_la-ComponentManager.lo \ common/libopenmpt_la-FileReader.lo \ common/libopenmpt_la-Logging.lo \ common/libopenmpt_la-misc_util.lo \ common/libopenmpt_la-mptCPU.lo \ common/libopenmpt_la-mptFileIO.lo \ common/libopenmpt_la-mptIO.lo \ common/libopenmpt_la-mptLibrary.lo \ common/libopenmpt_la-mptOS.lo \ common/libopenmpt_la-mptPathString.lo \ common/libopenmpt_la-mptRandom.lo \ common/libopenmpt_la-mptString.lo \ common/libopenmpt_la-mptStringFormat.lo \ common/libopenmpt_la-mptStringParse.lo \ common/libopenmpt_la-mptTime.lo \ common/libopenmpt_la-mptUUID.lo \ common/libopenmpt_la-mptWine.lo \ common/libopenmpt_la-Profiler.lo \ common/libopenmpt_la-serialization_utils.lo \ common/libopenmpt_la-stdafx.lo \ common/libopenmpt_la-typedefs.lo \ common/libopenmpt_la-version.lo am__objects_2 = am__objects_3 = soundlib/libopenmpt_la-AudioCriticalSection.lo \ soundlib/libopenmpt_la-ContainerMMCMP.lo \ soundlib/libopenmpt_la-ContainerPP20.lo \ soundlib/libopenmpt_la-ContainerUMX.lo \ soundlib/libopenmpt_la-ContainerXPK.lo \ soundlib/libopenmpt_la-Dither.lo \ soundlib/libopenmpt_la-Dlsbank.lo \ soundlib/libopenmpt_la-Fastmix.lo \ soundlib/libopenmpt_la-InstrumentExtensions.lo \ soundlib/libopenmpt_la-ITCompression.lo \ soundlib/libopenmpt_la-ITTools.lo \ soundlib/libopenmpt_la-Load_669.lo \ soundlib/libopenmpt_la-Load_amf.lo \ soundlib/libopenmpt_la-Load_ams.lo \ soundlib/libopenmpt_la-Load_dbm.lo \ soundlib/libopenmpt_la-Load_digi.lo \ soundlib/libopenmpt_la-Load_dmf.lo \ soundlib/libopenmpt_la-Load_dsm.lo \ soundlib/libopenmpt_la-Load_dtm.lo \ soundlib/libopenmpt_la-Load_far.lo \ soundlib/libopenmpt_la-Load_gdm.lo \ soundlib/libopenmpt_la-Load_imf.lo \ soundlib/libopenmpt_la-Load_it.lo \ soundlib/libopenmpt_la-Load_itp.lo \ soundlib/libopenmpt_la-load_j2b.lo \ soundlib/libopenmpt_la-Load_mdl.lo \ soundlib/libopenmpt_la-Load_med.lo \ soundlib/libopenmpt_la-Load_mid.lo \ soundlib/libopenmpt_la-Load_mo3.lo \ soundlib/libopenmpt_la-Load_mod.lo \ soundlib/libopenmpt_la-Load_mt2.lo \ soundlib/libopenmpt_la-Load_mtm.lo \ soundlib/libopenmpt_la-Load_okt.lo \ soundlib/libopenmpt_la-Load_plm.lo \ soundlib/libopenmpt_la-Load_psm.lo \ soundlib/libopenmpt_la-Load_ptm.lo \ soundlib/libopenmpt_la-Load_s3m.lo \ soundlib/libopenmpt_la-Load_sfx.lo \ soundlib/libopenmpt_la-Load_stm.lo \ soundlib/libopenmpt_la-Load_stp.lo \ soundlib/libopenmpt_la-Load_uax.lo \ soundlib/libopenmpt_la-Load_ult.lo \ soundlib/libopenmpt_la-Load_wav.lo \ soundlib/libopenmpt_la-Load_xm.lo \ soundlib/libopenmpt_la-Message.lo \ soundlib/libopenmpt_la-MIDIEvents.lo \ soundlib/libopenmpt_la-MIDIMacros.lo \ soundlib/libopenmpt_la-MixerLoops.lo \ soundlib/libopenmpt_la-MixerSettings.lo \ soundlib/libopenmpt_la-MixFuncTable.lo \ soundlib/libopenmpt_la-ModChannel.lo \ soundlib/libopenmpt_la-modcommand.lo \ soundlib/libopenmpt_la-ModInstrument.lo \ soundlib/libopenmpt_la-ModSample.lo \ soundlib/libopenmpt_la-ModSequence.lo \ soundlib/libopenmpt_la-modsmp_ctrl.lo \ soundlib/libopenmpt_la-mod_specifications.lo \ soundlib/libopenmpt_la-MPEGFrame.lo \ soundlib/libopenmpt_la-OggStream.lo \ soundlib/libopenmpt_la-Paula.lo \ soundlib/libopenmpt_la-patternContainer.lo \ soundlib/libopenmpt_la-pattern.lo \ soundlib/libopenmpt_la-RowVisitor.lo \ soundlib/libopenmpt_la-S3MTools.lo \ soundlib/libopenmpt_la-SampleFormats.lo \ soundlib/libopenmpt_la-SampleFormatFLAC.lo \ soundlib/libopenmpt_la-SampleFormatMediaFoundation.lo \ soundlib/libopenmpt_la-SampleFormatMP3.lo \ soundlib/libopenmpt_la-SampleFormatOpus.lo \ soundlib/libopenmpt_la-SampleFormatVorbis.lo \ soundlib/libopenmpt_la-SampleIO.lo \ soundlib/libopenmpt_la-Sndfile.lo \ soundlib/libopenmpt_la-Snd_flt.lo \ soundlib/libopenmpt_la-Snd_fx.lo \ soundlib/libopenmpt_la-Sndmix.lo \ soundlib/libopenmpt_la-SoundFilePlayConfig.lo \ soundlib/libopenmpt_la-Tables.lo \ soundlib/libopenmpt_la-Tagging.lo \ soundlib/libopenmpt_la-tuningbase.lo \ soundlib/libopenmpt_la-tuningCollection.lo \ soundlib/libopenmpt_la-tuning.lo \ soundlib/libopenmpt_la-UMXTools.lo \ soundlib/libopenmpt_la-UpgradeModule.lo \ soundlib/libopenmpt_la-WAVTools.lo \ soundlib/libopenmpt_la-WindowedFIR.lo \ soundlib/libopenmpt_la-XMTools.lo \ soundlib/plugins/dmo/libopenmpt_la-DMOPlugin.lo \ soundlib/plugins/dmo/libopenmpt_la-Chorus.lo \ soundlib/plugins/dmo/libopenmpt_la-Compressor.lo \ soundlib/plugins/dmo/libopenmpt_la-Distortion.lo \ soundlib/plugins/dmo/libopenmpt_la-Echo.lo \ soundlib/plugins/dmo/libopenmpt_la-Flanger.lo \ soundlib/plugins/dmo/libopenmpt_la-Gargle.lo \ soundlib/plugins/dmo/libopenmpt_la-I3DL2Reverb.lo \ soundlib/plugins/dmo/libopenmpt_la-ParamEq.lo \ soundlib/plugins/dmo/libopenmpt_la-WavesReverb.lo \ soundlib/plugins/libopenmpt_la-DigiBoosterEcho.lo \ soundlib/plugins/libopenmpt_la-LFOPlugin.lo \ soundlib/plugins/libopenmpt_la-PluginManager.lo \ soundlib/plugins/libopenmpt_la-PlugInterface.lo am__objects_4 = sounddsp/libopenmpt_la-AGC.lo \ sounddsp/libopenmpt_la-DSP.lo sounddsp/libopenmpt_la-EQ.lo \ sounddsp/libopenmpt_la-Reverb.lo am_libopenmpt_la_OBJECTS = $(am__objects_1) $(am__objects_2) \ $(am__objects_3) $(am__objects_4) \ libopenmpt/libopenmpt_la-libopenmpt_c.lo \ libopenmpt/libopenmpt_la-libopenmpt_cxx.lo \ libopenmpt/libopenmpt_la-libopenmpt_ext_impl.lo \ libopenmpt/libopenmpt_la-libopenmpt_impl.lo libopenmpt_la_OBJECTS = $(am_libopenmpt_la_OBJECTS) libopenmpt_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) $(libopenmpt_la_LDFLAGS) \ $(LDFLAGS) -o $@ @ENABLE_LIBOPENMPT_MODPLUG_TRUE@libopenmpt_modplug_la_DEPENDENCIES = \ @ENABLE_LIBOPENMPT_MODPLUG_TRUE@ libopenmpt.la am__libopenmpt_modplug_la_SOURCES_DIST = \ libopenmpt/libopenmpt_modplug.c \ libopenmpt/libopenmpt_modplug_cpp.cpp @ENABLE_LIBOPENMPT_MODPLUG_TRUE@am_libopenmpt_modplug_la_OBJECTS = libopenmpt/libopenmpt_modplug_la-libopenmpt_modplug.lo \ @ENABLE_LIBOPENMPT_MODPLUG_TRUE@ libopenmpt/libopenmpt_modplug_la-libopenmpt_modplug_cpp.lo libopenmpt_modplug_la_OBJECTS = $(am_libopenmpt_modplug_la_OBJECTS) libopenmpt_modplug_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ $(libopenmpt_modplug_la_CXXFLAGS) $(CXXFLAGS) \ $(libopenmpt_modplug_la_LDFLAGS) $(LDFLAGS) -o $@ @ENABLE_LIBOPENMPT_MODPLUG_TRUE@am_libopenmpt_modplug_la_rpath = \ @ENABLE_LIBOPENMPT_MODPLUG_TRUE@ -rpath $(libdir) @ENABLE_OPENMPT123_TRUE@am__EXEEXT_1 = bin/openmpt123$(EXEEXT) @ENABLE_EXAMPLES_TRUE@am__EXEEXT_2 = \ @ENABLE_EXAMPLES_TRUE@ libopenmpt_example_c_stdout$(EXEEXT) \ @ENABLE_EXAMPLES_TRUE@ libopenmpt_example_c_probe$(EXEEXT) @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIO_TRUE@am__EXEEXT_3 = libopenmpt_example_c$(EXEEXT) \ @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIO_TRUE@ libopenmpt_example_c_mem$(EXEEXT) \ @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIO_TRUE@ libopenmpt_example_c_unsafe$(EXEEXT) @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIOCPP_TRUE@am__EXEEXT_4 = libopenmpt_example_cxx$(EXEEXT) @ENABLE_TESTS_TRUE@am__EXEEXT_5 = libopenmpttest$(EXEEXT) PROGRAMS = $(bin_PROGRAMS) am__bin_openmpt123_SOURCES_DIST = openmpt123/openmpt123_config.hpp \ openmpt123/openmpt123.cpp openmpt123/openmpt123_flac.hpp \ openmpt123/openmpt123.hpp openmpt123/openmpt123_mmio.hpp \ openmpt123/openmpt123_portaudio.hpp \ openmpt123/openmpt123_pulseaudio.hpp \ openmpt123/openmpt123_raw.hpp openmpt123/openmpt123_sdl.hpp \ openmpt123/openmpt123_sdl2.hpp \ openmpt123/openmpt123_sndfile.hpp \ openmpt123/openmpt123_stdout.hpp \ openmpt123/openmpt123_waveout.hpp @ENABLE_OPENMPT123_TRUE@am_bin_openmpt123_OBJECTS = openmpt123/bin_openmpt123-openmpt123.$(OBJEXT) bin_openmpt123_OBJECTS = $(am_bin_openmpt123_OBJECTS) @ENABLE_OPENMPT123_TRUE@bin_openmpt123_DEPENDENCIES = libopenmpt.la \ @ENABLE_OPENMPT123_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLE_OPENMPT123_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLE_OPENMPT123_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLE_OPENMPT123_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLE_OPENMPT123_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLE_OPENMPT123_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLE_OPENMPT123_TRUE@ $(am__DEPENDENCIES_1) bin_openmpt123_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ $(bin_openmpt123_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ am__libopenmpt_example_c_SOURCES_DIST = \ examples/libopenmpt_example_c.c @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIO_TRUE@am_libopenmpt_example_c_OBJECTS = examples/libopenmpt_example_c-libopenmpt_example_c.$(OBJEXT) libopenmpt_example_c_OBJECTS = $(am_libopenmpt_example_c_OBJECTS) @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIO_TRUE@libopenmpt_example_c_DEPENDENCIES = \ @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIO_TRUE@ $(lib_LTLIBRARIES) \ @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIO_TRUE@ $(am__DEPENDENCIES_1) libopenmpt_example_c_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(libopenmpt_example_c_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ am__libopenmpt_example_c_mem_SOURCES_DIST = \ examples/libopenmpt_example_c_mem.c @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIO_TRUE@am_libopenmpt_example_c_mem_OBJECTS = examples/libopenmpt_example_c_mem-libopenmpt_example_c_mem.$(OBJEXT) libopenmpt_example_c_mem_OBJECTS = \ $(am_libopenmpt_example_c_mem_OBJECTS) @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIO_TRUE@libopenmpt_example_c_mem_DEPENDENCIES = \ @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIO_TRUE@ $(lib_LTLIBRARIES) \ @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIO_TRUE@ $(am__DEPENDENCIES_1) libopenmpt_example_c_mem_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(libopenmpt_example_c_mem_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ am__libopenmpt_example_c_probe_SOURCES_DIST = \ examples/libopenmpt_example_c_probe.c @ENABLE_EXAMPLES_TRUE@am_libopenmpt_example_c_probe_OBJECTS = examples/libopenmpt_example_c_probe-libopenmpt_example_c_probe.$(OBJEXT) libopenmpt_example_c_probe_OBJECTS = \ $(am_libopenmpt_example_c_probe_OBJECTS) @ENABLE_EXAMPLES_TRUE@libopenmpt_example_c_probe_DEPENDENCIES = \ @ENABLE_EXAMPLES_TRUE@ $(lib_LTLIBRARIES) libopenmpt_example_c_probe_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(libopenmpt_example_c_probe_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ am__libopenmpt_example_c_stdout_SOURCES_DIST = \ examples/libopenmpt_example_c_stdout.c @ENABLE_EXAMPLES_TRUE@am_libopenmpt_example_c_stdout_OBJECTS = examples/libopenmpt_example_c_stdout-libopenmpt_example_c_stdout.$(OBJEXT) libopenmpt_example_c_stdout_OBJECTS = \ $(am_libopenmpt_example_c_stdout_OBJECTS) @ENABLE_EXAMPLES_TRUE@libopenmpt_example_c_stdout_DEPENDENCIES = \ @ENABLE_EXAMPLES_TRUE@ $(lib_LTLIBRARIES) libopenmpt_example_c_stdout_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(libopenmpt_example_c_stdout_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ am__libopenmpt_example_c_unsafe_SOURCES_DIST = \ examples/libopenmpt_example_c_unsafe.c @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIO_TRUE@am_libopenmpt_example_c_unsafe_OBJECTS = examples/libopenmpt_example_c_unsafe-libopenmpt_example_c_unsafe.$(OBJEXT) libopenmpt_example_c_unsafe_OBJECTS = \ $(am_libopenmpt_example_c_unsafe_OBJECTS) @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIO_TRUE@libopenmpt_example_c_unsafe_DEPENDENCIES = \ @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIO_TRUE@ $(lib_LTLIBRARIES) \ @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIO_TRUE@ $(am__DEPENDENCIES_1) libopenmpt_example_c_unsafe_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(libopenmpt_example_c_unsafe_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ am__libopenmpt_example_cxx_SOURCES_DIST = \ examples/libopenmpt_example_cxx.cpp @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIOCPP_TRUE@am_libopenmpt_example_cxx_OBJECTS = examples/libopenmpt_example_cxx-libopenmpt_example_cxx.$(OBJEXT) libopenmpt_example_cxx_OBJECTS = $(am_libopenmpt_example_cxx_OBJECTS) @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIOCPP_TRUE@libopenmpt_example_cxx_DEPENDENCIES = $(lib_LTLIBRARIES) \ @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIOCPP_TRUE@ $(am__DEPENDENCIES_1) libopenmpt_example_cxx_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ $(libopenmpt_example_cxx_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ am__libopenmpttest_SOURCES_DIST = libopenmpt/libopenmpt_test.cpp \ test/test.cpp test/test.h test/TestTools.h \ test/TestToolsLib.cpp test/TestToolsLib.h \ test/TestToolsTracker.h build/svn_version/svn_version.h \ common/BuildSettings.h common/CompilerDetect.h \ common/ComponentManager.cpp common/ComponentManager.h \ common/Endianness.h common/FileReader.cpp common/FileReader.h \ common/FileReaderFwd.h common/FlagSet.h common/Logging.cpp \ common/Logging.h common/misc_util.cpp common/misc_util.h \ common/mptBufferIO.h common/mptCPU.cpp common/mptCPU.h \ common/mptCRC.h common/mptFileIO.cpp common/mptFileIO.h \ common/mptIO.cpp common/mptIO.h common/mptLibrary.cpp \ common/mptLibrary.h common/mptMutex.h common/mptOS.cpp \ common/mptOS.h common/mptPathString.cpp common/mptPathString.h \ common/mptRandom.cpp common/mptRandom.h common/mptString.cpp \ common/mptString.h common/mptStringFormat.cpp \ common/mptStringFormat.h common/mptStringParse.cpp \ common/mptStringParse.h common/mptThread.h common/mptTime.cpp \ common/mptTime.h common/mptTypeTraits.h common/mptUUID.cpp \ common/mptUUID.h common/mptWine.cpp common/mptWine.h \ common/Profiler.cpp common/Profiler.h \ common/serialization_utils.cpp common/serialization_utils.h \ common/stdafx.cpp common/stdafx.h common/StringFixer.h \ common/typedefs.cpp common/typedefs.h common/version.cpp \ common/version.h common/versionNumber.h \ soundbase/SampleFormat.h soundbase/SampleFormatConverters.h \ soundbase/SampleFormatCopy.h soundlib/AudioCriticalSection.cpp \ soundlib/AudioCriticalSection.h soundlib/AudioReadTarget.h \ soundlib/ChunkReader.h soundlib/ContainerMMCMP.cpp \ soundlib/ContainerPP20.cpp soundlib/ContainerUMX.cpp \ soundlib/ContainerXPK.cpp soundlib/Container.h \ soundlib/Dither.cpp soundlib/Dither.h soundlib/Dlsbank.cpp \ soundlib/Dlsbank.h soundlib/Fastmix.cpp soundlib/FloatMixer.h \ soundlib/InstrumentExtensions.cpp soundlib/IntMixer.h \ soundlib/ITCompression.cpp soundlib/ITCompression.h \ soundlib/ITTools.cpp soundlib/ITTools.h soundlib/Load_669.cpp \ soundlib/Load_amf.cpp soundlib/Load_ams.cpp \ soundlib/Load_dbm.cpp soundlib/Load_digi.cpp \ soundlib/Load_dmf.cpp soundlib/Load_dsm.cpp \ soundlib/Load_dtm.cpp soundlib/Loaders.h soundlib/Load_far.cpp \ soundlib/Load_gdm.cpp soundlib/Load_imf.cpp \ soundlib/Load_it.cpp soundlib/Load_itp.cpp \ soundlib/load_j2b.cpp soundlib/Load_mdl.cpp \ soundlib/Load_med.cpp soundlib/Load_mid.cpp \ soundlib/Load_mo3.cpp soundlib/Load_mod.cpp \ soundlib/Load_mt2.cpp soundlib/Load_mtm.cpp \ soundlib/Load_okt.cpp soundlib/Load_plm.cpp \ soundlib/Load_psm.cpp soundlib/Load_ptm.cpp \ soundlib/Load_s3m.cpp soundlib/Load_sfx.cpp \ soundlib/Load_stm.cpp soundlib/Load_stp.cpp \ soundlib/Load_uax.cpp soundlib/Load_ult.cpp \ soundlib/Load_wav.cpp soundlib/Load_xm.cpp \ soundlib/Message.cpp soundlib/Message.h \ soundlib/MIDIEvents.cpp soundlib/MIDIEvents.h \ soundlib/MIDIMacros.cpp soundlib/MIDIMacros.h soundlib/Mixer.h \ soundlib/MixerInterface.h soundlib/MixerLoops.cpp \ soundlib/MixerLoops.h soundlib/MixerSettings.cpp \ soundlib/MixerSettings.h soundlib/MixFuncTable.cpp \ soundlib/MixFuncTable.h soundlib/ModChannel.cpp \ soundlib/ModChannel.h soundlib/modcommand.cpp \ soundlib/modcommand.h soundlib/ModInstrument.cpp \ soundlib/ModInstrument.h soundlib/ModSample.cpp \ soundlib/ModSample.h soundlib/ModSampleCopy.h \ soundlib/ModSequence.cpp soundlib/ModSequence.h \ soundlib/modsmp_ctrl.cpp soundlib/modsmp_ctrl.h \ soundlib/mod_specifications.cpp soundlib/mod_specifications.h \ soundlib/MPEGFrame.cpp soundlib/MPEGFrame.h \ soundlib/OggStream.cpp soundlib/OggStream.h soundlib/Paula.cpp \ soundlib/Paula.h soundlib/patternContainer.cpp \ soundlib/patternContainer.h soundlib/pattern.cpp \ soundlib/pattern.h soundlib/Resampler.h \ soundlib/RowVisitor.cpp soundlib/RowVisitor.h \ soundlib/S3MTools.cpp soundlib/S3MTools.h \ soundlib/SampleFormats.cpp soundlib/SampleFormatFLAC.cpp \ soundlib/SampleFormatMediaFoundation.cpp \ soundlib/SampleFormatMP3.cpp soundlib/SampleFormatOpus.cpp \ soundlib/SampleFormatVorbis.cpp soundlib/SampleIO.cpp \ soundlib/SampleIO.h soundlib/Snd_defs.h soundlib/Sndfile.cpp \ soundlib/Sndfile.h soundlib/Snd_flt.cpp soundlib/Snd_fx.cpp \ soundlib/Sndmix.cpp soundlib/SoundFilePlayConfig.cpp \ soundlib/SoundFilePlayConfig.h soundlib/Tables.cpp \ soundlib/Tables.h soundlib/Tagging.cpp soundlib/Tagging.h \ soundlib/tuningbase.cpp soundlib/tuningbase.h \ soundlib/tuningCollection.cpp soundlib/tuningcollection.h \ soundlib/tuning.cpp soundlib/tuning.h soundlib/UMXTools.cpp \ soundlib/UMXTools.h soundlib/UpgradeModule.cpp \ soundlib/WAVTools.cpp soundlib/WAVTools.h \ soundlib/WindowedFIR.cpp soundlib/WindowedFIR.h \ soundlib/XMTools.cpp soundlib/XMTools.h \ soundlib/plugins/dmo/DMOPlugin.cpp \ soundlib/plugins/dmo/DMOPlugin.h \ soundlib/plugins/dmo/Chorus.cpp soundlib/plugins/dmo/Chorus.h \ soundlib/plugins/dmo/Compressor.cpp \ soundlib/plugins/dmo/Compressor.h \ soundlib/plugins/dmo/Distortion.cpp \ soundlib/plugins/dmo/Distortion.h \ soundlib/plugins/dmo/Echo.cpp soundlib/plugins/dmo/Echo.h \ soundlib/plugins/dmo/Flanger.cpp \ soundlib/plugins/dmo/Flanger.h soundlib/plugins/dmo/Gargle.cpp \ soundlib/plugins/dmo/Gargle.h \ soundlib/plugins/dmo/I3DL2Reverb.cpp \ soundlib/plugins/dmo/I3DL2Reverb.h \ soundlib/plugins/dmo/ParamEq.cpp \ soundlib/plugins/dmo/ParamEq.h \ soundlib/plugins/dmo/WavesReverb.cpp \ soundlib/plugins/dmo/WavesReverb.h \ soundlib/plugins/DigiBoosterEcho.cpp \ soundlib/plugins/DigiBoosterEcho.h \ soundlib/plugins/LFOPlugin.cpp soundlib/plugins/LFOPlugin.h \ soundlib/plugins/PluginManager.cpp \ soundlib/plugins/PluginManager.h \ soundlib/plugins/PluginMixBuffer.h \ soundlib/plugins/PluginStructs.h \ soundlib/plugins/PlugInterface.cpp \ soundlib/plugins/PlugInterface.h sounddsp/AGC.cpp \ sounddsp/AGC.h sounddsp/DSP.cpp sounddsp/DSP.h sounddsp/EQ.cpp \ sounddsp/EQ.h sounddsp/Reverb.cpp sounddsp/Reverb.h \ libopenmpt/libopenmpt_c.cpp libopenmpt/libopenmpt_cxx.cpp \ libopenmpt/libopenmpt_ext_impl.cpp \ libopenmpt/libopenmpt_impl.cpp libopenmpt/libopenmpt_config.h \ libopenmpt/libopenmpt_ext.h libopenmpt/libopenmpt_ext.hpp \ libopenmpt/libopenmpt_ext_impl.hpp libopenmpt/libopenmpt.h \ libopenmpt/libopenmpt.hpp libopenmpt/libopenmpt_impl.hpp \ libopenmpt/libopenmpt_internal.h \ libopenmpt/libopenmpt_stream_callbacks_buffer.h \ libopenmpt/libopenmpt_stream_callbacks_fd.h \ libopenmpt/libopenmpt_stream_callbacks_file.h \ libopenmpt/libopenmpt_version.h am__objects_5 = common/libopenmpttest-ComponentManager.$(OBJEXT) \ common/libopenmpttest-FileReader.$(OBJEXT) \ common/libopenmpttest-Logging.$(OBJEXT) \ common/libopenmpttest-misc_util.$(OBJEXT) \ common/libopenmpttest-mptCPU.$(OBJEXT) \ common/libopenmpttest-mptFileIO.$(OBJEXT) \ common/libopenmpttest-mptIO.$(OBJEXT) \ common/libopenmpttest-mptLibrary.$(OBJEXT) \ common/libopenmpttest-mptOS.$(OBJEXT) \ common/libopenmpttest-mptPathString.$(OBJEXT) \ common/libopenmpttest-mptRandom.$(OBJEXT) \ common/libopenmpttest-mptString.$(OBJEXT) \ common/libopenmpttest-mptStringFormat.$(OBJEXT) \ common/libopenmpttest-mptStringParse.$(OBJEXT) \ common/libopenmpttest-mptTime.$(OBJEXT) \ common/libopenmpttest-mptUUID.$(OBJEXT) \ common/libopenmpttest-mptWine.$(OBJEXT) \ common/libopenmpttest-Profiler.$(OBJEXT) \ common/libopenmpttest-serialization_utils.$(OBJEXT) \ common/libopenmpttest-stdafx.$(OBJEXT) \ common/libopenmpttest-typedefs.$(OBJEXT) \ common/libopenmpttest-version.$(OBJEXT) am__objects_6 = \ soundlib/libopenmpttest-AudioCriticalSection.$(OBJEXT) \ soundlib/libopenmpttest-ContainerMMCMP.$(OBJEXT) \ soundlib/libopenmpttest-ContainerPP20.$(OBJEXT) \ soundlib/libopenmpttest-ContainerUMX.$(OBJEXT) \ soundlib/libopenmpttest-ContainerXPK.$(OBJEXT) \ soundlib/libopenmpttest-Dither.$(OBJEXT) \ soundlib/libopenmpttest-Dlsbank.$(OBJEXT) \ soundlib/libopenmpttest-Fastmix.$(OBJEXT) \ soundlib/libopenmpttest-InstrumentExtensions.$(OBJEXT) \ soundlib/libopenmpttest-ITCompression.$(OBJEXT) \ soundlib/libopenmpttest-ITTools.$(OBJEXT) \ soundlib/libopenmpttest-Load_669.$(OBJEXT) \ soundlib/libopenmpttest-Load_amf.$(OBJEXT) \ soundlib/libopenmpttest-Load_ams.$(OBJEXT) \ soundlib/libopenmpttest-Load_dbm.$(OBJEXT) \ soundlib/libopenmpttest-Load_digi.$(OBJEXT) \ soundlib/libopenmpttest-Load_dmf.$(OBJEXT) \ soundlib/libopenmpttest-Load_dsm.$(OBJEXT) \ soundlib/libopenmpttest-Load_dtm.$(OBJEXT) \ soundlib/libopenmpttest-Load_far.$(OBJEXT) \ soundlib/libopenmpttest-Load_gdm.$(OBJEXT) \ soundlib/libopenmpttest-Load_imf.$(OBJEXT) \ soundlib/libopenmpttest-Load_it.$(OBJEXT) \ soundlib/libopenmpttest-Load_itp.$(OBJEXT) \ soundlib/libopenmpttest-load_j2b.$(OBJEXT) \ soundlib/libopenmpttest-Load_mdl.$(OBJEXT) \ soundlib/libopenmpttest-Load_med.$(OBJEXT) \ soundlib/libopenmpttest-Load_mid.$(OBJEXT) \ soundlib/libopenmpttest-Load_mo3.$(OBJEXT) \ soundlib/libopenmpttest-Load_mod.$(OBJEXT) \ soundlib/libopenmpttest-Load_mt2.$(OBJEXT) \ soundlib/libopenmpttest-Load_mtm.$(OBJEXT) \ soundlib/libopenmpttest-Load_okt.$(OBJEXT) \ soundlib/libopenmpttest-Load_plm.$(OBJEXT) \ soundlib/libopenmpttest-Load_psm.$(OBJEXT) \ soundlib/libopenmpttest-Load_ptm.$(OBJEXT) \ soundlib/libopenmpttest-Load_s3m.$(OBJEXT) \ soundlib/libopenmpttest-Load_sfx.$(OBJEXT) \ soundlib/libopenmpttest-Load_stm.$(OBJEXT) \ soundlib/libopenmpttest-Load_stp.$(OBJEXT) \ soundlib/libopenmpttest-Load_uax.$(OBJEXT) \ soundlib/libopenmpttest-Load_ult.$(OBJEXT) \ soundlib/libopenmpttest-Load_wav.$(OBJEXT) \ soundlib/libopenmpttest-Load_xm.$(OBJEXT) \ soundlib/libopenmpttest-Message.$(OBJEXT) \ soundlib/libopenmpttest-MIDIEvents.$(OBJEXT) \ soundlib/libopenmpttest-MIDIMacros.$(OBJEXT) \ soundlib/libopenmpttest-MixerLoops.$(OBJEXT) \ soundlib/libopenmpttest-MixerSettings.$(OBJEXT) \ soundlib/libopenmpttest-MixFuncTable.$(OBJEXT) \ soundlib/libopenmpttest-ModChannel.$(OBJEXT) \ soundlib/libopenmpttest-modcommand.$(OBJEXT) \ soundlib/libopenmpttest-ModInstrument.$(OBJEXT) \ soundlib/libopenmpttest-ModSample.$(OBJEXT) \ soundlib/libopenmpttest-ModSequence.$(OBJEXT) \ soundlib/libopenmpttest-modsmp_ctrl.$(OBJEXT) \ soundlib/libopenmpttest-mod_specifications.$(OBJEXT) \ soundlib/libopenmpttest-MPEGFrame.$(OBJEXT) \ soundlib/libopenmpttest-OggStream.$(OBJEXT) \ soundlib/libopenmpttest-Paula.$(OBJEXT) \ soundlib/libopenmpttest-patternContainer.$(OBJEXT) \ soundlib/libopenmpttest-pattern.$(OBJEXT) \ soundlib/libopenmpttest-RowVisitor.$(OBJEXT) \ soundlib/libopenmpttest-S3MTools.$(OBJEXT) \ soundlib/libopenmpttest-SampleFormats.$(OBJEXT) \ soundlib/libopenmpttest-SampleFormatFLAC.$(OBJEXT) \ soundlib/libopenmpttest-SampleFormatMediaFoundation.$(OBJEXT) \ soundlib/libopenmpttest-SampleFormatMP3.$(OBJEXT) \ soundlib/libopenmpttest-SampleFormatOpus.$(OBJEXT) \ soundlib/libopenmpttest-SampleFormatVorbis.$(OBJEXT) \ soundlib/libopenmpttest-SampleIO.$(OBJEXT) \ soundlib/libopenmpttest-Sndfile.$(OBJEXT) \ soundlib/libopenmpttest-Snd_flt.$(OBJEXT) \ soundlib/libopenmpttest-Snd_fx.$(OBJEXT) \ soundlib/libopenmpttest-Sndmix.$(OBJEXT) \ soundlib/libopenmpttest-SoundFilePlayConfig.$(OBJEXT) \ soundlib/libopenmpttest-Tables.$(OBJEXT) \ soundlib/libopenmpttest-Tagging.$(OBJEXT) \ soundlib/libopenmpttest-tuningbase.$(OBJEXT) \ soundlib/libopenmpttest-tuningCollection.$(OBJEXT) \ soundlib/libopenmpttest-tuning.$(OBJEXT) \ soundlib/libopenmpttest-UMXTools.$(OBJEXT) \ soundlib/libopenmpttest-UpgradeModule.$(OBJEXT) \ soundlib/libopenmpttest-WAVTools.$(OBJEXT) \ soundlib/libopenmpttest-WindowedFIR.$(OBJEXT) \ soundlib/libopenmpttest-XMTools.$(OBJEXT) \ soundlib/plugins/dmo/libopenmpttest-DMOPlugin.$(OBJEXT) \ soundlib/plugins/dmo/libopenmpttest-Chorus.$(OBJEXT) \ soundlib/plugins/dmo/libopenmpttest-Compressor.$(OBJEXT) \ soundlib/plugins/dmo/libopenmpttest-Distortion.$(OBJEXT) \ soundlib/plugins/dmo/libopenmpttest-Echo.$(OBJEXT) \ soundlib/plugins/dmo/libopenmpttest-Flanger.$(OBJEXT) \ soundlib/plugins/dmo/libopenmpttest-Gargle.$(OBJEXT) \ soundlib/plugins/dmo/libopenmpttest-I3DL2Reverb.$(OBJEXT) \ soundlib/plugins/dmo/libopenmpttest-ParamEq.$(OBJEXT) \ soundlib/plugins/dmo/libopenmpttest-WavesReverb.$(OBJEXT) \ soundlib/plugins/libopenmpttest-DigiBoosterEcho.$(OBJEXT) \ soundlib/plugins/libopenmpttest-LFOPlugin.$(OBJEXT) \ soundlib/plugins/libopenmpttest-PluginManager.$(OBJEXT) \ soundlib/plugins/libopenmpttest-PlugInterface.$(OBJEXT) am__objects_7 = sounddsp/libopenmpttest-AGC.$(OBJEXT) \ sounddsp/libopenmpttest-DSP.$(OBJEXT) \ sounddsp/libopenmpttest-EQ.$(OBJEXT) \ sounddsp/libopenmpttest-Reverb.$(OBJEXT) @ENABLE_TESTS_TRUE@am_libopenmpttest_OBJECTS = libopenmpt/libopenmpttest-libopenmpt_test.$(OBJEXT) \ @ENABLE_TESTS_TRUE@ test/libopenmpttest-test.$(OBJEXT) \ @ENABLE_TESTS_TRUE@ test/libopenmpttest-TestToolsLib.$(OBJEXT) \ @ENABLE_TESTS_TRUE@ $(am__objects_5) $(am__objects_2) \ @ENABLE_TESTS_TRUE@ $(am__objects_6) $(am__objects_7) \ @ENABLE_TESTS_TRUE@ libopenmpt/libopenmpttest-libopenmpt_c.$(OBJEXT) \ @ENABLE_TESTS_TRUE@ libopenmpt/libopenmpttest-libopenmpt_cxx.$(OBJEXT) \ @ENABLE_TESTS_TRUE@ libopenmpt/libopenmpttest-libopenmpt_ext_impl.$(OBJEXT) \ @ENABLE_TESTS_TRUE@ libopenmpt/libopenmpttest-libopenmpt_impl.$(OBJEXT) libopenmpttest_OBJECTS = $(am_libopenmpttest_OBJECTS) @ENABLE_TESTS_TRUE@libopenmpttest_DEPENDENCIES = \ @ENABLE_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @ENABLE_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @ENABLE_TESTS_TRUE@ $(am__DEPENDENCIES_1) libopenmpttest_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = SOURCES = $(libmodplug_la_SOURCES) $(libopenmpt_la_SOURCES) \ $(libopenmpt_modplug_la_SOURCES) $(bin_openmpt123_SOURCES) \ $(libopenmpt_example_c_SOURCES) \ $(libopenmpt_example_c_mem_SOURCES) \ $(libopenmpt_example_c_probe_SOURCES) \ $(libopenmpt_example_c_stdout_SOURCES) \ $(libopenmpt_example_c_unsafe_SOURCES) \ $(libopenmpt_example_cxx_SOURCES) $(libopenmpttest_SOURCES) DIST_SOURCES = $(am__libmodplug_la_SOURCES_DIST) \ $(libopenmpt_la_SOURCES) \ $(am__libopenmpt_modplug_la_SOURCES_DIST) \ $(am__bin_openmpt123_SOURCES_DIST) \ $(am__libopenmpt_example_c_SOURCES_DIST) \ $(am__libopenmpt_example_c_mem_SOURCES_DIST) \ $(am__libopenmpt_example_c_probe_SOURCES_DIST) \ $(am__libopenmpt_example_c_stdout_SOURCES_DIST) \ $(am__libopenmpt_example_c_unsafe_SOURCES_DIST) \ $(am__libopenmpt_example_cxx_SOURCES_DIST) \ $(am__libopenmpttest_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac man1dir = $(mandir)/man1 NROFF = nroff MANS = $(man1_MANS) DATA = $(dist_doc_DATA) $(nobase_dist_doc_DATA) $(pkgconfig_DATA) am__nobase_include_HEADERS_DIST = libopenmpt/libopenmpt.h \ libopenmpt/libopenmpt.hpp libopenmpt/libopenmpt_version.h \ libopenmpt/libopenmpt_config.h \ libopenmpt/libopenmpt_stream_callbacks_buffer.h \ libopenmpt/libopenmpt_stream_callbacks_fd.h \ libopenmpt/libopenmpt_stream_callbacks_file.h \ libopenmpt/libopenmpt_ext.h libopenmpt/libopenmpt_ext.hpp \ libmodplug/modplug.h libmodplug/sndfile.h libmodplug/stdafx.h HEADERS = $(nobase_include_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ $(LISP)config.h.in # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags CSCOPE = cscope AM_RECURSIVE_TARGETS = cscope check recheck am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` RECHECK_LOGS = $(TEST_LOGS) TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) am__DIST_COMMON = $(srcdir)/Doxyfile.in $(srcdir)/Makefile.in \ $(srcdir)/config.h.in $(top_srcdir)/build-aux/ar-lib \ $(top_srcdir)/build-aux/compile \ $(top_srcdir)/build-aux/config.guess \ $(top_srcdir)/build-aux/config.sub \ $(top_srcdir)/build-aux/depcomp \ $(top_srcdir)/build-aux/install-sh \ $(top_srcdir)/build-aux/ltmain.sh \ $(top_srcdir)/build-aux/missing \ $(top_srcdir)/build-aux/test-driver \ $(top_srcdir)/libmodplug/libmodplug.pc.in \ $(top_srcdir)/libopenmpt/libopenmpt.pc.in build-aux/ar-lib \ build-aux/compile build-aux/config.guess build-aux/config.sub \ build-aux/depcomp build-aux/install-sh build-aux/ltmain.sh \ build-aux/missing DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__post_remove_distdir = $(am__remove_distdir) DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best DIST_TARGETS = dist-gzip distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CXXSTDLIB_PCLIBSPRIVATE = @CXXSTDLIB_PCLIBSPRIVATE@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOXYGEN_PAPER_SIZE = @DOXYGEN_PAPER_SIZE@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DX_CONFIG = @DX_CONFIG@ DX_DOCDIR = @DX_DOCDIR@ DX_DOT = @DX_DOT@ DX_DOXYGEN = @DX_DOXYGEN@ DX_DVIPS = @DX_DVIPS@ DX_EGREP = @DX_EGREP@ DX_ENV = @DX_ENV@ DX_FLAG_chi = @DX_FLAG_chi@ DX_FLAG_chm = @DX_FLAG_chm@ DX_FLAG_doc = @DX_FLAG_doc@ DX_FLAG_dot = @DX_FLAG_dot@ DX_FLAG_html = @DX_FLAG_html@ DX_FLAG_man = @DX_FLAG_man@ DX_FLAG_pdf = @DX_FLAG_pdf@ DX_FLAG_ps = @DX_FLAG_ps@ DX_FLAG_rtf = @DX_FLAG_rtf@ DX_FLAG_xml = @DX_FLAG_xml@ DX_HHC = @DX_HHC@ DX_LATEX = @DX_LATEX@ DX_MAKEINDEX = @DX_MAKEINDEX@ DX_PDFLATEX = @DX_PDFLATEX@ DX_PERL = @DX_PERL@ DX_PROJECT = @DX_PROJECT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FLAC_CFLAGS = @FLAC_CFLAGS@ FLAC_LIBS = @FLAC_LIBS@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBOPENMPT_LIBS_PRIVATE = @LIBOPENMPT_LIBS_PRIVATE@ LIBOPENMPT_LTVER_AGE = @LIBOPENMPT_LTVER_AGE@ LIBOPENMPT_LTVER_CURRENT = @LIBOPENMPT_LTVER_CURRENT@ LIBOPENMPT_LTVER_REVISION = @LIBOPENMPT_LTVER_REVISION@ LIBOPENMPT_REQUIRES_PRIVATE = @LIBOPENMPT_REQUIRES_PRIVATE@ LIBOPENMPT_WIN32_LIBS = @LIBOPENMPT_WIN32_LIBS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MPG123_CFLAGS = @MPG123_CFLAGS@ MPG123_LIBS = @MPG123_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OGG_CFLAGS = @OGG_CFLAGS@ OGG_LIBS = @OGG_LIBS@ OPENMPT123_WIN32_LIBS = @OPENMPT123_WIN32_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PORTAUDIOCPP_CFLAGS = @PORTAUDIOCPP_CFLAGS@ PORTAUDIOCPP_LIBS = @PORTAUDIOCPP_LIBS@ PORTAUDIO_CFLAGS = @PORTAUDIO_CFLAGS@ PORTAUDIO_LIBS = @PORTAUDIO_LIBS@ PULSEAUDIO_CFLAGS = @PULSEAUDIO_CFLAGS@ PULSEAUDIO_LIBS = @PULSEAUDIO_LIBS@ RANLIB = @RANLIB@ SDL2_CFLAGS = @SDL2_CFLAGS@ SDL2_LIBS = @SDL2_LIBS@ SDL_CFLAGS = @SDL_CFLAGS@ SDL_LIBS = @SDL_LIBS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNDFILE_CFLAGS = @SNDFILE_CFLAGS@ SNDFILE_LIBS = @SNDFILE_LIBS@ STRIP = @STRIP@ VERSION = @VERSION@ VORBISFILE_CFLAGS = @VORBISFILE_CFLAGS@ VORBISFILE_LIBS = @VORBISFILE_LIBS@ VORBIS_CFLAGS = @VORBIS_CFLAGS@ VORBIS_LIBS = @VORBIS_LIBS@ WIN32_CONSOLE_CFLAGS = @WIN32_CONSOLE_CFLAGS@ WIN32_CONSOLE_CXXFLAGS = @WIN32_CONSOLE_CXXFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ ACLOCAL_AMFLAGS = -I m4 --install EXTRA_DIST = m4/emptydir libopenmpt/libopenmpt.pc.in \ libmodplug/libmodplug.pc.in LICENSE README.md Doxyfile.in \ libopenmpt/dox/changelog.md libopenmpt/dox/dependencies.md \ libopenmpt/dox/index.dox libopenmpt/dox/packaging.md \ libopenmpt/dox/quickstart.md libopenmpt/dox/tests.md \ libopenmpt/dox/todo.md libopenmpt/libopenmpt_version.mk \ test/test.xm test/test.s3m test/test.mptm man/openmpt123.1 \ examples/.clang-format \ libopenmpt/bindings/freebasic/libopenmpt.bi MOSTLYCLEANFILES = $(DX_CLEANFILES) dist_doc_DATA = LICENSE README.md nobase_dist_doc_DATA = examples/libopenmpt_example_cxx.cpp \ examples/libopenmpt_example_c_mem.c \ examples/libopenmpt_example_c_unsafe.c \ examples/libopenmpt_example_c.c \ examples/libopenmpt_example_c_probe.c \ examples/libopenmpt_example_c_stdout.c lib_LTLIBRARIES = libopenmpt.la $(am__append_4) $(am__append_6) @ENABLE_EXAMPLES_TRUE@libopenmpt_example_c_stdout_SOURCES = examples/libopenmpt_example_c_stdout.c @ENABLE_EXAMPLES_TRUE@libopenmpt_example_c_probe_SOURCES = examples/libopenmpt_example_c_probe.c @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIO_TRUE@libopenmpt_example_c_SOURCES = examples/libopenmpt_example_c.c @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIO_TRUE@libopenmpt_example_c_mem_SOURCES = examples/libopenmpt_example_c_mem.c @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIO_TRUE@libopenmpt_example_c_unsafe_SOURCES = examples/libopenmpt_example_c_unsafe.c @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIOCPP_TRUE@libopenmpt_example_cxx_SOURCES = examples/libopenmpt_example_cxx.cpp @ENABLE_EXAMPLES_TRUE@libopenmpt_example_c_stdout_CPPFLAGS = @ENABLE_EXAMPLES_TRUE@libopenmpt_example_c_probe_CPPFLAGS = @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIO_TRUE@libopenmpt_example_c_CPPFLAGS = $(PORTAUDIO_CFLAGS) @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIO_TRUE@libopenmpt_example_c_mem_CPPFLAGS = $(PORTAUDIO_CFLAGS) @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIO_TRUE@libopenmpt_example_c_unsafe_CPPFLAGS = $(PORTAUDIO_CFLAGS) @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIOCPP_TRUE@libopenmpt_example_cxx_CPPFLAGS = $(PORTAUDIOCPP_CFLAGS) @ENABLE_EXAMPLES_TRUE@libopenmpt_example_c_stdout_CFLAGS = $(WIN32_CONSOLE_CFLAGS) @ENABLE_EXAMPLES_TRUE@libopenmpt_example_c_probe_CFLAGS = $(WIN32_CONSOLE_CFLAGS) @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIO_TRUE@libopenmpt_example_c_CFLAGS = $(WIN32_CONSOLE_CFLAGS) @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIO_TRUE@libopenmpt_example_c_mem_CFLAGS = $(WIN32_CONSOLE_CFLAGS) @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIO_TRUE@libopenmpt_example_c_unsafe_CFLAGS = $(WIN32_CONSOLE_CFLAGS) @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIOCPP_TRUE@libopenmpt_example_cxx_CXXFLAGS = $(WIN32_CONSOLE_CXXFLAGS) @ENABLE_EXAMPLES_TRUE@libopenmpt_example_c_stdout_LDADD = $(lib_LTLIBRARIES) @ENABLE_EXAMPLES_TRUE@libopenmpt_example_c_probe_LDADD = $(lib_LTLIBRARIES) @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIO_TRUE@libopenmpt_example_c_LDADD = $(lib_LTLIBRARIES) $(PORTAUDIO_LIBS) @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIO_TRUE@libopenmpt_example_c_mem_LDADD = $(lib_LTLIBRARIES) $(PORTAUDIO_LIBS) @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIO_TRUE@libopenmpt_example_c_unsafe_LDADD = $(lib_LTLIBRARIES) $(PORTAUDIO_LIBS) @ENABLE_EXAMPLES_TRUE@@HAVE_PORTAUDIOCPP_TRUE@libopenmpt_example_cxx_LDADD = $(lib_LTLIBRARIES) $(PORTAUDIOCPP_LIBS) pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libopenmpt/libopenmpt.pc $(am__append_5) nobase_include_HEADERS = libopenmpt/libopenmpt.h \ libopenmpt/libopenmpt.hpp libopenmpt/libopenmpt_version.h \ libopenmpt/libopenmpt_config.h \ libopenmpt/libopenmpt_stream_callbacks_buffer.h \ libopenmpt/libopenmpt_stream_callbacks_fd.h \ libopenmpt/libopenmpt_stream_callbacks_file.h \ libopenmpt/libopenmpt_ext.h libopenmpt/libopenmpt_ext.hpp \ $(am__append_7) MPT_FILES_COMMON = common/BuildSettings.h common/CompilerDetect.h \ common/ComponentManager.cpp common/ComponentManager.h \ common/Endianness.h common/FileReader.cpp common/FileReader.h \ common/FileReaderFwd.h common/FlagSet.h common/Logging.cpp \ common/Logging.h common/misc_util.cpp common/misc_util.h \ common/mptBufferIO.h common/mptCPU.cpp common/mptCPU.h \ common/mptCRC.h common/mptFileIO.cpp common/mptFileIO.h \ common/mptIO.cpp common/mptIO.h common/mptLibrary.cpp \ common/mptLibrary.h common/mptMutex.h common/mptOS.cpp \ common/mptOS.h common/mptPathString.cpp common/mptPathString.h \ common/mptRandom.cpp common/mptRandom.h common/mptString.cpp \ common/mptString.h common/mptStringFormat.cpp \ common/mptStringFormat.h common/mptStringParse.cpp \ common/mptStringParse.h common/mptThread.h common/mptTime.cpp \ common/mptTime.h common/mptTypeTraits.h common/mptUUID.cpp \ common/mptUUID.h common/mptWine.cpp common/mptWine.h \ common/Profiler.cpp common/Profiler.h \ common/serialization_utils.cpp common/serialization_utils.h \ common/stdafx.cpp common/stdafx.h common/StringFixer.h \ common/typedefs.cpp common/typedefs.h common/version.cpp \ common/version.h common/versionNumber.h MPT_FILES_SOUNDBASE = soundbase/SampleFormat.h \ soundbase/SampleFormatConverters.h \ soundbase/SampleFormatCopy.h MPT_FILES_SOUNDLIB = soundlib/AudioCriticalSection.cpp \ soundlib/AudioCriticalSection.h soundlib/AudioReadTarget.h \ soundlib/ChunkReader.h soundlib/ContainerMMCMP.cpp \ soundlib/ContainerPP20.cpp soundlib/ContainerUMX.cpp \ soundlib/ContainerXPK.cpp soundlib/Container.h \ soundlib/Dither.cpp soundlib/Dither.h soundlib/Dlsbank.cpp \ soundlib/Dlsbank.h soundlib/Fastmix.cpp soundlib/FloatMixer.h \ soundlib/InstrumentExtensions.cpp soundlib/IntMixer.h \ soundlib/ITCompression.cpp soundlib/ITCompression.h \ soundlib/ITTools.cpp soundlib/ITTools.h soundlib/Load_669.cpp \ soundlib/Load_amf.cpp soundlib/Load_ams.cpp \ soundlib/Load_dbm.cpp soundlib/Load_digi.cpp \ soundlib/Load_dmf.cpp soundlib/Load_dsm.cpp \ soundlib/Load_dtm.cpp soundlib/Loaders.h soundlib/Load_far.cpp \ soundlib/Load_gdm.cpp soundlib/Load_imf.cpp \ soundlib/Load_it.cpp soundlib/Load_itp.cpp \ soundlib/load_j2b.cpp soundlib/Load_mdl.cpp \ soundlib/Load_med.cpp soundlib/Load_mid.cpp \ soundlib/Load_mo3.cpp soundlib/Load_mod.cpp \ soundlib/Load_mt2.cpp soundlib/Load_mtm.cpp \ soundlib/Load_okt.cpp soundlib/Load_plm.cpp \ soundlib/Load_psm.cpp soundlib/Load_ptm.cpp \ soundlib/Load_s3m.cpp soundlib/Load_sfx.cpp \ soundlib/Load_stm.cpp soundlib/Load_stp.cpp \ soundlib/Load_uax.cpp soundlib/Load_ult.cpp \ soundlib/Load_wav.cpp soundlib/Load_xm.cpp \ soundlib/Message.cpp soundlib/Message.h \ soundlib/MIDIEvents.cpp soundlib/MIDIEvents.h \ soundlib/MIDIMacros.cpp soundlib/MIDIMacros.h soundlib/Mixer.h \ soundlib/MixerInterface.h soundlib/MixerLoops.cpp \ soundlib/MixerLoops.h soundlib/MixerSettings.cpp \ soundlib/MixerSettings.h soundlib/MixFuncTable.cpp \ soundlib/MixFuncTable.h soundlib/ModChannel.cpp \ soundlib/ModChannel.h soundlib/modcommand.cpp \ soundlib/modcommand.h soundlib/ModInstrument.cpp \ soundlib/ModInstrument.h soundlib/ModSample.cpp \ soundlib/ModSample.h soundlib/ModSampleCopy.h \ soundlib/ModSequence.cpp soundlib/ModSequence.h \ soundlib/modsmp_ctrl.cpp soundlib/modsmp_ctrl.h \ soundlib/mod_specifications.cpp soundlib/mod_specifications.h \ soundlib/MPEGFrame.cpp soundlib/MPEGFrame.h \ soundlib/OggStream.cpp soundlib/OggStream.h soundlib/Paula.cpp \ soundlib/Paula.h soundlib/patternContainer.cpp \ soundlib/patternContainer.h soundlib/pattern.cpp \ soundlib/pattern.h soundlib/Resampler.h \ soundlib/RowVisitor.cpp soundlib/RowVisitor.h \ soundlib/S3MTools.cpp soundlib/S3MTools.h \ soundlib/SampleFormats.cpp soundlib/SampleFormatFLAC.cpp \ soundlib/SampleFormatMediaFoundation.cpp \ soundlib/SampleFormatMP3.cpp soundlib/SampleFormatOpus.cpp \ soundlib/SampleFormatVorbis.cpp soundlib/SampleIO.cpp \ soundlib/SampleIO.h soundlib/Snd_defs.h soundlib/Sndfile.cpp \ soundlib/Sndfile.h soundlib/Snd_flt.cpp soundlib/Snd_fx.cpp \ soundlib/Sndmix.cpp soundlib/SoundFilePlayConfig.cpp \ soundlib/SoundFilePlayConfig.h soundlib/Tables.cpp \ soundlib/Tables.h soundlib/Tagging.cpp soundlib/Tagging.h \ soundlib/tuningbase.cpp soundlib/tuningbase.h \ soundlib/tuningCollection.cpp soundlib/tuningcollection.h \ soundlib/tuning.cpp soundlib/tuning.h soundlib/UMXTools.cpp \ soundlib/UMXTools.h soundlib/UpgradeModule.cpp \ soundlib/WAVTools.cpp soundlib/WAVTools.h \ soundlib/WindowedFIR.cpp soundlib/WindowedFIR.h \ soundlib/XMTools.cpp soundlib/XMTools.h \ soundlib/plugins/dmo/DMOPlugin.cpp \ soundlib/plugins/dmo/DMOPlugin.h \ soundlib/plugins/dmo/Chorus.cpp soundlib/plugins/dmo/Chorus.h \ soundlib/plugins/dmo/Compressor.cpp \ soundlib/plugins/dmo/Compressor.h \ soundlib/plugins/dmo/Distortion.cpp \ soundlib/plugins/dmo/Distortion.h \ soundlib/plugins/dmo/Echo.cpp soundlib/plugins/dmo/Echo.h \ soundlib/plugins/dmo/Flanger.cpp \ soundlib/plugins/dmo/Flanger.h soundlib/plugins/dmo/Gargle.cpp \ soundlib/plugins/dmo/Gargle.h \ soundlib/plugins/dmo/I3DL2Reverb.cpp \ soundlib/plugins/dmo/I3DL2Reverb.h \ soundlib/plugins/dmo/ParamEq.cpp \ soundlib/plugins/dmo/ParamEq.h \ soundlib/plugins/dmo/WavesReverb.cpp \ soundlib/plugins/dmo/WavesReverb.h \ soundlib/plugins/DigiBoosterEcho.cpp \ soundlib/plugins/DigiBoosterEcho.h \ soundlib/plugins/LFOPlugin.cpp soundlib/plugins/LFOPlugin.h \ soundlib/plugins/PluginManager.cpp \ soundlib/plugins/PluginManager.h \ soundlib/plugins/PluginMixBuffer.h \ soundlib/plugins/PluginStructs.h \ soundlib/plugins/PlugInterface.cpp \ soundlib/plugins/PlugInterface.h MPT_FILES_SOUNDDSP = sounddsp/AGC.cpp sounddsp/AGC.h sounddsp/DSP.cpp \ sounddsp/DSP.h sounddsp/EQ.cpp sounddsp/EQ.h \ sounddsp/Reverb.cpp sounddsp/Reverb.h libopenmpt_la_LDFLAGS = -version-info $(LIBOPENMPT_LTVER_CURRENT):$(LIBOPENMPT_LTVER_REVISION):$(LIBOPENMPT_LTVER_AGE) -no-undefined libopenmpt_la_CPPFLAGS = -DLIBOPENMPT_BUILD -I$(srcdir)/build/svn_version -I$(srcdir)/ -I$(srcdir)/common $(ZLIB_CFLAGS) $(MPG123_CFLAGS) $(OGG_CFLAGS) $(VORBIS_CFLAGS) $(VORBISFILE_CFLAGS) libopenmpt_la_CXXFLAGS = $(ZLIB_CFLAGS) $(MPG123_CFLAGS) $(OGG_CFLAGS) $(VORBIS_CFLAGS) $(VORBISFILE_CFLAGS) libopenmpt_la_CFLAGS = $(ZLIB_CFLAGS) $(MPG123_CFLAGS) $(OGG_CFLAGS) $(VORBIS_CFLAGS) $(VORBISFILE_CFLAGS) libopenmpt_la_LIBADD = $(ZLIB_LIBS) $(MPG123_LIBS) $(OGG_LIBS) $(VORBIS_LIBS) $(VORBISFILE_LIBS) $(LIBOPENMPT_WIN32_LIBS) libopenmpt_la_SOURCES = build/svn_version/svn_version.h \ $(MPT_FILES_COMMON) $(MPT_FILES_SOUNDBASE) \ $(MPT_FILES_SOUNDLIB) $(MPT_FILES_SOUNDDSP) \ libopenmpt/libopenmpt_c.cpp libopenmpt/libopenmpt_cxx.cpp \ libopenmpt/libopenmpt_ext_impl.cpp \ libopenmpt/libopenmpt_impl.cpp libopenmpt/libopenmpt_config.h \ libopenmpt/libopenmpt_ext.h libopenmpt/libopenmpt_ext.hpp \ libopenmpt/libopenmpt_ext_impl.hpp libopenmpt/libopenmpt.h \ libopenmpt/libopenmpt.hpp libopenmpt/libopenmpt_impl.hpp \ libopenmpt/libopenmpt_internal.h \ libopenmpt/libopenmpt_stream_callbacks_buffer.h \ libopenmpt/libopenmpt_stream_callbacks_fd.h \ libopenmpt/libopenmpt_stream_callbacks_file.h \ libopenmpt/libopenmpt_version.h @ENABLE_LIBOPENMPT_MODPLUG_TRUE@libopenmpt_modplug_la_LDFLAGS = -version-info 1:0:0 -no-undefined @ENABLE_LIBOPENMPT_MODPLUG_TRUE@libopenmpt_modplug_la_CPPFLAGS = -I$(srcdir)/ @ENABLE_LIBOPENMPT_MODPLUG_TRUE@libopenmpt_modplug_la_CXXFLAGS = @ENABLE_LIBOPENMPT_MODPLUG_TRUE@libopenmpt_modplug_la_CFLAGS = @ENABLE_LIBOPENMPT_MODPLUG_TRUE@libopenmpt_modplug_la_LIBADD = libopenmpt.la @ENABLE_LIBOPENMPT_MODPLUG_TRUE@libopenmpt_modplug_la_SOURCES = libopenmpt/libopenmpt_modplug.c \ @ENABLE_LIBOPENMPT_MODPLUG_TRUE@ libopenmpt/libopenmpt_modplug_cpp.cpp @ENABLE_LIBMODPLUG_TRUE@libmodplug_la_LDFLAGS = -version-info 1:0:0 -no-undefined @ENABLE_LIBMODPLUG_TRUE@libmodplug_la_CPPFLAGS = -I$(srcdir)/ @ENABLE_LIBMODPLUG_TRUE@libmodplug_la_CXXFLAGS = @ENABLE_LIBMODPLUG_TRUE@libmodplug_la_CFLAGS = @ENABLE_LIBMODPLUG_TRUE@libmodplug_la_LIBADD = libopenmpt.la @ENABLE_LIBMODPLUG_TRUE@libmodplug_la_SOURCES = \ @ENABLE_LIBMODPLUG_TRUE@ libopenmpt/libopenmpt_modplug.c \ @ENABLE_LIBMODPLUG_TRUE@ libopenmpt/libopenmpt_modplug_cpp.cpp @ENABLE_TESTS_TRUE@libopenmpttest_CPPFLAGS = -DLIBOPENMPT_BUILD -DLIBOPENMPT_BUILD_TEST -I$(srcdir)/build/svn_version -I$(srcdir)/ -I$(srcdir)/common $(ZLIB_CFLAGS) $(MPG123_CFLAGS) $(OGG_CFLAGS) $(VORBIS_CFLAGS) $(VORBISFILE_CFLAGS) @ENABLE_TESTS_TRUE@libopenmpttest_CXXFLAGS = $(ZLIB_CFLAGS) $(MPG123_CFLAGS) $(OGG_CFLAGS) $(VORBIS_CFLAGS) $(VORBISFILE_CFLAGS) $(WIN32_CONSOLE_CXXFLAGS) @ENABLE_TESTS_TRUE@libopenmpttest_CFLAGS = $(ZLIB_CFLAGS) $(MPG123_CFLAGS) $(OGG_CFLAGS) $(VORBIS_CFLAGS) $(VORBISFILE_CFLAGS) $(WIN32_CONSOLE_CFLAGS) @ENABLE_TESTS_TRUE@libopenmpttest_LDADD = $(ZLIB_LIBS) $(MPG123_LIBS) $(OGG_LIBS) $(VORBIS_LIBS) $(VORBISFILE_LIBS) $(LIBOPENMPT_WIN32_LIB) @ENABLE_TESTS_TRUE@libopenmpttest_SOURCES = \ @ENABLE_TESTS_TRUE@ libopenmpt/libopenmpt_test.cpp \ @ENABLE_TESTS_TRUE@ test/test.cpp test/test.h test/TestTools.h \ @ENABLE_TESTS_TRUE@ test/TestToolsLib.cpp test/TestToolsLib.h \ @ENABLE_TESTS_TRUE@ test/TestToolsTracker.h \ @ENABLE_TESTS_TRUE@ build/svn_version/svn_version.h \ @ENABLE_TESTS_TRUE@ $(MPT_FILES_COMMON) $(MPT_FILES_SOUNDBASE) \ @ENABLE_TESTS_TRUE@ $(MPT_FILES_SOUNDLIB) $(MPT_FILES_SOUNDDSP) \ @ENABLE_TESTS_TRUE@ libopenmpt/libopenmpt_c.cpp \ @ENABLE_TESTS_TRUE@ libopenmpt/libopenmpt_cxx.cpp \ @ENABLE_TESTS_TRUE@ libopenmpt/libopenmpt_ext_impl.cpp \ @ENABLE_TESTS_TRUE@ libopenmpt/libopenmpt_impl.cpp \ @ENABLE_TESTS_TRUE@ libopenmpt/libopenmpt_config.h \ @ENABLE_TESTS_TRUE@ libopenmpt/libopenmpt_ext.h \ @ENABLE_TESTS_TRUE@ libopenmpt/libopenmpt_ext.hpp \ @ENABLE_TESTS_TRUE@ libopenmpt/libopenmpt_ext_impl.hpp \ @ENABLE_TESTS_TRUE@ libopenmpt/libopenmpt.h \ @ENABLE_TESTS_TRUE@ libopenmpt/libopenmpt.hpp \ @ENABLE_TESTS_TRUE@ libopenmpt/libopenmpt_impl.hpp \ @ENABLE_TESTS_TRUE@ libopenmpt/libopenmpt_internal.h \ @ENABLE_TESTS_TRUE@ libopenmpt/libopenmpt_stream_callbacks_buffer.h \ @ENABLE_TESTS_TRUE@ libopenmpt/libopenmpt_stream_callbacks_fd.h \ @ENABLE_TESTS_TRUE@ libopenmpt/libopenmpt_stream_callbacks_file.h \ @ENABLE_TESTS_TRUE@ libopenmpt/libopenmpt_version.h @ENABLE_OPENMPT123_TRUE@bin_openmpt123_CPPFLAGS = -I$(srcdir)/src/openmpt123 $(PORTAUDIO_CFLAGS) $(PULSEAUDIO_CFLAGS) $(SDL2_CFLAGS) $(SDL_CFLAGS) $(SNDFILE_CFLAGS) $(FLAC_CFLAGS) @ENABLE_OPENMPT123_TRUE@bin_openmpt123_CXXFLAGS = $(WIN32_CONSOLE_CXXFLAGS) @ENABLE_OPENMPT123_TRUE@bin_openmpt123_LDADD = libopenmpt.la $(PORTAUDIO_LIBS) $(PULSEAUDIO_LIBS) $(SDL2_LIBS) $(SDL_LIBS) $(SNDFILE_LIBS) $(FLAC_LIBS) $(OPENMPT123_WIN32_LIBS) @ENABLE_OPENMPT123_TRUE@bin_openmpt123_SOURCES = \ @ENABLE_OPENMPT123_TRUE@ openmpt123/openmpt123_config.hpp \ @ENABLE_OPENMPT123_TRUE@ openmpt123/openmpt123.cpp \ @ENABLE_OPENMPT123_TRUE@ openmpt123/openmpt123_flac.hpp \ @ENABLE_OPENMPT123_TRUE@ openmpt123/openmpt123.hpp \ @ENABLE_OPENMPT123_TRUE@ openmpt123/openmpt123_mmio.hpp \ @ENABLE_OPENMPT123_TRUE@ openmpt123/openmpt123_portaudio.hpp \ @ENABLE_OPENMPT123_TRUE@ openmpt123/openmpt123_pulseaudio.hpp \ @ENABLE_OPENMPT123_TRUE@ openmpt123/openmpt123_raw.hpp \ @ENABLE_OPENMPT123_TRUE@ openmpt123/openmpt123_sdl.hpp \ @ENABLE_OPENMPT123_TRUE@ openmpt123/openmpt123_sdl2.hpp \ @ENABLE_OPENMPT123_TRUE@ openmpt123/openmpt123_sndfile.hpp \ @ENABLE_OPENMPT123_TRUE@ openmpt123/openmpt123_stdout.hpp \ @ENABLE_OPENMPT123_TRUE@ openmpt123/openmpt123_waveout.hpp @ENABLE_OPENMPT123_TRUE@man1_MANS = man/openmpt123.1 all: config.h $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: .SUFFIXES: .c .cpp .lo .log .o .obj .test .test$(EXEEXT) .trs am--refresh: Makefile @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): config.h: stamp-h1 @test -f $@ || rm -f stamp-h1 @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 libopenmpt/libopenmpt.pc: $(top_builddir)/config.status $(top_srcdir)/libopenmpt/libopenmpt.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ libmodplug/libmodplug.pc: $(top_builddir)/config.status $(top_srcdir)/libmodplug/libmodplug.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ Doxyfile: $(top_builddir)/config.status $(srcdir)/Doxyfile.in cd $(top_builddir) && $(SHELL) ./config.status $@ install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libopenmpt/$(am__dirstamp): @$(MKDIR_P) libopenmpt @: > libopenmpt/$(am__dirstamp) libopenmpt/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) libopenmpt/$(DEPDIR) @: > libopenmpt/$(DEPDIR)/$(am__dirstamp) libopenmpt/libmodplug_la-libopenmpt_modplug.lo: \ libopenmpt/$(am__dirstamp) \ libopenmpt/$(DEPDIR)/$(am__dirstamp) libopenmpt/libmodplug_la-libopenmpt_modplug_cpp.lo: \ libopenmpt/$(am__dirstamp) \ libopenmpt/$(DEPDIR)/$(am__dirstamp) libmodplug.la: $(libmodplug_la_OBJECTS) $(libmodplug_la_DEPENDENCIES) $(EXTRA_libmodplug_la_DEPENDENCIES) $(AM_V_CXXLD)$(libmodplug_la_LINK) $(am_libmodplug_la_rpath) $(libmodplug_la_OBJECTS) $(libmodplug_la_LIBADD) $(LIBS) common/$(am__dirstamp): @$(MKDIR_P) common @: > common/$(am__dirstamp) common/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) common/$(DEPDIR) @: > common/$(DEPDIR)/$(am__dirstamp) common/libopenmpt_la-ComponentManager.lo: common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpt_la-FileReader.lo: common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpt_la-Logging.lo: common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpt_la-misc_util.lo: common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpt_la-mptCPU.lo: common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpt_la-mptFileIO.lo: common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpt_la-mptIO.lo: common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpt_la-mptLibrary.lo: common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpt_la-mptOS.lo: common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpt_la-mptPathString.lo: common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpt_la-mptRandom.lo: common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpt_la-mptString.lo: common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpt_la-mptStringFormat.lo: common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpt_la-mptStringParse.lo: common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpt_la-mptTime.lo: common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpt_la-mptUUID.lo: common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpt_la-mptWine.lo: common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpt_la-Profiler.lo: common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpt_la-serialization_utils.lo: common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpt_la-stdafx.lo: common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpt_la-typedefs.lo: common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpt_la-version.lo: common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) soundlib/$(am__dirstamp): @$(MKDIR_P) soundlib @: > soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) soundlib/$(DEPDIR) @: > soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-AudioCriticalSection.lo: \ soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-ContainerMMCMP.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-ContainerPP20.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-ContainerUMX.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-ContainerXPK.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Dither.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Dlsbank.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Fastmix.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-InstrumentExtensions.lo: \ soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-ITCompression.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-ITTools.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Load_669.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Load_amf.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Load_ams.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Load_dbm.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Load_digi.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Load_dmf.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Load_dsm.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Load_dtm.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Load_far.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Load_gdm.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Load_imf.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Load_it.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Load_itp.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-load_j2b.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Load_mdl.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Load_med.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Load_mid.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Load_mo3.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Load_mod.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Load_mt2.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Load_mtm.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Load_okt.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Load_plm.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Load_psm.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Load_ptm.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Load_s3m.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Load_sfx.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Load_stm.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Load_stp.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Load_uax.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Load_ult.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Load_wav.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Load_xm.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Message.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-MIDIEvents.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-MIDIMacros.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-MixerLoops.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-MixerSettings.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-MixFuncTable.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-ModChannel.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-modcommand.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-ModInstrument.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-ModSample.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-ModSequence.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-modsmp_ctrl.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-mod_specifications.lo: \ soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-MPEGFrame.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-OggStream.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Paula.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-patternContainer.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-pattern.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-RowVisitor.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-S3MTools.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-SampleFormats.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-SampleFormatFLAC.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-SampleFormatMediaFoundation.lo: \ soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-SampleFormatMP3.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-SampleFormatOpus.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-SampleFormatVorbis.lo: \ soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-SampleIO.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Sndfile.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Snd_flt.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Snd_fx.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Sndmix.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-SoundFilePlayConfig.lo: \ soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Tables.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-Tagging.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-tuningbase.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-tuningCollection.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-tuning.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-UMXTools.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-UpgradeModule.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-WAVTools.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-WindowedFIR.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpt_la-XMTools.lo: soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/plugins/dmo/$(am__dirstamp): @$(MKDIR_P) soundlib/plugins/dmo @: > soundlib/plugins/dmo/$(am__dirstamp) soundlib/plugins/dmo/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) soundlib/plugins/dmo/$(DEPDIR) @: > soundlib/plugins/dmo/$(DEPDIR)/$(am__dirstamp) soundlib/plugins/dmo/libopenmpt_la-DMOPlugin.lo: \ soundlib/plugins/dmo/$(am__dirstamp) \ soundlib/plugins/dmo/$(DEPDIR)/$(am__dirstamp) soundlib/plugins/dmo/libopenmpt_la-Chorus.lo: \ soundlib/plugins/dmo/$(am__dirstamp) \ soundlib/plugins/dmo/$(DEPDIR)/$(am__dirstamp) soundlib/plugins/dmo/libopenmpt_la-Compressor.lo: \ soundlib/plugins/dmo/$(am__dirstamp) \ soundlib/plugins/dmo/$(DEPDIR)/$(am__dirstamp) soundlib/plugins/dmo/libopenmpt_la-Distortion.lo: \ soundlib/plugins/dmo/$(am__dirstamp) \ soundlib/plugins/dmo/$(DEPDIR)/$(am__dirstamp) soundlib/plugins/dmo/libopenmpt_la-Echo.lo: \ soundlib/plugins/dmo/$(am__dirstamp) \ soundlib/plugins/dmo/$(DEPDIR)/$(am__dirstamp) soundlib/plugins/dmo/libopenmpt_la-Flanger.lo: \ soundlib/plugins/dmo/$(am__dirstamp) \ soundlib/plugins/dmo/$(DEPDIR)/$(am__dirstamp) soundlib/plugins/dmo/libopenmpt_la-Gargle.lo: \ soundlib/plugins/dmo/$(am__dirstamp) \ soundlib/plugins/dmo/$(DEPDIR)/$(am__dirstamp) soundlib/plugins/dmo/libopenmpt_la-I3DL2Reverb.lo: \ soundlib/plugins/dmo/$(am__dirstamp) \ soundlib/plugins/dmo/$(DEPDIR)/$(am__dirstamp) soundlib/plugins/dmo/libopenmpt_la-ParamEq.lo: \ soundlib/plugins/dmo/$(am__dirstamp) \ soundlib/plugins/dmo/$(DEPDIR)/$(am__dirstamp) soundlib/plugins/dmo/libopenmpt_la-WavesReverb.lo: \ soundlib/plugins/dmo/$(am__dirstamp) \ soundlib/plugins/dmo/$(DEPDIR)/$(am__dirstamp) soundlib/plugins/$(am__dirstamp): @$(MKDIR_P) soundlib/plugins @: > soundlib/plugins/$(am__dirstamp) soundlib/plugins/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) soundlib/plugins/$(DEPDIR) @: > soundlib/plugins/$(DEPDIR)/$(am__dirstamp) soundlib/plugins/libopenmpt_la-DigiBoosterEcho.lo: \ soundlib/plugins/$(am__dirstamp) \ soundlib/plugins/$(DEPDIR)/$(am__dirstamp) soundlib/plugins/libopenmpt_la-LFOPlugin.lo: \ soundlib/plugins/$(am__dirstamp) \ soundlib/plugins/$(DEPDIR)/$(am__dirstamp) soundlib/plugins/libopenmpt_la-PluginManager.lo: \ soundlib/plugins/$(am__dirstamp) \ soundlib/plugins/$(DEPDIR)/$(am__dirstamp) soundlib/plugins/libopenmpt_la-PlugInterface.lo: \ soundlib/plugins/$(am__dirstamp) \ soundlib/plugins/$(DEPDIR)/$(am__dirstamp) sounddsp/$(am__dirstamp): @$(MKDIR_P) sounddsp @: > sounddsp/$(am__dirstamp) sounddsp/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) sounddsp/$(DEPDIR) @: > sounddsp/$(DEPDIR)/$(am__dirstamp) sounddsp/libopenmpt_la-AGC.lo: sounddsp/$(am__dirstamp) \ sounddsp/$(DEPDIR)/$(am__dirstamp) sounddsp/libopenmpt_la-DSP.lo: sounddsp/$(am__dirstamp) \ sounddsp/$(DEPDIR)/$(am__dirstamp) sounddsp/libopenmpt_la-EQ.lo: sounddsp/$(am__dirstamp) \ sounddsp/$(DEPDIR)/$(am__dirstamp) sounddsp/libopenmpt_la-Reverb.lo: sounddsp/$(am__dirstamp) \ sounddsp/$(DEPDIR)/$(am__dirstamp) libopenmpt/libopenmpt_la-libopenmpt_c.lo: libopenmpt/$(am__dirstamp) \ libopenmpt/$(DEPDIR)/$(am__dirstamp) libopenmpt/libopenmpt_la-libopenmpt_cxx.lo: \ libopenmpt/$(am__dirstamp) \ libopenmpt/$(DEPDIR)/$(am__dirstamp) libopenmpt/libopenmpt_la-libopenmpt_ext_impl.lo: \ libopenmpt/$(am__dirstamp) \ libopenmpt/$(DEPDIR)/$(am__dirstamp) libopenmpt/libopenmpt_la-libopenmpt_impl.lo: \ libopenmpt/$(am__dirstamp) \ libopenmpt/$(DEPDIR)/$(am__dirstamp) libopenmpt.la: $(libopenmpt_la_OBJECTS) $(libopenmpt_la_DEPENDENCIES) $(EXTRA_libopenmpt_la_DEPENDENCIES) $(AM_V_CXXLD)$(libopenmpt_la_LINK) -rpath $(libdir) $(libopenmpt_la_OBJECTS) $(libopenmpt_la_LIBADD) $(LIBS) libopenmpt/libopenmpt_modplug_la-libopenmpt_modplug.lo: \ libopenmpt/$(am__dirstamp) \ libopenmpt/$(DEPDIR)/$(am__dirstamp) libopenmpt/libopenmpt_modplug_la-libopenmpt_modplug_cpp.lo: \ libopenmpt/$(am__dirstamp) \ libopenmpt/$(DEPDIR)/$(am__dirstamp) libopenmpt_modplug.la: $(libopenmpt_modplug_la_OBJECTS) $(libopenmpt_modplug_la_DEPENDENCIES) $(EXTRA_libopenmpt_modplug_la_DEPENDENCIES) $(AM_V_CXXLD)$(libopenmpt_modplug_la_LINK) $(am_libopenmpt_modplug_la_rpath) $(libopenmpt_modplug_la_OBJECTS) $(libopenmpt_modplug_la_LIBADD) $(LIBS) install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list clean-checkPROGRAMS: @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list openmpt123/$(am__dirstamp): @$(MKDIR_P) openmpt123 @: > openmpt123/$(am__dirstamp) openmpt123/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) openmpt123/$(DEPDIR) @: > openmpt123/$(DEPDIR)/$(am__dirstamp) openmpt123/bin_openmpt123-openmpt123.$(OBJEXT): \ openmpt123/$(am__dirstamp) \ openmpt123/$(DEPDIR)/$(am__dirstamp) bin/$(am__dirstamp): @$(MKDIR_P) bin @: > bin/$(am__dirstamp) bin/openmpt123$(EXEEXT): $(bin_openmpt123_OBJECTS) $(bin_openmpt123_DEPENDENCIES) $(EXTRA_bin_openmpt123_DEPENDENCIES) bin/$(am__dirstamp) @rm -f bin/openmpt123$(EXEEXT) $(AM_V_CXXLD)$(bin_openmpt123_LINK) $(bin_openmpt123_OBJECTS) $(bin_openmpt123_LDADD) $(LIBS) examples/$(am__dirstamp): @$(MKDIR_P) examples @: > examples/$(am__dirstamp) examples/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) examples/$(DEPDIR) @: > examples/$(DEPDIR)/$(am__dirstamp) examples/libopenmpt_example_c-libopenmpt_example_c.$(OBJEXT): \ examples/$(am__dirstamp) examples/$(DEPDIR)/$(am__dirstamp) libopenmpt_example_c$(EXEEXT): $(libopenmpt_example_c_OBJECTS) $(libopenmpt_example_c_DEPENDENCIES) $(EXTRA_libopenmpt_example_c_DEPENDENCIES) @rm -f libopenmpt_example_c$(EXEEXT) $(AM_V_CCLD)$(libopenmpt_example_c_LINK) $(libopenmpt_example_c_OBJECTS) $(libopenmpt_example_c_LDADD) $(LIBS) examples/libopenmpt_example_c_mem-libopenmpt_example_c_mem.$(OBJEXT): \ examples/$(am__dirstamp) examples/$(DEPDIR)/$(am__dirstamp) libopenmpt_example_c_mem$(EXEEXT): $(libopenmpt_example_c_mem_OBJECTS) $(libopenmpt_example_c_mem_DEPENDENCIES) $(EXTRA_libopenmpt_example_c_mem_DEPENDENCIES) @rm -f libopenmpt_example_c_mem$(EXEEXT) $(AM_V_CCLD)$(libopenmpt_example_c_mem_LINK) $(libopenmpt_example_c_mem_OBJECTS) $(libopenmpt_example_c_mem_LDADD) $(LIBS) examples/libopenmpt_example_c_probe-libopenmpt_example_c_probe.$(OBJEXT): \ examples/$(am__dirstamp) examples/$(DEPDIR)/$(am__dirstamp) libopenmpt_example_c_probe$(EXEEXT): $(libopenmpt_example_c_probe_OBJECTS) $(libopenmpt_example_c_probe_DEPENDENCIES) $(EXTRA_libopenmpt_example_c_probe_DEPENDENCIES) @rm -f libopenmpt_example_c_probe$(EXEEXT) $(AM_V_CCLD)$(libopenmpt_example_c_probe_LINK) $(libopenmpt_example_c_probe_OBJECTS) $(libopenmpt_example_c_probe_LDADD) $(LIBS) examples/libopenmpt_example_c_stdout-libopenmpt_example_c_stdout.$(OBJEXT): \ examples/$(am__dirstamp) examples/$(DEPDIR)/$(am__dirstamp) libopenmpt_example_c_stdout$(EXEEXT): $(libopenmpt_example_c_stdout_OBJECTS) $(libopenmpt_example_c_stdout_DEPENDENCIES) $(EXTRA_libopenmpt_example_c_stdout_DEPENDENCIES) @rm -f libopenmpt_example_c_stdout$(EXEEXT) $(AM_V_CCLD)$(libopenmpt_example_c_stdout_LINK) $(libopenmpt_example_c_stdout_OBJECTS) $(libopenmpt_example_c_stdout_LDADD) $(LIBS) examples/libopenmpt_example_c_unsafe-libopenmpt_example_c_unsafe.$(OBJEXT): \ examples/$(am__dirstamp) examples/$(DEPDIR)/$(am__dirstamp) libopenmpt_example_c_unsafe$(EXEEXT): $(libopenmpt_example_c_unsafe_OBJECTS) $(libopenmpt_example_c_unsafe_DEPENDENCIES) $(EXTRA_libopenmpt_example_c_unsafe_DEPENDENCIES) @rm -f libopenmpt_example_c_unsafe$(EXEEXT) $(AM_V_CCLD)$(libopenmpt_example_c_unsafe_LINK) $(libopenmpt_example_c_unsafe_OBJECTS) $(libopenmpt_example_c_unsafe_LDADD) $(LIBS) examples/libopenmpt_example_cxx-libopenmpt_example_cxx.$(OBJEXT): \ examples/$(am__dirstamp) examples/$(DEPDIR)/$(am__dirstamp) libopenmpt_example_cxx$(EXEEXT): $(libopenmpt_example_cxx_OBJECTS) $(libopenmpt_example_cxx_DEPENDENCIES) $(EXTRA_libopenmpt_example_cxx_DEPENDENCIES) @rm -f libopenmpt_example_cxx$(EXEEXT) $(AM_V_CXXLD)$(libopenmpt_example_cxx_LINK) $(libopenmpt_example_cxx_OBJECTS) $(libopenmpt_example_cxx_LDADD) $(LIBS) libopenmpt/libopenmpttest-libopenmpt_test.$(OBJEXT): \ libopenmpt/$(am__dirstamp) \ libopenmpt/$(DEPDIR)/$(am__dirstamp) test/$(am__dirstamp): @$(MKDIR_P) test @: > test/$(am__dirstamp) test/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) test/$(DEPDIR) @: > test/$(DEPDIR)/$(am__dirstamp) test/libopenmpttest-test.$(OBJEXT): test/$(am__dirstamp) \ test/$(DEPDIR)/$(am__dirstamp) test/libopenmpttest-TestToolsLib.$(OBJEXT): test/$(am__dirstamp) \ test/$(DEPDIR)/$(am__dirstamp) common/libopenmpttest-ComponentManager.$(OBJEXT): \ common/$(am__dirstamp) common/$(DEPDIR)/$(am__dirstamp) common/libopenmpttest-FileReader.$(OBJEXT): common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpttest-Logging.$(OBJEXT): common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpttest-misc_util.$(OBJEXT): common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpttest-mptCPU.$(OBJEXT): common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpttest-mptFileIO.$(OBJEXT): common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpttest-mptIO.$(OBJEXT): common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpttest-mptLibrary.$(OBJEXT): common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpttest-mptOS.$(OBJEXT): common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpttest-mptPathString.$(OBJEXT): common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpttest-mptRandom.$(OBJEXT): common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpttest-mptString.$(OBJEXT): common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpttest-mptStringFormat.$(OBJEXT): \ common/$(am__dirstamp) common/$(DEPDIR)/$(am__dirstamp) common/libopenmpttest-mptStringParse.$(OBJEXT): \ common/$(am__dirstamp) common/$(DEPDIR)/$(am__dirstamp) common/libopenmpttest-mptTime.$(OBJEXT): common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpttest-mptUUID.$(OBJEXT): common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpttest-mptWine.$(OBJEXT): common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpttest-Profiler.$(OBJEXT): common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpttest-serialization_utils.$(OBJEXT): \ common/$(am__dirstamp) common/$(DEPDIR)/$(am__dirstamp) common/libopenmpttest-stdafx.$(OBJEXT): common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpttest-typedefs.$(OBJEXT): common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) common/libopenmpttest-version.$(OBJEXT): common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-AudioCriticalSection.$(OBJEXT): \ soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-ContainerMMCMP.$(OBJEXT): \ soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-ContainerPP20.$(OBJEXT): \ soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-ContainerUMX.$(OBJEXT): \ soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-ContainerXPK.$(OBJEXT): \ soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Dither.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Dlsbank.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Fastmix.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-InstrumentExtensions.$(OBJEXT): \ soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-ITCompression.$(OBJEXT): \ soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-ITTools.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Load_669.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Load_amf.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Load_ams.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Load_dbm.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Load_digi.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Load_dmf.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Load_dsm.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Load_dtm.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Load_far.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Load_gdm.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Load_imf.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Load_it.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Load_itp.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-load_j2b.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Load_mdl.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Load_med.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Load_mid.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Load_mo3.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Load_mod.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Load_mt2.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Load_mtm.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Load_okt.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Load_plm.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Load_psm.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Load_ptm.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Load_s3m.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Load_sfx.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Load_stm.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Load_stp.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Load_uax.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Load_ult.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Load_wav.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Load_xm.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Message.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-MIDIEvents.$(OBJEXT): \ soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-MIDIMacros.$(OBJEXT): \ soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-MixerLoops.$(OBJEXT): \ soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-MixerSettings.$(OBJEXT): \ soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-MixFuncTable.$(OBJEXT): \ soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-ModChannel.$(OBJEXT): \ soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-modcommand.$(OBJEXT): \ soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-ModInstrument.$(OBJEXT): \ soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-ModSample.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-ModSequence.$(OBJEXT): \ soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-modsmp_ctrl.$(OBJEXT): \ soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-mod_specifications.$(OBJEXT): \ soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-MPEGFrame.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-OggStream.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Paula.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-patternContainer.$(OBJEXT): \ soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-pattern.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-RowVisitor.$(OBJEXT): \ soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-S3MTools.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-SampleFormats.$(OBJEXT): \ soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-SampleFormatFLAC.$(OBJEXT): \ soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-SampleFormatMediaFoundation.$(OBJEXT): \ soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-SampleFormatMP3.$(OBJEXT): \ soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-SampleFormatOpus.$(OBJEXT): \ soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-SampleFormatVorbis.$(OBJEXT): \ soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-SampleIO.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Sndfile.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Snd_flt.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Snd_fx.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Sndmix.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-SoundFilePlayConfig.$(OBJEXT): \ soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Tables.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-Tagging.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-tuningbase.$(OBJEXT): \ soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-tuningCollection.$(OBJEXT): \ soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-tuning.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-UMXTools.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-UpgradeModule.$(OBJEXT): \ soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-WAVTools.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-WindowedFIR.$(OBJEXT): \ soundlib/$(am__dirstamp) soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/libopenmpttest-XMTools.$(OBJEXT): soundlib/$(am__dirstamp) \ soundlib/$(DEPDIR)/$(am__dirstamp) soundlib/plugins/dmo/libopenmpttest-DMOPlugin.$(OBJEXT): \ soundlib/plugins/dmo/$(am__dirstamp) \ soundlib/plugins/dmo/$(DEPDIR)/$(am__dirstamp) soundlib/plugins/dmo/libopenmpttest-Chorus.$(OBJEXT): \ soundlib/plugins/dmo/$(am__dirstamp) \ soundlib/plugins/dmo/$(DEPDIR)/$(am__dirstamp) soundlib/plugins/dmo/libopenmpttest-Compressor.$(OBJEXT): \ soundlib/plugins/dmo/$(am__dirstamp) \ soundlib/plugins/dmo/$(DEPDIR)/$(am__dirstamp) soundlib/plugins/dmo/libopenmpttest-Distortion.$(OBJEXT): \ soundlib/plugins/dmo/$(am__dirstamp) \ soundlib/plugins/dmo/$(DEPDIR)/$(am__dirstamp) soundlib/plugins/dmo/libopenmpttest-Echo.$(OBJEXT): \ soundlib/plugins/dmo/$(am__dirstamp) \ soundlib/plugins/dmo/$(DEPDIR)/$(am__dirstamp) soundlib/plugins/dmo/libopenmpttest-Flanger.$(OBJEXT): \ soundlib/plugins/dmo/$(am__dirstamp) \ soundlib/plugins/dmo/$(DEPDIR)/$(am__dirstamp) soundlib/plugins/dmo/libopenmpttest-Gargle.$(OBJEXT): \ soundlib/plugins/dmo/$(am__dirstamp) \ soundlib/plugins/dmo/$(DEPDIR)/$(am__dirstamp) soundlib/plugins/dmo/libopenmpttest-I3DL2Reverb.$(OBJEXT): \ soundlib/plugins/dmo/$(am__dirstamp) \ soundlib/plugins/dmo/$(DEPDIR)/$(am__dirstamp) soundlib/plugins/dmo/libopenmpttest-ParamEq.$(OBJEXT): \ soundlib/plugins/dmo/$(am__dirstamp) \ soundlib/plugins/dmo/$(DEPDIR)/$(am__dirstamp) soundlib/plugins/dmo/libopenmpttest-WavesReverb.$(OBJEXT): \ soundlib/plugins/dmo/$(am__dirstamp) \ soundlib/plugins/dmo/$(DEPDIR)/$(am__dirstamp) soundlib/plugins/libopenmpttest-DigiBoosterEcho.$(OBJEXT): \ soundlib/plugins/$(am__dirstamp) \ soundlib/plugins/$(DEPDIR)/$(am__dirstamp) soundlib/plugins/libopenmpttest-LFOPlugin.$(OBJEXT): \ soundlib/plugins/$(am__dirstamp) \ soundlib/plugins/$(DEPDIR)/$(am__dirstamp) soundlib/plugins/libopenmpttest-PluginManager.$(OBJEXT): \ soundlib/plugins/$(am__dirstamp) \ soundlib/plugins/$(DEPDIR)/$(am__dirstamp) soundlib/plugins/libopenmpttest-PlugInterface.$(OBJEXT): \ soundlib/plugins/$(am__dirstamp) \ soundlib/plugins/$(DEPDIR)/$(am__dirstamp) sounddsp/libopenmpttest-AGC.$(OBJEXT): sounddsp/$(am__dirstamp) \ sounddsp/$(DEPDIR)/$(am__dirstamp) sounddsp/libopenmpttest-DSP.$(OBJEXT): sounddsp/$(am__dirstamp) \ sounddsp/$(DEPDIR)/$(am__dirstamp) sounddsp/libopenmpttest-EQ.$(OBJEXT): sounddsp/$(am__dirstamp) \ sounddsp/$(DEPDIR)/$(am__dirstamp) sounddsp/libopenmpttest-Reverb.$(OBJEXT): sounddsp/$(am__dirstamp) \ sounddsp/$(DEPDIR)/$(am__dirstamp) libopenmpt/libopenmpttest-libopenmpt_c.$(OBJEXT): \ libopenmpt/$(am__dirstamp) \ libopenmpt/$(DEPDIR)/$(am__dirstamp) libopenmpt/libopenmpttest-libopenmpt_cxx.$(OBJEXT): \ libopenmpt/$(am__dirstamp) \ libopenmpt/$(DEPDIR)/$(am__dirstamp) libopenmpt/libopenmpttest-libopenmpt_ext_impl.$(OBJEXT): \ libopenmpt/$(am__dirstamp) \ libopenmpt/$(DEPDIR)/$(am__dirstamp) libopenmpt/libopenmpttest-libopenmpt_impl.$(OBJEXT): \ libopenmpt/$(am__dirstamp) \ libopenmpt/$(DEPDIR)/$(am__dirstamp) libopenmpttest$(EXEEXT): $(libopenmpttest_OBJECTS) $(libopenmpttest_DEPENDENCIES) $(EXTRA_libopenmpttest_DEPENDENCIES) @rm -f libopenmpttest$(EXEEXT) $(AM_V_CXXLD)$(libopenmpttest_LINK) $(libopenmpttest_OBJECTS) $(libopenmpttest_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f common/*.$(OBJEXT) -rm -f common/*.lo -rm -f examples/*.$(OBJEXT) -rm -f libopenmpt/*.$(OBJEXT) -rm -f libopenmpt/*.lo -rm -f openmpt123/*.$(OBJEXT) -rm -f sounddsp/*.$(OBJEXT) -rm -f sounddsp/*.lo -rm -f soundlib/*.$(OBJEXT) -rm -f soundlib/*.lo -rm -f soundlib/plugins/*.$(OBJEXT) -rm -f soundlib/plugins/*.lo -rm -f soundlib/plugins/dmo/*.$(OBJEXT) -rm -f soundlib/plugins/dmo/*.lo -rm -f test/*.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpt_la-ComponentManager.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpt_la-FileReader.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpt_la-Logging.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpt_la-Profiler.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpt_la-misc_util.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpt_la-mptCPU.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpt_la-mptFileIO.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpt_la-mptIO.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpt_la-mptLibrary.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpt_la-mptOS.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpt_la-mptPathString.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpt_la-mptRandom.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpt_la-mptString.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpt_la-mptStringFormat.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpt_la-mptStringParse.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpt_la-mptTime.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpt_la-mptUUID.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpt_la-mptWine.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpt_la-serialization_utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpt_la-stdafx.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpt_la-typedefs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpt_la-version.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpttest-ComponentManager.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpttest-FileReader.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpttest-Logging.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpttest-Profiler.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpttest-misc_util.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpttest-mptCPU.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpttest-mptFileIO.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpttest-mptIO.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpttest-mptLibrary.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpttest-mptOS.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpttest-mptPathString.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpttest-mptRandom.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpttest-mptString.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpttest-mptStringFormat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpttest-mptStringParse.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpttest-mptTime.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpttest-mptUUID.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpttest-mptWine.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpttest-serialization_utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpttest-stdafx.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpttest-typedefs.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/libopenmpttest-version.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@examples/$(DEPDIR)/libopenmpt_example_c-libopenmpt_example_c.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@examples/$(DEPDIR)/libopenmpt_example_c_mem-libopenmpt_example_c_mem.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@examples/$(DEPDIR)/libopenmpt_example_c_probe-libopenmpt_example_c_probe.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@examples/$(DEPDIR)/libopenmpt_example_c_stdout-libopenmpt_example_c_stdout.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@examples/$(DEPDIR)/libopenmpt_example_c_unsafe-libopenmpt_example_c_unsafe.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@examples/$(DEPDIR)/libopenmpt_example_cxx-libopenmpt_example_cxx.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libopenmpt/$(DEPDIR)/libmodplug_la-libopenmpt_modplug.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libopenmpt/$(DEPDIR)/libmodplug_la-libopenmpt_modplug_cpp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libopenmpt/$(DEPDIR)/libopenmpt_la-libopenmpt_c.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libopenmpt/$(DEPDIR)/libopenmpt_la-libopenmpt_cxx.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libopenmpt/$(DEPDIR)/libopenmpt_la-libopenmpt_ext_impl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libopenmpt/$(DEPDIR)/libopenmpt_la-libopenmpt_impl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libopenmpt/$(DEPDIR)/libopenmpt_modplug_la-libopenmpt_modplug.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libopenmpt/$(DEPDIR)/libopenmpt_modplug_la-libopenmpt_modplug_cpp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libopenmpt/$(DEPDIR)/libopenmpttest-libopenmpt_c.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libopenmpt/$(DEPDIR)/libopenmpttest-libopenmpt_cxx.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libopenmpt/$(DEPDIR)/libopenmpttest-libopenmpt_ext_impl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libopenmpt/$(DEPDIR)/libopenmpttest-libopenmpt_impl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libopenmpt/$(DEPDIR)/libopenmpttest-libopenmpt_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@openmpt123/$(DEPDIR)/bin_openmpt123-openmpt123.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@sounddsp/$(DEPDIR)/libopenmpt_la-AGC.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@sounddsp/$(DEPDIR)/libopenmpt_la-DSP.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@sounddsp/$(DEPDIR)/libopenmpt_la-EQ.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@sounddsp/$(DEPDIR)/libopenmpt_la-Reverb.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@sounddsp/$(DEPDIR)/libopenmpttest-AGC.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@sounddsp/$(DEPDIR)/libopenmpttest-DSP.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@sounddsp/$(DEPDIR)/libopenmpttest-EQ.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@sounddsp/$(DEPDIR)/libopenmpttest-Reverb.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-AudioCriticalSection.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-ContainerMMCMP.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-ContainerPP20.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-ContainerUMX.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-ContainerXPK.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Dither.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Dlsbank.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Fastmix.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-ITCompression.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-ITTools.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-InstrumentExtensions.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Load_669.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Load_amf.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Load_ams.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Load_dbm.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Load_digi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Load_dmf.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Load_dsm.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Load_dtm.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Load_far.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Load_gdm.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Load_imf.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Load_it.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Load_itp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Load_mdl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Load_med.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Load_mid.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Load_mo3.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Load_mod.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Load_mt2.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Load_mtm.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Load_okt.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Load_plm.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Load_psm.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Load_ptm.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Load_s3m.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Load_sfx.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Load_stm.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Load_stp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Load_uax.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Load_ult.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Load_wav.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Load_xm.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-MIDIEvents.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-MIDIMacros.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-MPEGFrame.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Message.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-MixFuncTable.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-MixerLoops.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-MixerSettings.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-ModChannel.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-ModInstrument.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-ModSample.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-ModSequence.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-OggStream.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Paula.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-RowVisitor.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-S3MTools.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-SampleFormatFLAC.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-SampleFormatMP3.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-SampleFormatMediaFoundation.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-SampleFormatOpus.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-SampleFormatVorbis.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-SampleFormats.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-SampleIO.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Snd_flt.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Snd_fx.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Sndfile.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Sndmix.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-SoundFilePlayConfig.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Tables.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-Tagging.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-UMXTools.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-UpgradeModule.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-WAVTools.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-WindowedFIR.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-XMTools.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-load_j2b.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-mod_specifications.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-modcommand.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-modsmp_ctrl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-pattern.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-patternContainer.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-tuning.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-tuningCollection.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpt_la-tuningbase.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-AudioCriticalSection.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-ContainerMMCMP.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-ContainerPP20.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-ContainerUMX.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-ContainerXPK.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Dither.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Dlsbank.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Fastmix.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-ITCompression.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-ITTools.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-InstrumentExtensions.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Load_669.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Load_amf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Load_ams.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Load_dbm.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Load_digi.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Load_dmf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Load_dsm.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Load_dtm.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Load_far.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Load_gdm.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Load_imf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Load_it.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Load_itp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Load_mdl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Load_med.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Load_mid.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Load_mo3.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Load_mod.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Load_mt2.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Load_mtm.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Load_okt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Load_plm.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Load_psm.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Load_ptm.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Load_s3m.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Load_sfx.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Load_stm.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Load_stp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Load_uax.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Load_ult.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Load_wav.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Load_xm.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-MIDIEvents.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-MIDIMacros.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-MPEGFrame.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Message.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-MixFuncTable.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-MixerLoops.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-MixerSettings.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-ModChannel.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-ModInstrument.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-ModSample.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-ModSequence.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-OggStream.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Paula.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-RowVisitor.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-S3MTools.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-SampleFormatFLAC.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-SampleFormatMP3.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-SampleFormatMediaFoundation.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-SampleFormatOpus.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-SampleFormatVorbis.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-SampleFormats.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-SampleIO.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Snd_flt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Snd_fx.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Sndfile.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Sndmix.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-SoundFilePlayConfig.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Tables.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-Tagging.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-UMXTools.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-UpgradeModule.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-WAVTools.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-WindowedFIR.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-XMTools.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-load_j2b.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-mod_specifications.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-modcommand.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-modsmp_ctrl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-pattern.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-patternContainer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-tuning.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-tuningCollection.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/$(DEPDIR)/libopenmpttest-tuningbase.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/plugins/$(DEPDIR)/libopenmpt_la-DigiBoosterEcho.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/plugins/$(DEPDIR)/libopenmpt_la-LFOPlugin.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/plugins/$(DEPDIR)/libopenmpt_la-PlugInterface.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/plugins/$(DEPDIR)/libopenmpt_la-PluginManager.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/plugins/$(DEPDIR)/libopenmpttest-DigiBoosterEcho.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/plugins/$(DEPDIR)/libopenmpttest-LFOPlugin.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/plugins/$(DEPDIR)/libopenmpttest-PlugInterface.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/plugins/$(DEPDIR)/libopenmpttest-PluginManager.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-Chorus.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-Compressor.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-DMOPlugin.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-Distortion.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-Echo.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-Flanger.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-Gargle.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-I3DL2Reverb.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-ParamEq.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-WavesReverb.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Chorus.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Compressor.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-DMOPlugin.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Distortion.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Echo.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Flanger.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Gargle.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-I3DL2Reverb.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-ParamEq.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-WavesReverb.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/libopenmpttest-TestToolsLib.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/libopenmpttest-test.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< libopenmpt/libmodplug_la-libopenmpt_modplug.lo: libopenmpt/libopenmpt_modplug.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmodplug_la_CPPFLAGS) $(CPPFLAGS) $(libmodplug_la_CFLAGS) $(CFLAGS) -MT libopenmpt/libmodplug_la-libopenmpt_modplug.lo -MD -MP -MF libopenmpt/$(DEPDIR)/libmodplug_la-libopenmpt_modplug.Tpo -c -o libopenmpt/libmodplug_la-libopenmpt_modplug.lo `test -f 'libopenmpt/libopenmpt_modplug.c' || echo '$(srcdir)/'`libopenmpt/libopenmpt_modplug.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libopenmpt/$(DEPDIR)/libmodplug_la-libopenmpt_modplug.Tpo libopenmpt/$(DEPDIR)/libmodplug_la-libopenmpt_modplug.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libopenmpt/libopenmpt_modplug.c' object='libopenmpt/libmodplug_la-libopenmpt_modplug.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmodplug_la_CPPFLAGS) $(CPPFLAGS) $(libmodplug_la_CFLAGS) $(CFLAGS) -c -o libopenmpt/libmodplug_la-libopenmpt_modplug.lo `test -f 'libopenmpt/libopenmpt_modplug.c' || echo '$(srcdir)/'`libopenmpt/libopenmpt_modplug.c libopenmpt/libopenmpt_modplug_la-libopenmpt_modplug.lo: libopenmpt/libopenmpt_modplug.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_modplug_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_modplug_la_CFLAGS) $(CFLAGS) -MT libopenmpt/libopenmpt_modplug_la-libopenmpt_modplug.lo -MD -MP -MF libopenmpt/$(DEPDIR)/libopenmpt_modplug_la-libopenmpt_modplug.Tpo -c -o libopenmpt/libopenmpt_modplug_la-libopenmpt_modplug.lo `test -f 'libopenmpt/libopenmpt_modplug.c' || echo '$(srcdir)/'`libopenmpt/libopenmpt_modplug.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libopenmpt/$(DEPDIR)/libopenmpt_modplug_la-libopenmpt_modplug.Tpo libopenmpt/$(DEPDIR)/libopenmpt_modplug_la-libopenmpt_modplug.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libopenmpt/libopenmpt_modplug.c' object='libopenmpt/libopenmpt_modplug_la-libopenmpt_modplug.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_modplug_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_modplug_la_CFLAGS) $(CFLAGS) -c -o libopenmpt/libopenmpt_modplug_la-libopenmpt_modplug.lo `test -f 'libopenmpt/libopenmpt_modplug.c' || echo '$(srcdir)/'`libopenmpt/libopenmpt_modplug.c examples/libopenmpt_example_c-libopenmpt_example_c.o: examples/libopenmpt_example_c.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_example_c_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_example_c_CFLAGS) $(CFLAGS) -MT examples/libopenmpt_example_c-libopenmpt_example_c.o -MD -MP -MF examples/$(DEPDIR)/libopenmpt_example_c-libopenmpt_example_c.Tpo -c -o examples/libopenmpt_example_c-libopenmpt_example_c.o `test -f 'examples/libopenmpt_example_c.c' || echo '$(srcdir)/'`examples/libopenmpt_example_c.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/$(DEPDIR)/libopenmpt_example_c-libopenmpt_example_c.Tpo examples/$(DEPDIR)/libopenmpt_example_c-libopenmpt_example_c.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/libopenmpt_example_c.c' object='examples/libopenmpt_example_c-libopenmpt_example_c.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_example_c_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_example_c_CFLAGS) $(CFLAGS) -c -o examples/libopenmpt_example_c-libopenmpt_example_c.o `test -f 'examples/libopenmpt_example_c.c' || echo '$(srcdir)/'`examples/libopenmpt_example_c.c examples/libopenmpt_example_c-libopenmpt_example_c.obj: examples/libopenmpt_example_c.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_example_c_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_example_c_CFLAGS) $(CFLAGS) -MT examples/libopenmpt_example_c-libopenmpt_example_c.obj -MD -MP -MF examples/$(DEPDIR)/libopenmpt_example_c-libopenmpt_example_c.Tpo -c -o examples/libopenmpt_example_c-libopenmpt_example_c.obj `if test -f 'examples/libopenmpt_example_c.c'; then $(CYGPATH_W) 'examples/libopenmpt_example_c.c'; else $(CYGPATH_W) '$(srcdir)/examples/libopenmpt_example_c.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/$(DEPDIR)/libopenmpt_example_c-libopenmpt_example_c.Tpo examples/$(DEPDIR)/libopenmpt_example_c-libopenmpt_example_c.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/libopenmpt_example_c.c' object='examples/libopenmpt_example_c-libopenmpt_example_c.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_example_c_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_example_c_CFLAGS) $(CFLAGS) -c -o examples/libopenmpt_example_c-libopenmpt_example_c.obj `if test -f 'examples/libopenmpt_example_c.c'; then $(CYGPATH_W) 'examples/libopenmpt_example_c.c'; else $(CYGPATH_W) '$(srcdir)/examples/libopenmpt_example_c.c'; fi` examples/libopenmpt_example_c_mem-libopenmpt_example_c_mem.o: examples/libopenmpt_example_c_mem.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_example_c_mem_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_example_c_mem_CFLAGS) $(CFLAGS) -MT examples/libopenmpt_example_c_mem-libopenmpt_example_c_mem.o -MD -MP -MF examples/$(DEPDIR)/libopenmpt_example_c_mem-libopenmpt_example_c_mem.Tpo -c -o examples/libopenmpt_example_c_mem-libopenmpt_example_c_mem.o `test -f 'examples/libopenmpt_example_c_mem.c' || echo '$(srcdir)/'`examples/libopenmpt_example_c_mem.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/$(DEPDIR)/libopenmpt_example_c_mem-libopenmpt_example_c_mem.Tpo examples/$(DEPDIR)/libopenmpt_example_c_mem-libopenmpt_example_c_mem.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/libopenmpt_example_c_mem.c' object='examples/libopenmpt_example_c_mem-libopenmpt_example_c_mem.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_example_c_mem_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_example_c_mem_CFLAGS) $(CFLAGS) -c -o examples/libopenmpt_example_c_mem-libopenmpt_example_c_mem.o `test -f 'examples/libopenmpt_example_c_mem.c' || echo '$(srcdir)/'`examples/libopenmpt_example_c_mem.c examples/libopenmpt_example_c_mem-libopenmpt_example_c_mem.obj: examples/libopenmpt_example_c_mem.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_example_c_mem_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_example_c_mem_CFLAGS) $(CFLAGS) -MT examples/libopenmpt_example_c_mem-libopenmpt_example_c_mem.obj -MD -MP -MF examples/$(DEPDIR)/libopenmpt_example_c_mem-libopenmpt_example_c_mem.Tpo -c -o examples/libopenmpt_example_c_mem-libopenmpt_example_c_mem.obj `if test -f 'examples/libopenmpt_example_c_mem.c'; then $(CYGPATH_W) 'examples/libopenmpt_example_c_mem.c'; else $(CYGPATH_W) '$(srcdir)/examples/libopenmpt_example_c_mem.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/$(DEPDIR)/libopenmpt_example_c_mem-libopenmpt_example_c_mem.Tpo examples/$(DEPDIR)/libopenmpt_example_c_mem-libopenmpt_example_c_mem.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/libopenmpt_example_c_mem.c' object='examples/libopenmpt_example_c_mem-libopenmpt_example_c_mem.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_example_c_mem_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_example_c_mem_CFLAGS) $(CFLAGS) -c -o examples/libopenmpt_example_c_mem-libopenmpt_example_c_mem.obj `if test -f 'examples/libopenmpt_example_c_mem.c'; then $(CYGPATH_W) 'examples/libopenmpt_example_c_mem.c'; else $(CYGPATH_W) '$(srcdir)/examples/libopenmpt_example_c_mem.c'; fi` examples/libopenmpt_example_c_probe-libopenmpt_example_c_probe.o: examples/libopenmpt_example_c_probe.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_example_c_probe_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_example_c_probe_CFLAGS) $(CFLAGS) -MT examples/libopenmpt_example_c_probe-libopenmpt_example_c_probe.o -MD -MP -MF examples/$(DEPDIR)/libopenmpt_example_c_probe-libopenmpt_example_c_probe.Tpo -c -o examples/libopenmpt_example_c_probe-libopenmpt_example_c_probe.o `test -f 'examples/libopenmpt_example_c_probe.c' || echo '$(srcdir)/'`examples/libopenmpt_example_c_probe.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/$(DEPDIR)/libopenmpt_example_c_probe-libopenmpt_example_c_probe.Tpo examples/$(DEPDIR)/libopenmpt_example_c_probe-libopenmpt_example_c_probe.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/libopenmpt_example_c_probe.c' object='examples/libopenmpt_example_c_probe-libopenmpt_example_c_probe.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_example_c_probe_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_example_c_probe_CFLAGS) $(CFLAGS) -c -o examples/libopenmpt_example_c_probe-libopenmpt_example_c_probe.o `test -f 'examples/libopenmpt_example_c_probe.c' || echo '$(srcdir)/'`examples/libopenmpt_example_c_probe.c examples/libopenmpt_example_c_probe-libopenmpt_example_c_probe.obj: examples/libopenmpt_example_c_probe.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_example_c_probe_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_example_c_probe_CFLAGS) $(CFLAGS) -MT examples/libopenmpt_example_c_probe-libopenmpt_example_c_probe.obj -MD -MP -MF examples/$(DEPDIR)/libopenmpt_example_c_probe-libopenmpt_example_c_probe.Tpo -c -o examples/libopenmpt_example_c_probe-libopenmpt_example_c_probe.obj `if test -f 'examples/libopenmpt_example_c_probe.c'; then $(CYGPATH_W) 'examples/libopenmpt_example_c_probe.c'; else $(CYGPATH_W) '$(srcdir)/examples/libopenmpt_example_c_probe.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/$(DEPDIR)/libopenmpt_example_c_probe-libopenmpt_example_c_probe.Tpo examples/$(DEPDIR)/libopenmpt_example_c_probe-libopenmpt_example_c_probe.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/libopenmpt_example_c_probe.c' object='examples/libopenmpt_example_c_probe-libopenmpt_example_c_probe.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_example_c_probe_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_example_c_probe_CFLAGS) $(CFLAGS) -c -o examples/libopenmpt_example_c_probe-libopenmpt_example_c_probe.obj `if test -f 'examples/libopenmpt_example_c_probe.c'; then $(CYGPATH_W) 'examples/libopenmpt_example_c_probe.c'; else $(CYGPATH_W) '$(srcdir)/examples/libopenmpt_example_c_probe.c'; fi` examples/libopenmpt_example_c_stdout-libopenmpt_example_c_stdout.o: examples/libopenmpt_example_c_stdout.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_example_c_stdout_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_example_c_stdout_CFLAGS) $(CFLAGS) -MT examples/libopenmpt_example_c_stdout-libopenmpt_example_c_stdout.o -MD -MP -MF examples/$(DEPDIR)/libopenmpt_example_c_stdout-libopenmpt_example_c_stdout.Tpo -c -o examples/libopenmpt_example_c_stdout-libopenmpt_example_c_stdout.o `test -f 'examples/libopenmpt_example_c_stdout.c' || echo '$(srcdir)/'`examples/libopenmpt_example_c_stdout.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/$(DEPDIR)/libopenmpt_example_c_stdout-libopenmpt_example_c_stdout.Tpo examples/$(DEPDIR)/libopenmpt_example_c_stdout-libopenmpt_example_c_stdout.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/libopenmpt_example_c_stdout.c' object='examples/libopenmpt_example_c_stdout-libopenmpt_example_c_stdout.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_example_c_stdout_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_example_c_stdout_CFLAGS) $(CFLAGS) -c -o examples/libopenmpt_example_c_stdout-libopenmpt_example_c_stdout.o `test -f 'examples/libopenmpt_example_c_stdout.c' || echo '$(srcdir)/'`examples/libopenmpt_example_c_stdout.c examples/libopenmpt_example_c_stdout-libopenmpt_example_c_stdout.obj: examples/libopenmpt_example_c_stdout.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_example_c_stdout_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_example_c_stdout_CFLAGS) $(CFLAGS) -MT examples/libopenmpt_example_c_stdout-libopenmpt_example_c_stdout.obj -MD -MP -MF examples/$(DEPDIR)/libopenmpt_example_c_stdout-libopenmpt_example_c_stdout.Tpo -c -o examples/libopenmpt_example_c_stdout-libopenmpt_example_c_stdout.obj `if test -f 'examples/libopenmpt_example_c_stdout.c'; then $(CYGPATH_W) 'examples/libopenmpt_example_c_stdout.c'; else $(CYGPATH_W) '$(srcdir)/examples/libopenmpt_example_c_stdout.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/$(DEPDIR)/libopenmpt_example_c_stdout-libopenmpt_example_c_stdout.Tpo examples/$(DEPDIR)/libopenmpt_example_c_stdout-libopenmpt_example_c_stdout.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/libopenmpt_example_c_stdout.c' object='examples/libopenmpt_example_c_stdout-libopenmpt_example_c_stdout.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_example_c_stdout_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_example_c_stdout_CFLAGS) $(CFLAGS) -c -o examples/libopenmpt_example_c_stdout-libopenmpt_example_c_stdout.obj `if test -f 'examples/libopenmpt_example_c_stdout.c'; then $(CYGPATH_W) 'examples/libopenmpt_example_c_stdout.c'; else $(CYGPATH_W) '$(srcdir)/examples/libopenmpt_example_c_stdout.c'; fi` examples/libopenmpt_example_c_unsafe-libopenmpt_example_c_unsafe.o: examples/libopenmpt_example_c_unsafe.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_example_c_unsafe_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_example_c_unsafe_CFLAGS) $(CFLAGS) -MT examples/libopenmpt_example_c_unsafe-libopenmpt_example_c_unsafe.o -MD -MP -MF examples/$(DEPDIR)/libopenmpt_example_c_unsafe-libopenmpt_example_c_unsafe.Tpo -c -o examples/libopenmpt_example_c_unsafe-libopenmpt_example_c_unsafe.o `test -f 'examples/libopenmpt_example_c_unsafe.c' || echo '$(srcdir)/'`examples/libopenmpt_example_c_unsafe.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/$(DEPDIR)/libopenmpt_example_c_unsafe-libopenmpt_example_c_unsafe.Tpo examples/$(DEPDIR)/libopenmpt_example_c_unsafe-libopenmpt_example_c_unsafe.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/libopenmpt_example_c_unsafe.c' object='examples/libopenmpt_example_c_unsafe-libopenmpt_example_c_unsafe.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_example_c_unsafe_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_example_c_unsafe_CFLAGS) $(CFLAGS) -c -o examples/libopenmpt_example_c_unsafe-libopenmpt_example_c_unsafe.o `test -f 'examples/libopenmpt_example_c_unsafe.c' || echo '$(srcdir)/'`examples/libopenmpt_example_c_unsafe.c examples/libopenmpt_example_c_unsafe-libopenmpt_example_c_unsafe.obj: examples/libopenmpt_example_c_unsafe.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_example_c_unsafe_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_example_c_unsafe_CFLAGS) $(CFLAGS) -MT examples/libopenmpt_example_c_unsafe-libopenmpt_example_c_unsafe.obj -MD -MP -MF examples/$(DEPDIR)/libopenmpt_example_c_unsafe-libopenmpt_example_c_unsafe.Tpo -c -o examples/libopenmpt_example_c_unsafe-libopenmpt_example_c_unsafe.obj `if test -f 'examples/libopenmpt_example_c_unsafe.c'; then $(CYGPATH_W) 'examples/libopenmpt_example_c_unsafe.c'; else $(CYGPATH_W) '$(srcdir)/examples/libopenmpt_example_c_unsafe.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/$(DEPDIR)/libopenmpt_example_c_unsafe-libopenmpt_example_c_unsafe.Tpo examples/$(DEPDIR)/libopenmpt_example_c_unsafe-libopenmpt_example_c_unsafe.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/libopenmpt_example_c_unsafe.c' object='examples/libopenmpt_example_c_unsafe-libopenmpt_example_c_unsafe.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_example_c_unsafe_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_example_c_unsafe_CFLAGS) $(CFLAGS) -c -o examples/libopenmpt_example_c_unsafe-libopenmpt_example_c_unsafe.obj `if test -f 'examples/libopenmpt_example_c_unsafe.c'; then $(CYGPATH_W) 'examples/libopenmpt_example_c_unsafe.c'; else $(CYGPATH_W) '$(srcdir)/examples/libopenmpt_example_c_unsafe.c'; fi` .cpp.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< libopenmpt/libmodplug_la-libopenmpt_modplug_cpp.lo: libopenmpt/libopenmpt_modplug_cpp.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmodplug_la_CPPFLAGS) $(CPPFLAGS) $(libmodplug_la_CXXFLAGS) $(CXXFLAGS) -MT libopenmpt/libmodplug_la-libopenmpt_modplug_cpp.lo -MD -MP -MF libopenmpt/$(DEPDIR)/libmodplug_la-libopenmpt_modplug_cpp.Tpo -c -o libopenmpt/libmodplug_la-libopenmpt_modplug_cpp.lo `test -f 'libopenmpt/libopenmpt_modplug_cpp.cpp' || echo '$(srcdir)/'`libopenmpt/libopenmpt_modplug_cpp.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) libopenmpt/$(DEPDIR)/libmodplug_la-libopenmpt_modplug_cpp.Tpo libopenmpt/$(DEPDIR)/libmodplug_la-libopenmpt_modplug_cpp.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='libopenmpt/libopenmpt_modplug_cpp.cpp' object='libopenmpt/libmodplug_la-libopenmpt_modplug_cpp.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmodplug_la_CPPFLAGS) $(CPPFLAGS) $(libmodplug_la_CXXFLAGS) $(CXXFLAGS) -c -o libopenmpt/libmodplug_la-libopenmpt_modplug_cpp.lo `test -f 'libopenmpt/libopenmpt_modplug_cpp.cpp' || echo '$(srcdir)/'`libopenmpt/libopenmpt_modplug_cpp.cpp common/libopenmpt_la-ComponentManager.lo: common/ComponentManager.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpt_la-ComponentManager.lo -MD -MP -MF common/$(DEPDIR)/libopenmpt_la-ComponentManager.Tpo -c -o common/libopenmpt_la-ComponentManager.lo `test -f 'common/ComponentManager.cpp' || echo '$(srcdir)/'`common/ComponentManager.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpt_la-ComponentManager.Tpo common/$(DEPDIR)/libopenmpt_la-ComponentManager.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/ComponentManager.cpp' object='common/libopenmpt_la-ComponentManager.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpt_la-ComponentManager.lo `test -f 'common/ComponentManager.cpp' || echo '$(srcdir)/'`common/ComponentManager.cpp common/libopenmpt_la-FileReader.lo: common/FileReader.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpt_la-FileReader.lo -MD -MP -MF common/$(DEPDIR)/libopenmpt_la-FileReader.Tpo -c -o common/libopenmpt_la-FileReader.lo `test -f 'common/FileReader.cpp' || echo '$(srcdir)/'`common/FileReader.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpt_la-FileReader.Tpo common/$(DEPDIR)/libopenmpt_la-FileReader.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/FileReader.cpp' object='common/libopenmpt_la-FileReader.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpt_la-FileReader.lo `test -f 'common/FileReader.cpp' || echo '$(srcdir)/'`common/FileReader.cpp common/libopenmpt_la-Logging.lo: common/Logging.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpt_la-Logging.lo -MD -MP -MF common/$(DEPDIR)/libopenmpt_la-Logging.Tpo -c -o common/libopenmpt_la-Logging.lo `test -f 'common/Logging.cpp' || echo '$(srcdir)/'`common/Logging.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpt_la-Logging.Tpo common/$(DEPDIR)/libopenmpt_la-Logging.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/Logging.cpp' object='common/libopenmpt_la-Logging.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpt_la-Logging.lo `test -f 'common/Logging.cpp' || echo '$(srcdir)/'`common/Logging.cpp common/libopenmpt_la-misc_util.lo: common/misc_util.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpt_la-misc_util.lo -MD -MP -MF common/$(DEPDIR)/libopenmpt_la-misc_util.Tpo -c -o common/libopenmpt_la-misc_util.lo `test -f 'common/misc_util.cpp' || echo '$(srcdir)/'`common/misc_util.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpt_la-misc_util.Tpo common/$(DEPDIR)/libopenmpt_la-misc_util.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/misc_util.cpp' object='common/libopenmpt_la-misc_util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpt_la-misc_util.lo `test -f 'common/misc_util.cpp' || echo '$(srcdir)/'`common/misc_util.cpp common/libopenmpt_la-mptCPU.lo: common/mptCPU.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpt_la-mptCPU.lo -MD -MP -MF common/$(DEPDIR)/libopenmpt_la-mptCPU.Tpo -c -o common/libopenmpt_la-mptCPU.lo `test -f 'common/mptCPU.cpp' || echo '$(srcdir)/'`common/mptCPU.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpt_la-mptCPU.Tpo common/$(DEPDIR)/libopenmpt_la-mptCPU.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptCPU.cpp' object='common/libopenmpt_la-mptCPU.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpt_la-mptCPU.lo `test -f 'common/mptCPU.cpp' || echo '$(srcdir)/'`common/mptCPU.cpp common/libopenmpt_la-mptFileIO.lo: common/mptFileIO.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpt_la-mptFileIO.lo -MD -MP -MF common/$(DEPDIR)/libopenmpt_la-mptFileIO.Tpo -c -o common/libopenmpt_la-mptFileIO.lo `test -f 'common/mptFileIO.cpp' || echo '$(srcdir)/'`common/mptFileIO.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpt_la-mptFileIO.Tpo common/$(DEPDIR)/libopenmpt_la-mptFileIO.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptFileIO.cpp' object='common/libopenmpt_la-mptFileIO.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpt_la-mptFileIO.lo `test -f 'common/mptFileIO.cpp' || echo '$(srcdir)/'`common/mptFileIO.cpp common/libopenmpt_la-mptIO.lo: common/mptIO.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpt_la-mptIO.lo -MD -MP -MF common/$(DEPDIR)/libopenmpt_la-mptIO.Tpo -c -o common/libopenmpt_la-mptIO.lo `test -f 'common/mptIO.cpp' || echo '$(srcdir)/'`common/mptIO.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpt_la-mptIO.Tpo common/$(DEPDIR)/libopenmpt_la-mptIO.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptIO.cpp' object='common/libopenmpt_la-mptIO.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpt_la-mptIO.lo `test -f 'common/mptIO.cpp' || echo '$(srcdir)/'`common/mptIO.cpp common/libopenmpt_la-mptLibrary.lo: common/mptLibrary.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpt_la-mptLibrary.lo -MD -MP -MF common/$(DEPDIR)/libopenmpt_la-mptLibrary.Tpo -c -o common/libopenmpt_la-mptLibrary.lo `test -f 'common/mptLibrary.cpp' || echo '$(srcdir)/'`common/mptLibrary.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpt_la-mptLibrary.Tpo common/$(DEPDIR)/libopenmpt_la-mptLibrary.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptLibrary.cpp' object='common/libopenmpt_la-mptLibrary.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpt_la-mptLibrary.lo `test -f 'common/mptLibrary.cpp' || echo '$(srcdir)/'`common/mptLibrary.cpp common/libopenmpt_la-mptOS.lo: common/mptOS.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpt_la-mptOS.lo -MD -MP -MF common/$(DEPDIR)/libopenmpt_la-mptOS.Tpo -c -o common/libopenmpt_la-mptOS.lo `test -f 'common/mptOS.cpp' || echo '$(srcdir)/'`common/mptOS.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpt_la-mptOS.Tpo common/$(DEPDIR)/libopenmpt_la-mptOS.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptOS.cpp' object='common/libopenmpt_la-mptOS.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpt_la-mptOS.lo `test -f 'common/mptOS.cpp' || echo '$(srcdir)/'`common/mptOS.cpp common/libopenmpt_la-mptPathString.lo: common/mptPathString.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpt_la-mptPathString.lo -MD -MP -MF common/$(DEPDIR)/libopenmpt_la-mptPathString.Tpo -c -o common/libopenmpt_la-mptPathString.lo `test -f 'common/mptPathString.cpp' || echo '$(srcdir)/'`common/mptPathString.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpt_la-mptPathString.Tpo common/$(DEPDIR)/libopenmpt_la-mptPathString.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptPathString.cpp' object='common/libopenmpt_la-mptPathString.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpt_la-mptPathString.lo `test -f 'common/mptPathString.cpp' || echo '$(srcdir)/'`common/mptPathString.cpp common/libopenmpt_la-mptRandom.lo: common/mptRandom.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpt_la-mptRandom.lo -MD -MP -MF common/$(DEPDIR)/libopenmpt_la-mptRandom.Tpo -c -o common/libopenmpt_la-mptRandom.lo `test -f 'common/mptRandom.cpp' || echo '$(srcdir)/'`common/mptRandom.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpt_la-mptRandom.Tpo common/$(DEPDIR)/libopenmpt_la-mptRandom.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptRandom.cpp' object='common/libopenmpt_la-mptRandom.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpt_la-mptRandom.lo `test -f 'common/mptRandom.cpp' || echo '$(srcdir)/'`common/mptRandom.cpp common/libopenmpt_la-mptString.lo: common/mptString.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpt_la-mptString.lo -MD -MP -MF common/$(DEPDIR)/libopenmpt_la-mptString.Tpo -c -o common/libopenmpt_la-mptString.lo `test -f 'common/mptString.cpp' || echo '$(srcdir)/'`common/mptString.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpt_la-mptString.Tpo common/$(DEPDIR)/libopenmpt_la-mptString.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptString.cpp' object='common/libopenmpt_la-mptString.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpt_la-mptString.lo `test -f 'common/mptString.cpp' || echo '$(srcdir)/'`common/mptString.cpp common/libopenmpt_la-mptStringFormat.lo: common/mptStringFormat.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpt_la-mptStringFormat.lo -MD -MP -MF common/$(DEPDIR)/libopenmpt_la-mptStringFormat.Tpo -c -o common/libopenmpt_la-mptStringFormat.lo `test -f 'common/mptStringFormat.cpp' || echo '$(srcdir)/'`common/mptStringFormat.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpt_la-mptStringFormat.Tpo common/$(DEPDIR)/libopenmpt_la-mptStringFormat.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptStringFormat.cpp' object='common/libopenmpt_la-mptStringFormat.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpt_la-mptStringFormat.lo `test -f 'common/mptStringFormat.cpp' || echo '$(srcdir)/'`common/mptStringFormat.cpp common/libopenmpt_la-mptStringParse.lo: common/mptStringParse.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpt_la-mptStringParse.lo -MD -MP -MF common/$(DEPDIR)/libopenmpt_la-mptStringParse.Tpo -c -o common/libopenmpt_la-mptStringParse.lo `test -f 'common/mptStringParse.cpp' || echo '$(srcdir)/'`common/mptStringParse.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpt_la-mptStringParse.Tpo common/$(DEPDIR)/libopenmpt_la-mptStringParse.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptStringParse.cpp' object='common/libopenmpt_la-mptStringParse.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpt_la-mptStringParse.lo `test -f 'common/mptStringParse.cpp' || echo '$(srcdir)/'`common/mptStringParse.cpp common/libopenmpt_la-mptTime.lo: common/mptTime.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpt_la-mptTime.lo -MD -MP -MF common/$(DEPDIR)/libopenmpt_la-mptTime.Tpo -c -o common/libopenmpt_la-mptTime.lo `test -f 'common/mptTime.cpp' || echo '$(srcdir)/'`common/mptTime.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpt_la-mptTime.Tpo common/$(DEPDIR)/libopenmpt_la-mptTime.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptTime.cpp' object='common/libopenmpt_la-mptTime.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpt_la-mptTime.lo `test -f 'common/mptTime.cpp' || echo '$(srcdir)/'`common/mptTime.cpp common/libopenmpt_la-mptUUID.lo: common/mptUUID.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpt_la-mptUUID.lo -MD -MP -MF common/$(DEPDIR)/libopenmpt_la-mptUUID.Tpo -c -o common/libopenmpt_la-mptUUID.lo `test -f 'common/mptUUID.cpp' || echo '$(srcdir)/'`common/mptUUID.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpt_la-mptUUID.Tpo common/$(DEPDIR)/libopenmpt_la-mptUUID.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptUUID.cpp' object='common/libopenmpt_la-mptUUID.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpt_la-mptUUID.lo `test -f 'common/mptUUID.cpp' || echo '$(srcdir)/'`common/mptUUID.cpp common/libopenmpt_la-mptWine.lo: common/mptWine.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpt_la-mptWine.lo -MD -MP -MF common/$(DEPDIR)/libopenmpt_la-mptWine.Tpo -c -o common/libopenmpt_la-mptWine.lo `test -f 'common/mptWine.cpp' || echo '$(srcdir)/'`common/mptWine.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpt_la-mptWine.Tpo common/$(DEPDIR)/libopenmpt_la-mptWine.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptWine.cpp' object='common/libopenmpt_la-mptWine.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpt_la-mptWine.lo `test -f 'common/mptWine.cpp' || echo '$(srcdir)/'`common/mptWine.cpp common/libopenmpt_la-Profiler.lo: common/Profiler.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpt_la-Profiler.lo -MD -MP -MF common/$(DEPDIR)/libopenmpt_la-Profiler.Tpo -c -o common/libopenmpt_la-Profiler.lo `test -f 'common/Profiler.cpp' || echo '$(srcdir)/'`common/Profiler.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpt_la-Profiler.Tpo common/$(DEPDIR)/libopenmpt_la-Profiler.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/Profiler.cpp' object='common/libopenmpt_la-Profiler.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpt_la-Profiler.lo `test -f 'common/Profiler.cpp' || echo '$(srcdir)/'`common/Profiler.cpp common/libopenmpt_la-serialization_utils.lo: common/serialization_utils.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpt_la-serialization_utils.lo -MD -MP -MF common/$(DEPDIR)/libopenmpt_la-serialization_utils.Tpo -c -o common/libopenmpt_la-serialization_utils.lo `test -f 'common/serialization_utils.cpp' || echo '$(srcdir)/'`common/serialization_utils.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpt_la-serialization_utils.Tpo common/$(DEPDIR)/libopenmpt_la-serialization_utils.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/serialization_utils.cpp' object='common/libopenmpt_la-serialization_utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpt_la-serialization_utils.lo `test -f 'common/serialization_utils.cpp' || echo '$(srcdir)/'`common/serialization_utils.cpp common/libopenmpt_la-stdafx.lo: common/stdafx.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpt_la-stdafx.lo -MD -MP -MF common/$(DEPDIR)/libopenmpt_la-stdafx.Tpo -c -o common/libopenmpt_la-stdafx.lo `test -f 'common/stdafx.cpp' || echo '$(srcdir)/'`common/stdafx.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpt_la-stdafx.Tpo common/$(DEPDIR)/libopenmpt_la-stdafx.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/stdafx.cpp' object='common/libopenmpt_la-stdafx.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpt_la-stdafx.lo `test -f 'common/stdafx.cpp' || echo '$(srcdir)/'`common/stdafx.cpp common/libopenmpt_la-typedefs.lo: common/typedefs.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpt_la-typedefs.lo -MD -MP -MF common/$(DEPDIR)/libopenmpt_la-typedefs.Tpo -c -o common/libopenmpt_la-typedefs.lo `test -f 'common/typedefs.cpp' || echo '$(srcdir)/'`common/typedefs.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpt_la-typedefs.Tpo common/$(DEPDIR)/libopenmpt_la-typedefs.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/typedefs.cpp' object='common/libopenmpt_la-typedefs.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpt_la-typedefs.lo `test -f 'common/typedefs.cpp' || echo '$(srcdir)/'`common/typedefs.cpp common/libopenmpt_la-version.lo: common/version.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpt_la-version.lo -MD -MP -MF common/$(DEPDIR)/libopenmpt_la-version.Tpo -c -o common/libopenmpt_la-version.lo `test -f 'common/version.cpp' || echo '$(srcdir)/'`common/version.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpt_la-version.Tpo common/$(DEPDIR)/libopenmpt_la-version.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/version.cpp' object='common/libopenmpt_la-version.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpt_la-version.lo `test -f 'common/version.cpp' || echo '$(srcdir)/'`common/version.cpp soundlib/libopenmpt_la-AudioCriticalSection.lo: soundlib/AudioCriticalSection.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-AudioCriticalSection.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-AudioCriticalSection.Tpo -c -o soundlib/libopenmpt_la-AudioCriticalSection.lo `test -f 'soundlib/AudioCriticalSection.cpp' || echo '$(srcdir)/'`soundlib/AudioCriticalSection.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-AudioCriticalSection.Tpo soundlib/$(DEPDIR)/libopenmpt_la-AudioCriticalSection.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/AudioCriticalSection.cpp' object='soundlib/libopenmpt_la-AudioCriticalSection.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-AudioCriticalSection.lo `test -f 'soundlib/AudioCriticalSection.cpp' || echo '$(srcdir)/'`soundlib/AudioCriticalSection.cpp soundlib/libopenmpt_la-ContainerMMCMP.lo: soundlib/ContainerMMCMP.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-ContainerMMCMP.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-ContainerMMCMP.Tpo -c -o soundlib/libopenmpt_la-ContainerMMCMP.lo `test -f 'soundlib/ContainerMMCMP.cpp' || echo '$(srcdir)/'`soundlib/ContainerMMCMP.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-ContainerMMCMP.Tpo soundlib/$(DEPDIR)/libopenmpt_la-ContainerMMCMP.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/ContainerMMCMP.cpp' object='soundlib/libopenmpt_la-ContainerMMCMP.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-ContainerMMCMP.lo `test -f 'soundlib/ContainerMMCMP.cpp' || echo '$(srcdir)/'`soundlib/ContainerMMCMP.cpp soundlib/libopenmpt_la-ContainerPP20.lo: soundlib/ContainerPP20.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-ContainerPP20.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-ContainerPP20.Tpo -c -o soundlib/libopenmpt_la-ContainerPP20.lo `test -f 'soundlib/ContainerPP20.cpp' || echo '$(srcdir)/'`soundlib/ContainerPP20.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-ContainerPP20.Tpo soundlib/$(DEPDIR)/libopenmpt_la-ContainerPP20.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/ContainerPP20.cpp' object='soundlib/libopenmpt_la-ContainerPP20.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-ContainerPP20.lo `test -f 'soundlib/ContainerPP20.cpp' || echo '$(srcdir)/'`soundlib/ContainerPP20.cpp soundlib/libopenmpt_la-ContainerUMX.lo: soundlib/ContainerUMX.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-ContainerUMX.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-ContainerUMX.Tpo -c -o soundlib/libopenmpt_la-ContainerUMX.lo `test -f 'soundlib/ContainerUMX.cpp' || echo '$(srcdir)/'`soundlib/ContainerUMX.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-ContainerUMX.Tpo soundlib/$(DEPDIR)/libopenmpt_la-ContainerUMX.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/ContainerUMX.cpp' object='soundlib/libopenmpt_la-ContainerUMX.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-ContainerUMX.lo `test -f 'soundlib/ContainerUMX.cpp' || echo '$(srcdir)/'`soundlib/ContainerUMX.cpp soundlib/libopenmpt_la-ContainerXPK.lo: soundlib/ContainerXPK.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-ContainerXPK.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-ContainerXPK.Tpo -c -o soundlib/libopenmpt_la-ContainerXPK.lo `test -f 'soundlib/ContainerXPK.cpp' || echo '$(srcdir)/'`soundlib/ContainerXPK.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-ContainerXPK.Tpo soundlib/$(DEPDIR)/libopenmpt_la-ContainerXPK.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/ContainerXPK.cpp' object='soundlib/libopenmpt_la-ContainerXPK.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-ContainerXPK.lo `test -f 'soundlib/ContainerXPK.cpp' || echo '$(srcdir)/'`soundlib/ContainerXPK.cpp soundlib/libopenmpt_la-Dither.lo: soundlib/Dither.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Dither.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Dither.Tpo -c -o soundlib/libopenmpt_la-Dither.lo `test -f 'soundlib/Dither.cpp' || echo '$(srcdir)/'`soundlib/Dither.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Dither.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Dither.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Dither.cpp' object='soundlib/libopenmpt_la-Dither.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Dither.lo `test -f 'soundlib/Dither.cpp' || echo '$(srcdir)/'`soundlib/Dither.cpp soundlib/libopenmpt_la-Dlsbank.lo: soundlib/Dlsbank.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Dlsbank.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Dlsbank.Tpo -c -o soundlib/libopenmpt_la-Dlsbank.lo `test -f 'soundlib/Dlsbank.cpp' || echo '$(srcdir)/'`soundlib/Dlsbank.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Dlsbank.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Dlsbank.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Dlsbank.cpp' object='soundlib/libopenmpt_la-Dlsbank.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Dlsbank.lo `test -f 'soundlib/Dlsbank.cpp' || echo '$(srcdir)/'`soundlib/Dlsbank.cpp soundlib/libopenmpt_la-Fastmix.lo: soundlib/Fastmix.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Fastmix.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Fastmix.Tpo -c -o soundlib/libopenmpt_la-Fastmix.lo `test -f 'soundlib/Fastmix.cpp' || echo '$(srcdir)/'`soundlib/Fastmix.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Fastmix.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Fastmix.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Fastmix.cpp' object='soundlib/libopenmpt_la-Fastmix.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Fastmix.lo `test -f 'soundlib/Fastmix.cpp' || echo '$(srcdir)/'`soundlib/Fastmix.cpp soundlib/libopenmpt_la-InstrumentExtensions.lo: soundlib/InstrumentExtensions.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-InstrumentExtensions.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-InstrumentExtensions.Tpo -c -o soundlib/libopenmpt_la-InstrumentExtensions.lo `test -f 'soundlib/InstrumentExtensions.cpp' || echo '$(srcdir)/'`soundlib/InstrumentExtensions.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-InstrumentExtensions.Tpo soundlib/$(DEPDIR)/libopenmpt_la-InstrumentExtensions.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/InstrumentExtensions.cpp' object='soundlib/libopenmpt_la-InstrumentExtensions.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-InstrumentExtensions.lo `test -f 'soundlib/InstrumentExtensions.cpp' || echo '$(srcdir)/'`soundlib/InstrumentExtensions.cpp soundlib/libopenmpt_la-ITCompression.lo: soundlib/ITCompression.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-ITCompression.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-ITCompression.Tpo -c -o soundlib/libopenmpt_la-ITCompression.lo `test -f 'soundlib/ITCompression.cpp' || echo '$(srcdir)/'`soundlib/ITCompression.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-ITCompression.Tpo soundlib/$(DEPDIR)/libopenmpt_la-ITCompression.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/ITCompression.cpp' object='soundlib/libopenmpt_la-ITCompression.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-ITCompression.lo `test -f 'soundlib/ITCompression.cpp' || echo '$(srcdir)/'`soundlib/ITCompression.cpp soundlib/libopenmpt_la-ITTools.lo: soundlib/ITTools.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-ITTools.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-ITTools.Tpo -c -o soundlib/libopenmpt_la-ITTools.lo `test -f 'soundlib/ITTools.cpp' || echo '$(srcdir)/'`soundlib/ITTools.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-ITTools.Tpo soundlib/$(DEPDIR)/libopenmpt_la-ITTools.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/ITTools.cpp' object='soundlib/libopenmpt_la-ITTools.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-ITTools.lo `test -f 'soundlib/ITTools.cpp' || echo '$(srcdir)/'`soundlib/ITTools.cpp soundlib/libopenmpt_la-Load_669.lo: soundlib/Load_669.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Load_669.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Load_669.Tpo -c -o soundlib/libopenmpt_la-Load_669.lo `test -f 'soundlib/Load_669.cpp' || echo '$(srcdir)/'`soundlib/Load_669.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Load_669.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Load_669.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_669.cpp' object='soundlib/libopenmpt_la-Load_669.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Load_669.lo `test -f 'soundlib/Load_669.cpp' || echo '$(srcdir)/'`soundlib/Load_669.cpp soundlib/libopenmpt_la-Load_amf.lo: soundlib/Load_amf.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Load_amf.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Load_amf.Tpo -c -o soundlib/libopenmpt_la-Load_amf.lo `test -f 'soundlib/Load_amf.cpp' || echo '$(srcdir)/'`soundlib/Load_amf.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Load_amf.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Load_amf.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_amf.cpp' object='soundlib/libopenmpt_la-Load_amf.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Load_amf.lo `test -f 'soundlib/Load_amf.cpp' || echo '$(srcdir)/'`soundlib/Load_amf.cpp soundlib/libopenmpt_la-Load_ams.lo: soundlib/Load_ams.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Load_ams.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Load_ams.Tpo -c -o soundlib/libopenmpt_la-Load_ams.lo `test -f 'soundlib/Load_ams.cpp' || echo '$(srcdir)/'`soundlib/Load_ams.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Load_ams.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Load_ams.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_ams.cpp' object='soundlib/libopenmpt_la-Load_ams.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Load_ams.lo `test -f 'soundlib/Load_ams.cpp' || echo '$(srcdir)/'`soundlib/Load_ams.cpp soundlib/libopenmpt_la-Load_dbm.lo: soundlib/Load_dbm.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Load_dbm.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Load_dbm.Tpo -c -o soundlib/libopenmpt_la-Load_dbm.lo `test -f 'soundlib/Load_dbm.cpp' || echo '$(srcdir)/'`soundlib/Load_dbm.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Load_dbm.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Load_dbm.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_dbm.cpp' object='soundlib/libopenmpt_la-Load_dbm.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Load_dbm.lo `test -f 'soundlib/Load_dbm.cpp' || echo '$(srcdir)/'`soundlib/Load_dbm.cpp soundlib/libopenmpt_la-Load_digi.lo: soundlib/Load_digi.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Load_digi.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Load_digi.Tpo -c -o soundlib/libopenmpt_la-Load_digi.lo `test -f 'soundlib/Load_digi.cpp' || echo '$(srcdir)/'`soundlib/Load_digi.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Load_digi.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Load_digi.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_digi.cpp' object='soundlib/libopenmpt_la-Load_digi.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Load_digi.lo `test -f 'soundlib/Load_digi.cpp' || echo '$(srcdir)/'`soundlib/Load_digi.cpp soundlib/libopenmpt_la-Load_dmf.lo: soundlib/Load_dmf.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Load_dmf.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Load_dmf.Tpo -c -o soundlib/libopenmpt_la-Load_dmf.lo `test -f 'soundlib/Load_dmf.cpp' || echo '$(srcdir)/'`soundlib/Load_dmf.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Load_dmf.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Load_dmf.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_dmf.cpp' object='soundlib/libopenmpt_la-Load_dmf.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Load_dmf.lo `test -f 'soundlib/Load_dmf.cpp' || echo '$(srcdir)/'`soundlib/Load_dmf.cpp soundlib/libopenmpt_la-Load_dsm.lo: soundlib/Load_dsm.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Load_dsm.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Load_dsm.Tpo -c -o soundlib/libopenmpt_la-Load_dsm.lo `test -f 'soundlib/Load_dsm.cpp' || echo '$(srcdir)/'`soundlib/Load_dsm.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Load_dsm.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Load_dsm.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_dsm.cpp' object='soundlib/libopenmpt_la-Load_dsm.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Load_dsm.lo `test -f 'soundlib/Load_dsm.cpp' || echo '$(srcdir)/'`soundlib/Load_dsm.cpp soundlib/libopenmpt_la-Load_dtm.lo: soundlib/Load_dtm.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Load_dtm.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Load_dtm.Tpo -c -o soundlib/libopenmpt_la-Load_dtm.lo `test -f 'soundlib/Load_dtm.cpp' || echo '$(srcdir)/'`soundlib/Load_dtm.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Load_dtm.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Load_dtm.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_dtm.cpp' object='soundlib/libopenmpt_la-Load_dtm.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Load_dtm.lo `test -f 'soundlib/Load_dtm.cpp' || echo '$(srcdir)/'`soundlib/Load_dtm.cpp soundlib/libopenmpt_la-Load_far.lo: soundlib/Load_far.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Load_far.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Load_far.Tpo -c -o soundlib/libopenmpt_la-Load_far.lo `test -f 'soundlib/Load_far.cpp' || echo '$(srcdir)/'`soundlib/Load_far.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Load_far.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Load_far.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_far.cpp' object='soundlib/libopenmpt_la-Load_far.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Load_far.lo `test -f 'soundlib/Load_far.cpp' || echo '$(srcdir)/'`soundlib/Load_far.cpp soundlib/libopenmpt_la-Load_gdm.lo: soundlib/Load_gdm.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Load_gdm.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Load_gdm.Tpo -c -o soundlib/libopenmpt_la-Load_gdm.lo `test -f 'soundlib/Load_gdm.cpp' || echo '$(srcdir)/'`soundlib/Load_gdm.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Load_gdm.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Load_gdm.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_gdm.cpp' object='soundlib/libopenmpt_la-Load_gdm.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Load_gdm.lo `test -f 'soundlib/Load_gdm.cpp' || echo '$(srcdir)/'`soundlib/Load_gdm.cpp soundlib/libopenmpt_la-Load_imf.lo: soundlib/Load_imf.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Load_imf.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Load_imf.Tpo -c -o soundlib/libopenmpt_la-Load_imf.lo `test -f 'soundlib/Load_imf.cpp' || echo '$(srcdir)/'`soundlib/Load_imf.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Load_imf.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Load_imf.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_imf.cpp' object='soundlib/libopenmpt_la-Load_imf.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Load_imf.lo `test -f 'soundlib/Load_imf.cpp' || echo '$(srcdir)/'`soundlib/Load_imf.cpp soundlib/libopenmpt_la-Load_it.lo: soundlib/Load_it.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Load_it.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Load_it.Tpo -c -o soundlib/libopenmpt_la-Load_it.lo `test -f 'soundlib/Load_it.cpp' || echo '$(srcdir)/'`soundlib/Load_it.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Load_it.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Load_it.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_it.cpp' object='soundlib/libopenmpt_la-Load_it.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Load_it.lo `test -f 'soundlib/Load_it.cpp' || echo '$(srcdir)/'`soundlib/Load_it.cpp soundlib/libopenmpt_la-Load_itp.lo: soundlib/Load_itp.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Load_itp.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Load_itp.Tpo -c -o soundlib/libopenmpt_la-Load_itp.lo `test -f 'soundlib/Load_itp.cpp' || echo '$(srcdir)/'`soundlib/Load_itp.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Load_itp.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Load_itp.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_itp.cpp' object='soundlib/libopenmpt_la-Load_itp.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Load_itp.lo `test -f 'soundlib/Load_itp.cpp' || echo '$(srcdir)/'`soundlib/Load_itp.cpp soundlib/libopenmpt_la-load_j2b.lo: soundlib/load_j2b.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-load_j2b.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-load_j2b.Tpo -c -o soundlib/libopenmpt_la-load_j2b.lo `test -f 'soundlib/load_j2b.cpp' || echo '$(srcdir)/'`soundlib/load_j2b.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-load_j2b.Tpo soundlib/$(DEPDIR)/libopenmpt_la-load_j2b.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/load_j2b.cpp' object='soundlib/libopenmpt_la-load_j2b.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-load_j2b.lo `test -f 'soundlib/load_j2b.cpp' || echo '$(srcdir)/'`soundlib/load_j2b.cpp soundlib/libopenmpt_la-Load_mdl.lo: soundlib/Load_mdl.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Load_mdl.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Load_mdl.Tpo -c -o soundlib/libopenmpt_la-Load_mdl.lo `test -f 'soundlib/Load_mdl.cpp' || echo '$(srcdir)/'`soundlib/Load_mdl.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Load_mdl.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Load_mdl.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_mdl.cpp' object='soundlib/libopenmpt_la-Load_mdl.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Load_mdl.lo `test -f 'soundlib/Load_mdl.cpp' || echo '$(srcdir)/'`soundlib/Load_mdl.cpp soundlib/libopenmpt_la-Load_med.lo: soundlib/Load_med.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Load_med.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Load_med.Tpo -c -o soundlib/libopenmpt_la-Load_med.lo `test -f 'soundlib/Load_med.cpp' || echo '$(srcdir)/'`soundlib/Load_med.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Load_med.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Load_med.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_med.cpp' object='soundlib/libopenmpt_la-Load_med.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Load_med.lo `test -f 'soundlib/Load_med.cpp' || echo '$(srcdir)/'`soundlib/Load_med.cpp soundlib/libopenmpt_la-Load_mid.lo: soundlib/Load_mid.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Load_mid.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Load_mid.Tpo -c -o soundlib/libopenmpt_la-Load_mid.lo `test -f 'soundlib/Load_mid.cpp' || echo '$(srcdir)/'`soundlib/Load_mid.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Load_mid.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Load_mid.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_mid.cpp' object='soundlib/libopenmpt_la-Load_mid.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Load_mid.lo `test -f 'soundlib/Load_mid.cpp' || echo '$(srcdir)/'`soundlib/Load_mid.cpp soundlib/libopenmpt_la-Load_mo3.lo: soundlib/Load_mo3.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Load_mo3.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Load_mo3.Tpo -c -o soundlib/libopenmpt_la-Load_mo3.lo `test -f 'soundlib/Load_mo3.cpp' || echo '$(srcdir)/'`soundlib/Load_mo3.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Load_mo3.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Load_mo3.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_mo3.cpp' object='soundlib/libopenmpt_la-Load_mo3.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Load_mo3.lo `test -f 'soundlib/Load_mo3.cpp' || echo '$(srcdir)/'`soundlib/Load_mo3.cpp soundlib/libopenmpt_la-Load_mod.lo: soundlib/Load_mod.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Load_mod.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Load_mod.Tpo -c -o soundlib/libopenmpt_la-Load_mod.lo `test -f 'soundlib/Load_mod.cpp' || echo '$(srcdir)/'`soundlib/Load_mod.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Load_mod.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Load_mod.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_mod.cpp' object='soundlib/libopenmpt_la-Load_mod.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Load_mod.lo `test -f 'soundlib/Load_mod.cpp' || echo '$(srcdir)/'`soundlib/Load_mod.cpp soundlib/libopenmpt_la-Load_mt2.lo: soundlib/Load_mt2.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Load_mt2.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Load_mt2.Tpo -c -o soundlib/libopenmpt_la-Load_mt2.lo `test -f 'soundlib/Load_mt2.cpp' || echo '$(srcdir)/'`soundlib/Load_mt2.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Load_mt2.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Load_mt2.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_mt2.cpp' object='soundlib/libopenmpt_la-Load_mt2.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Load_mt2.lo `test -f 'soundlib/Load_mt2.cpp' || echo '$(srcdir)/'`soundlib/Load_mt2.cpp soundlib/libopenmpt_la-Load_mtm.lo: soundlib/Load_mtm.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Load_mtm.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Load_mtm.Tpo -c -o soundlib/libopenmpt_la-Load_mtm.lo `test -f 'soundlib/Load_mtm.cpp' || echo '$(srcdir)/'`soundlib/Load_mtm.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Load_mtm.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Load_mtm.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_mtm.cpp' object='soundlib/libopenmpt_la-Load_mtm.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Load_mtm.lo `test -f 'soundlib/Load_mtm.cpp' || echo '$(srcdir)/'`soundlib/Load_mtm.cpp soundlib/libopenmpt_la-Load_okt.lo: soundlib/Load_okt.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Load_okt.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Load_okt.Tpo -c -o soundlib/libopenmpt_la-Load_okt.lo `test -f 'soundlib/Load_okt.cpp' || echo '$(srcdir)/'`soundlib/Load_okt.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Load_okt.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Load_okt.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_okt.cpp' object='soundlib/libopenmpt_la-Load_okt.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Load_okt.lo `test -f 'soundlib/Load_okt.cpp' || echo '$(srcdir)/'`soundlib/Load_okt.cpp soundlib/libopenmpt_la-Load_plm.lo: soundlib/Load_plm.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Load_plm.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Load_plm.Tpo -c -o soundlib/libopenmpt_la-Load_plm.lo `test -f 'soundlib/Load_plm.cpp' || echo '$(srcdir)/'`soundlib/Load_plm.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Load_plm.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Load_plm.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_plm.cpp' object='soundlib/libopenmpt_la-Load_plm.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Load_plm.lo `test -f 'soundlib/Load_plm.cpp' || echo '$(srcdir)/'`soundlib/Load_plm.cpp soundlib/libopenmpt_la-Load_psm.lo: soundlib/Load_psm.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Load_psm.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Load_psm.Tpo -c -o soundlib/libopenmpt_la-Load_psm.lo `test -f 'soundlib/Load_psm.cpp' || echo '$(srcdir)/'`soundlib/Load_psm.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Load_psm.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Load_psm.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_psm.cpp' object='soundlib/libopenmpt_la-Load_psm.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Load_psm.lo `test -f 'soundlib/Load_psm.cpp' || echo '$(srcdir)/'`soundlib/Load_psm.cpp soundlib/libopenmpt_la-Load_ptm.lo: soundlib/Load_ptm.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Load_ptm.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Load_ptm.Tpo -c -o soundlib/libopenmpt_la-Load_ptm.lo `test -f 'soundlib/Load_ptm.cpp' || echo '$(srcdir)/'`soundlib/Load_ptm.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Load_ptm.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Load_ptm.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_ptm.cpp' object='soundlib/libopenmpt_la-Load_ptm.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Load_ptm.lo `test -f 'soundlib/Load_ptm.cpp' || echo '$(srcdir)/'`soundlib/Load_ptm.cpp soundlib/libopenmpt_la-Load_s3m.lo: soundlib/Load_s3m.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Load_s3m.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Load_s3m.Tpo -c -o soundlib/libopenmpt_la-Load_s3m.lo `test -f 'soundlib/Load_s3m.cpp' || echo '$(srcdir)/'`soundlib/Load_s3m.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Load_s3m.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Load_s3m.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_s3m.cpp' object='soundlib/libopenmpt_la-Load_s3m.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Load_s3m.lo `test -f 'soundlib/Load_s3m.cpp' || echo '$(srcdir)/'`soundlib/Load_s3m.cpp soundlib/libopenmpt_la-Load_sfx.lo: soundlib/Load_sfx.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Load_sfx.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Load_sfx.Tpo -c -o soundlib/libopenmpt_la-Load_sfx.lo `test -f 'soundlib/Load_sfx.cpp' || echo '$(srcdir)/'`soundlib/Load_sfx.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Load_sfx.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Load_sfx.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_sfx.cpp' object='soundlib/libopenmpt_la-Load_sfx.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Load_sfx.lo `test -f 'soundlib/Load_sfx.cpp' || echo '$(srcdir)/'`soundlib/Load_sfx.cpp soundlib/libopenmpt_la-Load_stm.lo: soundlib/Load_stm.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Load_stm.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Load_stm.Tpo -c -o soundlib/libopenmpt_la-Load_stm.lo `test -f 'soundlib/Load_stm.cpp' || echo '$(srcdir)/'`soundlib/Load_stm.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Load_stm.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Load_stm.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_stm.cpp' object='soundlib/libopenmpt_la-Load_stm.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Load_stm.lo `test -f 'soundlib/Load_stm.cpp' || echo '$(srcdir)/'`soundlib/Load_stm.cpp soundlib/libopenmpt_la-Load_stp.lo: soundlib/Load_stp.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Load_stp.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Load_stp.Tpo -c -o soundlib/libopenmpt_la-Load_stp.lo `test -f 'soundlib/Load_stp.cpp' || echo '$(srcdir)/'`soundlib/Load_stp.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Load_stp.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Load_stp.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_stp.cpp' object='soundlib/libopenmpt_la-Load_stp.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Load_stp.lo `test -f 'soundlib/Load_stp.cpp' || echo '$(srcdir)/'`soundlib/Load_stp.cpp soundlib/libopenmpt_la-Load_uax.lo: soundlib/Load_uax.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Load_uax.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Load_uax.Tpo -c -o soundlib/libopenmpt_la-Load_uax.lo `test -f 'soundlib/Load_uax.cpp' || echo '$(srcdir)/'`soundlib/Load_uax.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Load_uax.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Load_uax.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_uax.cpp' object='soundlib/libopenmpt_la-Load_uax.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Load_uax.lo `test -f 'soundlib/Load_uax.cpp' || echo '$(srcdir)/'`soundlib/Load_uax.cpp soundlib/libopenmpt_la-Load_ult.lo: soundlib/Load_ult.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Load_ult.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Load_ult.Tpo -c -o soundlib/libopenmpt_la-Load_ult.lo `test -f 'soundlib/Load_ult.cpp' || echo '$(srcdir)/'`soundlib/Load_ult.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Load_ult.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Load_ult.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_ult.cpp' object='soundlib/libopenmpt_la-Load_ult.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Load_ult.lo `test -f 'soundlib/Load_ult.cpp' || echo '$(srcdir)/'`soundlib/Load_ult.cpp soundlib/libopenmpt_la-Load_wav.lo: soundlib/Load_wav.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Load_wav.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Load_wav.Tpo -c -o soundlib/libopenmpt_la-Load_wav.lo `test -f 'soundlib/Load_wav.cpp' || echo '$(srcdir)/'`soundlib/Load_wav.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Load_wav.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Load_wav.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_wav.cpp' object='soundlib/libopenmpt_la-Load_wav.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Load_wav.lo `test -f 'soundlib/Load_wav.cpp' || echo '$(srcdir)/'`soundlib/Load_wav.cpp soundlib/libopenmpt_la-Load_xm.lo: soundlib/Load_xm.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Load_xm.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Load_xm.Tpo -c -o soundlib/libopenmpt_la-Load_xm.lo `test -f 'soundlib/Load_xm.cpp' || echo '$(srcdir)/'`soundlib/Load_xm.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Load_xm.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Load_xm.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_xm.cpp' object='soundlib/libopenmpt_la-Load_xm.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Load_xm.lo `test -f 'soundlib/Load_xm.cpp' || echo '$(srcdir)/'`soundlib/Load_xm.cpp soundlib/libopenmpt_la-Message.lo: soundlib/Message.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Message.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Message.Tpo -c -o soundlib/libopenmpt_la-Message.lo `test -f 'soundlib/Message.cpp' || echo '$(srcdir)/'`soundlib/Message.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Message.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Message.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Message.cpp' object='soundlib/libopenmpt_la-Message.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Message.lo `test -f 'soundlib/Message.cpp' || echo '$(srcdir)/'`soundlib/Message.cpp soundlib/libopenmpt_la-MIDIEvents.lo: soundlib/MIDIEvents.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-MIDIEvents.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-MIDIEvents.Tpo -c -o soundlib/libopenmpt_la-MIDIEvents.lo `test -f 'soundlib/MIDIEvents.cpp' || echo '$(srcdir)/'`soundlib/MIDIEvents.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-MIDIEvents.Tpo soundlib/$(DEPDIR)/libopenmpt_la-MIDIEvents.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/MIDIEvents.cpp' object='soundlib/libopenmpt_la-MIDIEvents.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-MIDIEvents.lo `test -f 'soundlib/MIDIEvents.cpp' || echo '$(srcdir)/'`soundlib/MIDIEvents.cpp soundlib/libopenmpt_la-MIDIMacros.lo: soundlib/MIDIMacros.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-MIDIMacros.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-MIDIMacros.Tpo -c -o soundlib/libopenmpt_la-MIDIMacros.lo `test -f 'soundlib/MIDIMacros.cpp' || echo '$(srcdir)/'`soundlib/MIDIMacros.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-MIDIMacros.Tpo soundlib/$(DEPDIR)/libopenmpt_la-MIDIMacros.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/MIDIMacros.cpp' object='soundlib/libopenmpt_la-MIDIMacros.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-MIDIMacros.lo `test -f 'soundlib/MIDIMacros.cpp' || echo '$(srcdir)/'`soundlib/MIDIMacros.cpp soundlib/libopenmpt_la-MixerLoops.lo: soundlib/MixerLoops.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-MixerLoops.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-MixerLoops.Tpo -c -o soundlib/libopenmpt_la-MixerLoops.lo `test -f 'soundlib/MixerLoops.cpp' || echo '$(srcdir)/'`soundlib/MixerLoops.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-MixerLoops.Tpo soundlib/$(DEPDIR)/libopenmpt_la-MixerLoops.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/MixerLoops.cpp' object='soundlib/libopenmpt_la-MixerLoops.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-MixerLoops.lo `test -f 'soundlib/MixerLoops.cpp' || echo '$(srcdir)/'`soundlib/MixerLoops.cpp soundlib/libopenmpt_la-MixerSettings.lo: soundlib/MixerSettings.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-MixerSettings.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-MixerSettings.Tpo -c -o soundlib/libopenmpt_la-MixerSettings.lo `test -f 'soundlib/MixerSettings.cpp' || echo '$(srcdir)/'`soundlib/MixerSettings.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-MixerSettings.Tpo soundlib/$(DEPDIR)/libopenmpt_la-MixerSettings.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/MixerSettings.cpp' object='soundlib/libopenmpt_la-MixerSettings.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-MixerSettings.lo `test -f 'soundlib/MixerSettings.cpp' || echo '$(srcdir)/'`soundlib/MixerSettings.cpp soundlib/libopenmpt_la-MixFuncTable.lo: soundlib/MixFuncTable.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-MixFuncTable.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-MixFuncTable.Tpo -c -o soundlib/libopenmpt_la-MixFuncTable.lo `test -f 'soundlib/MixFuncTable.cpp' || echo '$(srcdir)/'`soundlib/MixFuncTable.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-MixFuncTable.Tpo soundlib/$(DEPDIR)/libopenmpt_la-MixFuncTable.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/MixFuncTable.cpp' object='soundlib/libopenmpt_la-MixFuncTable.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-MixFuncTable.lo `test -f 'soundlib/MixFuncTable.cpp' || echo '$(srcdir)/'`soundlib/MixFuncTable.cpp soundlib/libopenmpt_la-ModChannel.lo: soundlib/ModChannel.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-ModChannel.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-ModChannel.Tpo -c -o soundlib/libopenmpt_la-ModChannel.lo `test -f 'soundlib/ModChannel.cpp' || echo '$(srcdir)/'`soundlib/ModChannel.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-ModChannel.Tpo soundlib/$(DEPDIR)/libopenmpt_la-ModChannel.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/ModChannel.cpp' object='soundlib/libopenmpt_la-ModChannel.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-ModChannel.lo `test -f 'soundlib/ModChannel.cpp' || echo '$(srcdir)/'`soundlib/ModChannel.cpp soundlib/libopenmpt_la-modcommand.lo: soundlib/modcommand.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-modcommand.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-modcommand.Tpo -c -o soundlib/libopenmpt_la-modcommand.lo `test -f 'soundlib/modcommand.cpp' || echo '$(srcdir)/'`soundlib/modcommand.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-modcommand.Tpo soundlib/$(DEPDIR)/libopenmpt_la-modcommand.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/modcommand.cpp' object='soundlib/libopenmpt_la-modcommand.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-modcommand.lo `test -f 'soundlib/modcommand.cpp' || echo '$(srcdir)/'`soundlib/modcommand.cpp soundlib/libopenmpt_la-ModInstrument.lo: soundlib/ModInstrument.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-ModInstrument.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-ModInstrument.Tpo -c -o soundlib/libopenmpt_la-ModInstrument.lo `test -f 'soundlib/ModInstrument.cpp' || echo '$(srcdir)/'`soundlib/ModInstrument.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-ModInstrument.Tpo soundlib/$(DEPDIR)/libopenmpt_la-ModInstrument.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/ModInstrument.cpp' object='soundlib/libopenmpt_la-ModInstrument.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-ModInstrument.lo `test -f 'soundlib/ModInstrument.cpp' || echo '$(srcdir)/'`soundlib/ModInstrument.cpp soundlib/libopenmpt_la-ModSample.lo: soundlib/ModSample.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-ModSample.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-ModSample.Tpo -c -o soundlib/libopenmpt_la-ModSample.lo `test -f 'soundlib/ModSample.cpp' || echo '$(srcdir)/'`soundlib/ModSample.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-ModSample.Tpo soundlib/$(DEPDIR)/libopenmpt_la-ModSample.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/ModSample.cpp' object='soundlib/libopenmpt_la-ModSample.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-ModSample.lo `test -f 'soundlib/ModSample.cpp' || echo '$(srcdir)/'`soundlib/ModSample.cpp soundlib/libopenmpt_la-ModSequence.lo: soundlib/ModSequence.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-ModSequence.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-ModSequence.Tpo -c -o soundlib/libopenmpt_la-ModSequence.lo `test -f 'soundlib/ModSequence.cpp' || echo '$(srcdir)/'`soundlib/ModSequence.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-ModSequence.Tpo soundlib/$(DEPDIR)/libopenmpt_la-ModSequence.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/ModSequence.cpp' object='soundlib/libopenmpt_la-ModSequence.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-ModSequence.lo `test -f 'soundlib/ModSequence.cpp' || echo '$(srcdir)/'`soundlib/ModSequence.cpp soundlib/libopenmpt_la-modsmp_ctrl.lo: soundlib/modsmp_ctrl.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-modsmp_ctrl.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-modsmp_ctrl.Tpo -c -o soundlib/libopenmpt_la-modsmp_ctrl.lo `test -f 'soundlib/modsmp_ctrl.cpp' || echo '$(srcdir)/'`soundlib/modsmp_ctrl.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-modsmp_ctrl.Tpo soundlib/$(DEPDIR)/libopenmpt_la-modsmp_ctrl.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/modsmp_ctrl.cpp' object='soundlib/libopenmpt_la-modsmp_ctrl.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-modsmp_ctrl.lo `test -f 'soundlib/modsmp_ctrl.cpp' || echo '$(srcdir)/'`soundlib/modsmp_ctrl.cpp soundlib/libopenmpt_la-mod_specifications.lo: soundlib/mod_specifications.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-mod_specifications.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-mod_specifications.Tpo -c -o soundlib/libopenmpt_la-mod_specifications.lo `test -f 'soundlib/mod_specifications.cpp' || echo '$(srcdir)/'`soundlib/mod_specifications.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-mod_specifications.Tpo soundlib/$(DEPDIR)/libopenmpt_la-mod_specifications.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/mod_specifications.cpp' object='soundlib/libopenmpt_la-mod_specifications.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-mod_specifications.lo `test -f 'soundlib/mod_specifications.cpp' || echo '$(srcdir)/'`soundlib/mod_specifications.cpp soundlib/libopenmpt_la-MPEGFrame.lo: soundlib/MPEGFrame.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-MPEGFrame.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-MPEGFrame.Tpo -c -o soundlib/libopenmpt_la-MPEGFrame.lo `test -f 'soundlib/MPEGFrame.cpp' || echo '$(srcdir)/'`soundlib/MPEGFrame.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-MPEGFrame.Tpo soundlib/$(DEPDIR)/libopenmpt_la-MPEGFrame.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/MPEGFrame.cpp' object='soundlib/libopenmpt_la-MPEGFrame.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-MPEGFrame.lo `test -f 'soundlib/MPEGFrame.cpp' || echo '$(srcdir)/'`soundlib/MPEGFrame.cpp soundlib/libopenmpt_la-OggStream.lo: soundlib/OggStream.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-OggStream.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-OggStream.Tpo -c -o soundlib/libopenmpt_la-OggStream.lo `test -f 'soundlib/OggStream.cpp' || echo '$(srcdir)/'`soundlib/OggStream.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-OggStream.Tpo soundlib/$(DEPDIR)/libopenmpt_la-OggStream.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/OggStream.cpp' object='soundlib/libopenmpt_la-OggStream.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-OggStream.lo `test -f 'soundlib/OggStream.cpp' || echo '$(srcdir)/'`soundlib/OggStream.cpp soundlib/libopenmpt_la-Paula.lo: soundlib/Paula.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Paula.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Paula.Tpo -c -o soundlib/libopenmpt_la-Paula.lo `test -f 'soundlib/Paula.cpp' || echo '$(srcdir)/'`soundlib/Paula.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Paula.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Paula.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Paula.cpp' object='soundlib/libopenmpt_la-Paula.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Paula.lo `test -f 'soundlib/Paula.cpp' || echo '$(srcdir)/'`soundlib/Paula.cpp soundlib/libopenmpt_la-patternContainer.lo: soundlib/patternContainer.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-patternContainer.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-patternContainer.Tpo -c -o soundlib/libopenmpt_la-patternContainer.lo `test -f 'soundlib/patternContainer.cpp' || echo '$(srcdir)/'`soundlib/patternContainer.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-patternContainer.Tpo soundlib/$(DEPDIR)/libopenmpt_la-patternContainer.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/patternContainer.cpp' object='soundlib/libopenmpt_la-patternContainer.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-patternContainer.lo `test -f 'soundlib/patternContainer.cpp' || echo '$(srcdir)/'`soundlib/patternContainer.cpp soundlib/libopenmpt_la-pattern.lo: soundlib/pattern.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-pattern.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-pattern.Tpo -c -o soundlib/libopenmpt_la-pattern.lo `test -f 'soundlib/pattern.cpp' || echo '$(srcdir)/'`soundlib/pattern.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-pattern.Tpo soundlib/$(DEPDIR)/libopenmpt_la-pattern.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/pattern.cpp' object='soundlib/libopenmpt_la-pattern.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-pattern.lo `test -f 'soundlib/pattern.cpp' || echo '$(srcdir)/'`soundlib/pattern.cpp soundlib/libopenmpt_la-RowVisitor.lo: soundlib/RowVisitor.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-RowVisitor.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-RowVisitor.Tpo -c -o soundlib/libopenmpt_la-RowVisitor.lo `test -f 'soundlib/RowVisitor.cpp' || echo '$(srcdir)/'`soundlib/RowVisitor.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-RowVisitor.Tpo soundlib/$(DEPDIR)/libopenmpt_la-RowVisitor.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/RowVisitor.cpp' object='soundlib/libopenmpt_la-RowVisitor.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-RowVisitor.lo `test -f 'soundlib/RowVisitor.cpp' || echo '$(srcdir)/'`soundlib/RowVisitor.cpp soundlib/libopenmpt_la-S3MTools.lo: soundlib/S3MTools.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-S3MTools.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-S3MTools.Tpo -c -o soundlib/libopenmpt_la-S3MTools.lo `test -f 'soundlib/S3MTools.cpp' || echo '$(srcdir)/'`soundlib/S3MTools.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-S3MTools.Tpo soundlib/$(DEPDIR)/libopenmpt_la-S3MTools.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/S3MTools.cpp' object='soundlib/libopenmpt_la-S3MTools.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-S3MTools.lo `test -f 'soundlib/S3MTools.cpp' || echo '$(srcdir)/'`soundlib/S3MTools.cpp soundlib/libopenmpt_la-SampleFormats.lo: soundlib/SampleFormats.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-SampleFormats.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-SampleFormats.Tpo -c -o soundlib/libopenmpt_la-SampleFormats.lo `test -f 'soundlib/SampleFormats.cpp' || echo '$(srcdir)/'`soundlib/SampleFormats.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-SampleFormats.Tpo soundlib/$(DEPDIR)/libopenmpt_la-SampleFormats.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/SampleFormats.cpp' object='soundlib/libopenmpt_la-SampleFormats.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-SampleFormats.lo `test -f 'soundlib/SampleFormats.cpp' || echo '$(srcdir)/'`soundlib/SampleFormats.cpp soundlib/libopenmpt_la-SampleFormatFLAC.lo: soundlib/SampleFormatFLAC.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-SampleFormatFLAC.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-SampleFormatFLAC.Tpo -c -o soundlib/libopenmpt_la-SampleFormatFLAC.lo `test -f 'soundlib/SampleFormatFLAC.cpp' || echo '$(srcdir)/'`soundlib/SampleFormatFLAC.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-SampleFormatFLAC.Tpo soundlib/$(DEPDIR)/libopenmpt_la-SampleFormatFLAC.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/SampleFormatFLAC.cpp' object='soundlib/libopenmpt_la-SampleFormatFLAC.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-SampleFormatFLAC.lo `test -f 'soundlib/SampleFormatFLAC.cpp' || echo '$(srcdir)/'`soundlib/SampleFormatFLAC.cpp soundlib/libopenmpt_la-SampleFormatMediaFoundation.lo: soundlib/SampleFormatMediaFoundation.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-SampleFormatMediaFoundation.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-SampleFormatMediaFoundation.Tpo -c -o soundlib/libopenmpt_la-SampleFormatMediaFoundation.lo `test -f 'soundlib/SampleFormatMediaFoundation.cpp' || echo '$(srcdir)/'`soundlib/SampleFormatMediaFoundation.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-SampleFormatMediaFoundation.Tpo soundlib/$(DEPDIR)/libopenmpt_la-SampleFormatMediaFoundation.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/SampleFormatMediaFoundation.cpp' object='soundlib/libopenmpt_la-SampleFormatMediaFoundation.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-SampleFormatMediaFoundation.lo `test -f 'soundlib/SampleFormatMediaFoundation.cpp' || echo '$(srcdir)/'`soundlib/SampleFormatMediaFoundation.cpp soundlib/libopenmpt_la-SampleFormatMP3.lo: soundlib/SampleFormatMP3.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-SampleFormatMP3.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-SampleFormatMP3.Tpo -c -o soundlib/libopenmpt_la-SampleFormatMP3.lo `test -f 'soundlib/SampleFormatMP3.cpp' || echo '$(srcdir)/'`soundlib/SampleFormatMP3.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-SampleFormatMP3.Tpo soundlib/$(DEPDIR)/libopenmpt_la-SampleFormatMP3.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/SampleFormatMP3.cpp' object='soundlib/libopenmpt_la-SampleFormatMP3.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-SampleFormatMP3.lo `test -f 'soundlib/SampleFormatMP3.cpp' || echo '$(srcdir)/'`soundlib/SampleFormatMP3.cpp soundlib/libopenmpt_la-SampleFormatOpus.lo: soundlib/SampleFormatOpus.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-SampleFormatOpus.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-SampleFormatOpus.Tpo -c -o soundlib/libopenmpt_la-SampleFormatOpus.lo `test -f 'soundlib/SampleFormatOpus.cpp' || echo '$(srcdir)/'`soundlib/SampleFormatOpus.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-SampleFormatOpus.Tpo soundlib/$(DEPDIR)/libopenmpt_la-SampleFormatOpus.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/SampleFormatOpus.cpp' object='soundlib/libopenmpt_la-SampleFormatOpus.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-SampleFormatOpus.lo `test -f 'soundlib/SampleFormatOpus.cpp' || echo '$(srcdir)/'`soundlib/SampleFormatOpus.cpp soundlib/libopenmpt_la-SampleFormatVorbis.lo: soundlib/SampleFormatVorbis.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-SampleFormatVorbis.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-SampleFormatVorbis.Tpo -c -o soundlib/libopenmpt_la-SampleFormatVorbis.lo `test -f 'soundlib/SampleFormatVorbis.cpp' || echo '$(srcdir)/'`soundlib/SampleFormatVorbis.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-SampleFormatVorbis.Tpo soundlib/$(DEPDIR)/libopenmpt_la-SampleFormatVorbis.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/SampleFormatVorbis.cpp' object='soundlib/libopenmpt_la-SampleFormatVorbis.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-SampleFormatVorbis.lo `test -f 'soundlib/SampleFormatVorbis.cpp' || echo '$(srcdir)/'`soundlib/SampleFormatVorbis.cpp soundlib/libopenmpt_la-SampleIO.lo: soundlib/SampleIO.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-SampleIO.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-SampleIO.Tpo -c -o soundlib/libopenmpt_la-SampleIO.lo `test -f 'soundlib/SampleIO.cpp' || echo '$(srcdir)/'`soundlib/SampleIO.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-SampleIO.Tpo soundlib/$(DEPDIR)/libopenmpt_la-SampleIO.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/SampleIO.cpp' object='soundlib/libopenmpt_la-SampleIO.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-SampleIO.lo `test -f 'soundlib/SampleIO.cpp' || echo '$(srcdir)/'`soundlib/SampleIO.cpp soundlib/libopenmpt_la-Sndfile.lo: soundlib/Sndfile.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Sndfile.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Sndfile.Tpo -c -o soundlib/libopenmpt_la-Sndfile.lo `test -f 'soundlib/Sndfile.cpp' || echo '$(srcdir)/'`soundlib/Sndfile.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Sndfile.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Sndfile.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Sndfile.cpp' object='soundlib/libopenmpt_la-Sndfile.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Sndfile.lo `test -f 'soundlib/Sndfile.cpp' || echo '$(srcdir)/'`soundlib/Sndfile.cpp soundlib/libopenmpt_la-Snd_flt.lo: soundlib/Snd_flt.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Snd_flt.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Snd_flt.Tpo -c -o soundlib/libopenmpt_la-Snd_flt.lo `test -f 'soundlib/Snd_flt.cpp' || echo '$(srcdir)/'`soundlib/Snd_flt.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Snd_flt.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Snd_flt.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Snd_flt.cpp' object='soundlib/libopenmpt_la-Snd_flt.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Snd_flt.lo `test -f 'soundlib/Snd_flt.cpp' || echo '$(srcdir)/'`soundlib/Snd_flt.cpp soundlib/libopenmpt_la-Snd_fx.lo: soundlib/Snd_fx.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Snd_fx.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Snd_fx.Tpo -c -o soundlib/libopenmpt_la-Snd_fx.lo `test -f 'soundlib/Snd_fx.cpp' || echo '$(srcdir)/'`soundlib/Snd_fx.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Snd_fx.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Snd_fx.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Snd_fx.cpp' object='soundlib/libopenmpt_la-Snd_fx.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Snd_fx.lo `test -f 'soundlib/Snd_fx.cpp' || echo '$(srcdir)/'`soundlib/Snd_fx.cpp soundlib/libopenmpt_la-Sndmix.lo: soundlib/Sndmix.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Sndmix.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Sndmix.Tpo -c -o soundlib/libopenmpt_la-Sndmix.lo `test -f 'soundlib/Sndmix.cpp' || echo '$(srcdir)/'`soundlib/Sndmix.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Sndmix.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Sndmix.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Sndmix.cpp' object='soundlib/libopenmpt_la-Sndmix.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Sndmix.lo `test -f 'soundlib/Sndmix.cpp' || echo '$(srcdir)/'`soundlib/Sndmix.cpp soundlib/libopenmpt_la-SoundFilePlayConfig.lo: soundlib/SoundFilePlayConfig.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-SoundFilePlayConfig.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-SoundFilePlayConfig.Tpo -c -o soundlib/libopenmpt_la-SoundFilePlayConfig.lo `test -f 'soundlib/SoundFilePlayConfig.cpp' || echo '$(srcdir)/'`soundlib/SoundFilePlayConfig.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-SoundFilePlayConfig.Tpo soundlib/$(DEPDIR)/libopenmpt_la-SoundFilePlayConfig.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/SoundFilePlayConfig.cpp' object='soundlib/libopenmpt_la-SoundFilePlayConfig.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-SoundFilePlayConfig.lo `test -f 'soundlib/SoundFilePlayConfig.cpp' || echo '$(srcdir)/'`soundlib/SoundFilePlayConfig.cpp soundlib/libopenmpt_la-Tables.lo: soundlib/Tables.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Tables.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Tables.Tpo -c -o soundlib/libopenmpt_la-Tables.lo `test -f 'soundlib/Tables.cpp' || echo '$(srcdir)/'`soundlib/Tables.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Tables.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Tables.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Tables.cpp' object='soundlib/libopenmpt_la-Tables.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Tables.lo `test -f 'soundlib/Tables.cpp' || echo '$(srcdir)/'`soundlib/Tables.cpp soundlib/libopenmpt_la-Tagging.lo: soundlib/Tagging.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-Tagging.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-Tagging.Tpo -c -o soundlib/libopenmpt_la-Tagging.lo `test -f 'soundlib/Tagging.cpp' || echo '$(srcdir)/'`soundlib/Tagging.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-Tagging.Tpo soundlib/$(DEPDIR)/libopenmpt_la-Tagging.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Tagging.cpp' object='soundlib/libopenmpt_la-Tagging.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-Tagging.lo `test -f 'soundlib/Tagging.cpp' || echo '$(srcdir)/'`soundlib/Tagging.cpp soundlib/libopenmpt_la-tuningbase.lo: soundlib/tuningbase.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-tuningbase.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-tuningbase.Tpo -c -o soundlib/libopenmpt_la-tuningbase.lo `test -f 'soundlib/tuningbase.cpp' || echo '$(srcdir)/'`soundlib/tuningbase.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-tuningbase.Tpo soundlib/$(DEPDIR)/libopenmpt_la-tuningbase.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/tuningbase.cpp' object='soundlib/libopenmpt_la-tuningbase.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-tuningbase.lo `test -f 'soundlib/tuningbase.cpp' || echo '$(srcdir)/'`soundlib/tuningbase.cpp soundlib/libopenmpt_la-tuningCollection.lo: soundlib/tuningCollection.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-tuningCollection.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-tuningCollection.Tpo -c -o soundlib/libopenmpt_la-tuningCollection.lo `test -f 'soundlib/tuningCollection.cpp' || echo '$(srcdir)/'`soundlib/tuningCollection.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-tuningCollection.Tpo soundlib/$(DEPDIR)/libopenmpt_la-tuningCollection.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/tuningCollection.cpp' object='soundlib/libopenmpt_la-tuningCollection.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-tuningCollection.lo `test -f 'soundlib/tuningCollection.cpp' || echo '$(srcdir)/'`soundlib/tuningCollection.cpp soundlib/libopenmpt_la-tuning.lo: soundlib/tuning.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-tuning.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-tuning.Tpo -c -o soundlib/libopenmpt_la-tuning.lo `test -f 'soundlib/tuning.cpp' || echo '$(srcdir)/'`soundlib/tuning.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-tuning.Tpo soundlib/$(DEPDIR)/libopenmpt_la-tuning.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/tuning.cpp' object='soundlib/libopenmpt_la-tuning.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-tuning.lo `test -f 'soundlib/tuning.cpp' || echo '$(srcdir)/'`soundlib/tuning.cpp soundlib/libopenmpt_la-UMXTools.lo: soundlib/UMXTools.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-UMXTools.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-UMXTools.Tpo -c -o soundlib/libopenmpt_la-UMXTools.lo `test -f 'soundlib/UMXTools.cpp' || echo '$(srcdir)/'`soundlib/UMXTools.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-UMXTools.Tpo soundlib/$(DEPDIR)/libopenmpt_la-UMXTools.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/UMXTools.cpp' object='soundlib/libopenmpt_la-UMXTools.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-UMXTools.lo `test -f 'soundlib/UMXTools.cpp' || echo '$(srcdir)/'`soundlib/UMXTools.cpp soundlib/libopenmpt_la-UpgradeModule.lo: soundlib/UpgradeModule.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-UpgradeModule.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-UpgradeModule.Tpo -c -o soundlib/libopenmpt_la-UpgradeModule.lo `test -f 'soundlib/UpgradeModule.cpp' || echo '$(srcdir)/'`soundlib/UpgradeModule.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-UpgradeModule.Tpo soundlib/$(DEPDIR)/libopenmpt_la-UpgradeModule.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/UpgradeModule.cpp' object='soundlib/libopenmpt_la-UpgradeModule.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-UpgradeModule.lo `test -f 'soundlib/UpgradeModule.cpp' || echo '$(srcdir)/'`soundlib/UpgradeModule.cpp soundlib/libopenmpt_la-WAVTools.lo: soundlib/WAVTools.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-WAVTools.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-WAVTools.Tpo -c -o soundlib/libopenmpt_la-WAVTools.lo `test -f 'soundlib/WAVTools.cpp' || echo '$(srcdir)/'`soundlib/WAVTools.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-WAVTools.Tpo soundlib/$(DEPDIR)/libopenmpt_la-WAVTools.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/WAVTools.cpp' object='soundlib/libopenmpt_la-WAVTools.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-WAVTools.lo `test -f 'soundlib/WAVTools.cpp' || echo '$(srcdir)/'`soundlib/WAVTools.cpp soundlib/libopenmpt_la-WindowedFIR.lo: soundlib/WindowedFIR.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-WindowedFIR.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-WindowedFIR.Tpo -c -o soundlib/libopenmpt_la-WindowedFIR.lo `test -f 'soundlib/WindowedFIR.cpp' || echo '$(srcdir)/'`soundlib/WindowedFIR.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-WindowedFIR.Tpo soundlib/$(DEPDIR)/libopenmpt_la-WindowedFIR.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/WindowedFIR.cpp' object='soundlib/libopenmpt_la-WindowedFIR.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-WindowedFIR.lo `test -f 'soundlib/WindowedFIR.cpp' || echo '$(srcdir)/'`soundlib/WindowedFIR.cpp soundlib/libopenmpt_la-XMTools.lo: soundlib/XMTools.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpt_la-XMTools.lo -MD -MP -MF soundlib/$(DEPDIR)/libopenmpt_la-XMTools.Tpo -c -o soundlib/libopenmpt_la-XMTools.lo `test -f 'soundlib/XMTools.cpp' || echo '$(srcdir)/'`soundlib/XMTools.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpt_la-XMTools.Tpo soundlib/$(DEPDIR)/libopenmpt_la-XMTools.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/XMTools.cpp' object='soundlib/libopenmpt_la-XMTools.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpt_la-XMTools.lo `test -f 'soundlib/XMTools.cpp' || echo '$(srcdir)/'`soundlib/XMTools.cpp soundlib/plugins/dmo/libopenmpt_la-DMOPlugin.lo: soundlib/plugins/dmo/DMOPlugin.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/dmo/libopenmpt_la-DMOPlugin.lo -MD -MP -MF soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-DMOPlugin.Tpo -c -o soundlib/plugins/dmo/libopenmpt_la-DMOPlugin.lo `test -f 'soundlib/plugins/dmo/DMOPlugin.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/DMOPlugin.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-DMOPlugin.Tpo soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-DMOPlugin.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/dmo/DMOPlugin.cpp' object='soundlib/plugins/dmo/libopenmpt_la-DMOPlugin.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/dmo/libopenmpt_la-DMOPlugin.lo `test -f 'soundlib/plugins/dmo/DMOPlugin.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/DMOPlugin.cpp soundlib/plugins/dmo/libopenmpt_la-Chorus.lo: soundlib/plugins/dmo/Chorus.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/dmo/libopenmpt_la-Chorus.lo -MD -MP -MF soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-Chorus.Tpo -c -o soundlib/plugins/dmo/libopenmpt_la-Chorus.lo `test -f 'soundlib/plugins/dmo/Chorus.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/Chorus.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-Chorus.Tpo soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-Chorus.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/dmo/Chorus.cpp' object='soundlib/plugins/dmo/libopenmpt_la-Chorus.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/dmo/libopenmpt_la-Chorus.lo `test -f 'soundlib/plugins/dmo/Chorus.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/Chorus.cpp soundlib/plugins/dmo/libopenmpt_la-Compressor.lo: soundlib/plugins/dmo/Compressor.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/dmo/libopenmpt_la-Compressor.lo -MD -MP -MF soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-Compressor.Tpo -c -o soundlib/plugins/dmo/libopenmpt_la-Compressor.lo `test -f 'soundlib/plugins/dmo/Compressor.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/Compressor.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-Compressor.Tpo soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-Compressor.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/dmo/Compressor.cpp' object='soundlib/plugins/dmo/libopenmpt_la-Compressor.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/dmo/libopenmpt_la-Compressor.lo `test -f 'soundlib/plugins/dmo/Compressor.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/Compressor.cpp soundlib/plugins/dmo/libopenmpt_la-Distortion.lo: soundlib/plugins/dmo/Distortion.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/dmo/libopenmpt_la-Distortion.lo -MD -MP -MF soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-Distortion.Tpo -c -o soundlib/plugins/dmo/libopenmpt_la-Distortion.lo `test -f 'soundlib/plugins/dmo/Distortion.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/Distortion.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-Distortion.Tpo soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-Distortion.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/dmo/Distortion.cpp' object='soundlib/plugins/dmo/libopenmpt_la-Distortion.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/dmo/libopenmpt_la-Distortion.lo `test -f 'soundlib/plugins/dmo/Distortion.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/Distortion.cpp soundlib/plugins/dmo/libopenmpt_la-Echo.lo: soundlib/plugins/dmo/Echo.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/dmo/libopenmpt_la-Echo.lo -MD -MP -MF soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-Echo.Tpo -c -o soundlib/plugins/dmo/libopenmpt_la-Echo.lo `test -f 'soundlib/plugins/dmo/Echo.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/Echo.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-Echo.Tpo soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-Echo.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/dmo/Echo.cpp' object='soundlib/plugins/dmo/libopenmpt_la-Echo.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/dmo/libopenmpt_la-Echo.lo `test -f 'soundlib/plugins/dmo/Echo.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/Echo.cpp soundlib/plugins/dmo/libopenmpt_la-Flanger.lo: soundlib/plugins/dmo/Flanger.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/dmo/libopenmpt_la-Flanger.lo -MD -MP -MF soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-Flanger.Tpo -c -o soundlib/plugins/dmo/libopenmpt_la-Flanger.lo `test -f 'soundlib/plugins/dmo/Flanger.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/Flanger.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-Flanger.Tpo soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-Flanger.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/dmo/Flanger.cpp' object='soundlib/plugins/dmo/libopenmpt_la-Flanger.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/dmo/libopenmpt_la-Flanger.lo `test -f 'soundlib/plugins/dmo/Flanger.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/Flanger.cpp soundlib/plugins/dmo/libopenmpt_la-Gargle.lo: soundlib/plugins/dmo/Gargle.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/dmo/libopenmpt_la-Gargle.lo -MD -MP -MF soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-Gargle.Tpo -c -o soundlib/plugins/dmo/libopenmpt_la-Gargle.lo `test -f 'soundlib/plugins/dmo/Gargle.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/Gargle.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-Gargle.Tpo soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-Gargle.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/dmo/Gargle.cpp' object='soundlib/plugins/dmo/libopenmpt_la-Gargle.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/dmo/libopenmpt_la-Gargle.lo `test -f 'soundlib/plugins/dmo/Gargle.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/Gargle.cpp soundlib/plugins/dmo/libopenmpt_la-I3DL2Reverb.lo: soundlib/plugins/dmo/I3DL2Reverb.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/dmo/libopenmpt_la-I3DL2Reverb.lo -MD -MP -MF soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-I3DL2Reverb.Tpo -c -o soundlib/plugins/dmo/libopenmpt_la-I3DL2Reverb.lo `test -f 'soundlib/plugins/dmo/I3DL2Reverb.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/I3DL2Reverb.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-I3DL2Reverb.Tpo soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-I3DL2Reverb.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/dmo/I3DL2Reverb.cpp' object='soundlib/plugins/dmo/libopenmpt_la-I3DL2Reverb.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/dmo/libopenmpt_la-I3DL2Reverb.lo `test -f 'soundlib/plugins/dmo/I3DL2Reverb.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/I3DL2Reverb.cpp soundlib/plugins/dmo/libopenmpt_la-ParamEq.lo: soundlib/plugins/dmo/ParamEq.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/dmo/libopenmpt_la-ParamEq.lo -MD -MP -MF soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-ParamEq.Tpo -c -o soundlib/plugins/dmo/libopenmpt_la-ParamEq.lo `test -f 'soundlib/plugins/dmo/ParamEq.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/ParamEq.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-ParamEq.Tpo soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-ParamEq.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/dmo/ParamEq.cpp' object='soundlib/plugins/dmo/libopenmpt_la-ParamEq.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/dmo/libopenmpt_la-ParamEq.lo `test -f 'soundlib/plugins/dmo/ParamEq.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/ParamEq.cpp soundlib/plugins/dmo/libopenmpt_la-WavesReverb.lo: soundlib/plugins/dmo/WavesReverb.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/dmo/libopenmpt_la-WavesReverb.lo -MD -MP -MF soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-WavesReverb.Tpo -c -o soundlib/plugins/dmo/libopenmpt_la-WavesReverb.lo `test -f 'soundlib/plugins/dmo/WavesReverb.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/WavesReverb.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-WavesReverb.Tpo soundlib/plugins/dmo/$(DEPDIR)/libopenmpt_la-WavesReverb.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/dmo/WavesReverb.cpp' object='soundlib/plugins/dmo/libopenmpt_la-WavesReverb.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/dmo/libopenmpt_la-WavesReverb.lo `test -f 'soundlib/plugins/dmo/WavesReverb.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/WavesReverb.cpp soundlib/plugins/libopenmpt_la-DigiBoosterEcho.lo: soundlib/plugins/DigiBoosterEcho.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/libopenmpt_la-DigiBoosterEcho.lo -MD -MP -MF soundlib/plugins/$(DEPDIR)/libopenmpt_la-DigiBoosterEcho.Tpo -c -o soundlib/plugins/libopenmpt_la-DigiBoosterEcho.lo `test -f 'soundlib/plugins/DigiBoosterEcho.cpp' || echo '$(srcdir)/'`soundlib/plugins/DigiBoosterEcho.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/$(DEPDIR)/libopenmpt_la-DigiBoosterEcho.Tpo soundlib/plugins/$(DEPDIR)/libopenmpt_la-DigiBoosterEcho.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/DigiBoosterEcho.cpp' object='soundlib/plugins/libopenmpt_la-DigiBoosterEcho.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/libopenmpt_la-DigiBoosterEcho.lo `test -f 'soundlib/plugins/DigiBoosterEcho.cpp' || echo '$(srcdir)/'`soundlib/plugins/DigiBoosterEcho.cpp soundlib/plugins/libopenmpt_la-LFOPlugin.lo: soundlib/plugins/LFOPlugin.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/libopenmpt_la-LFOPlugin.lo -MD -MP -MF soundlib/plugins/$(DEPDIR)/libopenmpt_la-LFOPlugin.Tpo -c -o soundlib/plugins/libopenmpt_la-LFOPlugin.lo `test -f 'soundlib/plugins/LFOPlugin.cpp' || echo '$(srcdir)/'`soundlib/plugins/LFOPlugin.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/$(DEPDIR)/libopenmpt_la-LFOPlugin.Tpo soundlib/plugins/$(DEPDIR)/libopenmpt_la-LFOPlugin.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/LFOPlugin.cpp' object='soundlib/plugins/libopenmpt_la-LFOPlugin.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/libopenmpt_la-LFOPlugin.lo `test -f 'soundlib/plugins/LFOPlugin.cpp' || echo '$(srcdir)/'`soundlib/plugins/LFOPlugin.cpp soundlib/plugins/libopenmpt_la-PluginManager.lo: soundlib/plugins/PluginManager.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/libopenmpt_la-PluginManager.lo -MD -MP -MF soundlib/plugins/$(DEPDIR)/libopenmpt_la-PluginManager.Tpo -c -o soundlib/plugins/libopenmpt_la-PluginManager.lo `test -f 'soundlib/plugins/PluginManager.cpp' || echo '$(srcdir)/'`soundlib/plugins/PluginManager.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/$(DEPDIR)/libopenmpt_la-PluginManager.Tpo soundlib/plugins/$(DEPDIR)/libopenmpt_la-PluginManager.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/PluginManager.cpp' object='soundlib/plugins/libopenmpt_la-PluginManager.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/libopenmpt_la-PluginManager.lo `test -f 'soundlib/plugins/PluginManager.cpp' || echo '$(srcdir)/'`soundlib/plugins/PluginManager.cpp soundlib/plugins/libopenmpt_la-PlugInterface.lo: soundlib/plugins/PlugInterface.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/libopenmpt_la-PlugInterface.lo -MD -MP -MF soundlib/plugins/$(DEPDIR)/libopenmpt_la-PlugInterface.Tpo -c -o soundlib/plugins/libopenmpt_la-PlugInterface.lo `test -f 'soundlib/plugins/PlugInterface.cpp' || echo '$(srcdir)/'`soundlib/plugins/PlugInterface.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/$(DEPDIR)/libopenmpt_la-PlugInterface.Tpo soundlib/plugins/$(DEPDIR)/libopenmpt_la-PlugInterface.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/PlugInterface.cpp' object='soundlib/plugins/libopenmpt_la-PlugInterface.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/libopenmpt_la-PlugInterface.lo `test -f 'soundlib/plugins/PlugInterface.cpp' || echo '$(srcdir)/'`soundlib/plugins/PlugInterface.cpp sounddsp/libopenmpt_la-AGC.lo: sounddsp/AGC.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT sounddsp/libopenmpt_la-AGC.lo -MD -MP -MF sounddsp/$(DEPDIR)/libopenmpt_la-AGC.Tpo -c -o sounddsp/libopenmpt_la-AGC.lo `test -f 'sounddsp/AGC.cpp' || echo '$(srcdir)/'`sounddsp/AGC.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) sounddsp/$(DEPDIR)/libopenmpt_la-AGC.Tpo sounddsp/$(DEPDIR)/libopenmpt_la-AGC.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='sounddsp/AGC.cpp' object='sounddsp/libopenmpt_la-AGC.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o sounddsp/libopenmpt_la-AGC.lo `test -f 'sounddsp/AGC.cpp' || echo '$(srcdir)/'`sounddsp/AGC.cpp sounddsp/libopenmpt_la-DSP.lo: sounddsp/DSP.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT sounddsp/libopenmpt_la-DSP.lo -MD -MP -MF sounddsp/$(DEPDIR)/libopenmpt_la-DSP.Tpo -c -o sounddsp/libopenmpt_la-DSP.lo `test -f 'sounddsp/DSP.cpp' || echo '$(srcdir)/'`sounddsp/DSP.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) sounddsp/$(DEPDIR)/libopenmpt_la-DSP.Tpo sounddsp/$(DEPDIR)/libopenmpt_la-DSP.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='sounddsp/DSP.cpp' object='sounddsp/libopenmpt_la-DSP.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o sounddsp/libopenmpt_la-DSP.lo `test -f 'sounddsp/DSP.cpp' || echo '$(srcdir)/'`sounddsp/DSP.cpp sounddsp/libopenmpt_la-EQ.lo: sounddsp/EQ.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT sounddsp/libopenmpt_la-EQ.lo -MD -MP -MF sounddsp/$(DEPDIR)/libopenmpt_la-EQ.Tpo -c -o sounddsp/libopenmpt_la-EQ.lo `test -f 'sounddsp/EQ.cpp' || echo '$(srcdir)/'`sounddsp/EQ.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) sounddsp/$(DEPDIR)/libopenmpt_la-EQ.Tpo sounddsp/$(DEPDIR)/libopenmpt_la-EQ.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='sounddsp/EQ.cpp' object='sounddsp/libopenmpt_la-EQ.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o sounddsp/libopenmpt_la-EQ.lo `test -f 'sounddsp/EQ.cpp' || echo '$(srcdir)/'`sounddsp/EQ.cpp sounddsp/libopenmpt_la-Reverb.lo: sounddsp/Reverb.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT sounddsp/libopenmpt_la-Reverb.lo -MD -MP -MF sounddsp/$(DEPDIR)/libopenmpt_la-Reverb.Tpo -c -o sounddsp/libopenmpt_la-Reverb.lo `test -f 'sounddsp/Reverb.cpp' || echo '$(srcdir)/'`sounddsp/Reverb.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) sounddsp/$(DEPDIR)/libopenmpt_la-Reverb.Tpo sounddsp/$(DEPDIR)/libopenmpt_la-Reverb.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='sounddsp/Reverb.cpp' object='sounddsp/libopenmpt_la-Reverb.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o sounddsp/libopenmpt_la-Reverb.lo `test -f 'sounddsp/Reverb.cpp' || echo '$(srcdir)/'`sounddsp/Reverb.cpp libopenmpt/libopenmpt_la-libopenmpt_c.lo: libopenmpt/libopenmpt_c.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT libopenmpt/libopenmpt_la-libopenmpt_c.lo -MD -MP -MF libopenmpt/$(DEPDIR)/libopenmpt_la-libopenmpt_c.Tpo -c -o libopenmpt/libopenmpt_la-libopenmpt_c.lo `test -f 'libopenmpt/libopenmpt_c.cpp' || echo '$(srcdir)/'`libopenmpt/libopenmpt_c.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) libopenmpt/$(DEPDIR)/libopenmpt_la-libopenmpt_c.Tpo libopenmpt/$(DEPDIR)/libopenmpt_la-libopenmpt_c.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='libopenmpt/libopenmpt_c.cpp' object='libopenmpt/libopenmpt_la-libopenmpt_c.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o libopenmpt/libopenmpt_la-libopenmpt_c.lo `test -f 'libopenmpt/libopenmpt_c.cpp' || echo '$(srcdir)/'`libopenmpt/libopenmpt_c.cpp libopenmpt/libopenmpt_la-libopenmpt_cxx.lo: libopenmpt/libopenmpt_cxx.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT libopenmpt/libopenmpt_la-libopenmpt_cxx.lo -MD -MP -MF libopenmpt/$(DEPDIR)/libopenmpt_la-libopenmpt_cxx.Tpo -c -o libopenmpt/libopenmpt_la-libopenmpt_cxx.lo `test -f 'libopenmpt/libopenmpt_cxx.cpp' || echo '$(srcdir)/'`libopenmpt/libopenmpt_cxx.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) libopenmpt/$(DEPDIR)/libopenmpt_la-libopenmpt_cxx.Tpo libopenmpt/$(DEPDIR)/libopenmpt_la-libopenmpt_cxx.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='libopenmpt/libopenmpt_cxx.cpp' object='libopenmpt/libopenmpt_la-libopenmpt_cxx.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o libopenmpt/libopenmpt_la-libopenmpt_cxx.lo `test -f 'libopenmpt/libopenmpt_cxx.cpp' || echo '$(srcdir)/'`libopenmpt/libopenmpt_cxx.cpp libopenmpt/libopenmpt_la-libopenmpt_ext_impl.lo: libopenmpt/libopenmpt_ext_impl.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT libopenmpt/libopenmpt_la-libopenmpt_ext_impl.lo -MD -MP -MF libopenmpt/$(DEPDIR)/libopenmpt_la-libopenmpt_ext_impl.Tpo -c -o libopenmpt/libopenmpt_la-libopenmpt_ext_impl.lo `test -f 'libopenmpt/libopenmpt_ext_impl.cpp' || echo '$(srcdir)/'`libopenmpt/libopenmpt_ext_impl.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) libopenmpt/$(DEPDIR)/libopenmpt_la-libopenmpt_ext_impl.Tpo libopenmpt/$(DEPDIR)/libopenmpt_la-libopenmpt_ext_impl.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='libopenmpt/libopenmpt_ext_impl.cpp' object='libopenmpt/libopenmpt_la-libopenmpt_ext_impl.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o libopenmpt/libopenmpt_la-libopenmpt_ext_impl.lo `test -f 'libopenmpt/libopenmpt_ext_impl.cpp' || echo '$(srcdir)/'`libopenmpt/libopenmpt_ext_impl.cpp libopenmpt/libopenmpt_la-libopenmpt_impl.lo: libopenmpt/libopenmpt_impl.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -MT libopenmpt/libopenmpt_la-libopenmpt_impl.lo -MD -MP -MF libopenmpt/$(DEPDIR)/libopenmpt_la-libopenmpt_impl.Tpo -c -o libopenmpt/libopenmpt_la-libopenmpt_impl.lo `test -f 'libopenmpt/libopenmpt_impl.cpp' || echo '$(srcdir)/'`libopenmpt/libopenmpt_impl.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) libopenmpt/$(DEPDIR)/libopenmpt_la-libopenmpt_impl.Tpo libopenmpt/$(DEPDIR)/libopenmpt_la-libopenmpt_impl.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='libopenmpt/libopenmpt_impl.cpp' object='libopenmpt/libopenmpt_la-libopenmpt_impl.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_la_CXXFLAGS) $(CXXFLAGS) -c -o libopenmpt/libopenmpt_la-libopenmpt_impl.lo `test -f 'libopenmpt/libopenmpt_impl.cpp' || echo '$(srcdir)/'`libopenmpt/libopenmpt_impl.cpp libopenmpt/libopenmpt_modplug_la-libopenmpt_modplug_cpp.lo: libopenmpt/libopenmpt_modplug_cpp.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_modplug_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_modplug_la_CXXFLAGS) $(CXXFLAGS) -MT libopenmpt/libopenmpt_modplug_la-libopenmpt_modplug_cpp.lo -MD -MP -MF libopenmpt/$(DEPDIR)/libopenmpt_modplug_la-libopenmpt_modplug_cpp.Tpo -c -o libopenmpt/libopenmpt_modplug_la-libopenmpt_modplug_cpp.lo `test -f 'libopenmpt/libopenmpt_modplug_cpp.cpp' || echo '$(srcdir)/'`libopenmpt/libopenmpt_modplug_cpp.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) libopenmpt/$(DEPDIR)/libopenmpt_modplug_la-libopenmpt_modplug_cpp.Tpo libopenmpt/$(DEPDIR)/libopenmpt_modplug_la-libopenmpt_modplug_cpp.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='libopenmpt/libopenmpt_modplug_cpp.cpp' object='libopenmpt/libopenmpt_modplug_la-libopenmpt_modplug_cpp.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_modplug_la_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_modplug_la_CXXFLAGS) $(CXXFLAGS) -c -o libopenmpt/libopenmpt_modplug_la-libopenmpt_modplug_cpp.lo `test -f 'libopenmpt/libopenmpt_modplug_cpp.cpp' || echo '$(srcdir)/'`libopenmpt/libopenmpt_modplug_cpp.cpp openmpt123/bin_openmpt123-openmpt123.o: openmpt123/openmpt123.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bin_openmpt123_CPPFLAGS) $(CPPFLAGS) $(bin_openmpt123_CXXFLAGS) $(CXXFLAGS) -MT openmpt123/bin_openmpt123-openmpt123.o -MD -MP -MF openmpt123/$(DEPDIR)/bin_openmpt123-openmpt123.Tpo -c -o openmpt123/bin_openmpt123-openmpt123.o `test -f 'openmpt123/openmpt123.cpp' || echo '$(srcdir)/'`openmpt123/openmpt123.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) openmpt123/$(DEPDIR)/bin_openmpt123-openmpt123.Tpo openmpt123/$(DEPDIR)/bin_openmpt123-openmpt123.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='openmpt123/openmpt123.cpp' object='openmpt123/bin_openmpt123-openmpt123.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bin_openmpt123_CPPFLAGS) $(CPPFLAGS) $(bin_openmpt123_CXXFLAGS) $(CXXFLAGS) -c -o openmpt123/bin_openmpt123-openmpt123.o `test -f 'openmpt123/openmpt123.cpp' || echo '$(srcdir)/'`openmpt123/openmpt123.cpp openmpt123/bin_openmpt123-openmpt123.obj: openmpt123/openmpt123.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bin_openmpt123_CPPFLAGS) $(CPPFLAGS) $(bin_openmpt123_CXXFLAGS) $(CXXFLAGS) -MT openmpt123/bin_openmpt123-openmpt123.obj -MD -MP -MF openmpt123/$(DEPDIR)/bin_openmpt123-openmpt123.Tpo -c -o openmpt123/bin_openmpt123-openmpt123.obj `if test -f 'openmpt123/openmpt123.cpp'; then $(CYGPATH_W) 'openmpt123/openmpt123.cpp'; else $(CYGPATH_W) '$(srcdir)/openmpt123/openmpt123.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) openmpt123/$(DEPDIR)/bin_openmpt123-openmpt123.Tpo openmpt123/$(DEPDIR)/bin_openmpt123-openmpt123.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='openmpt123/openmpt123.cpp' object='openmpt123/bin_openmpt123-openmpt123.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bin_openmpt123_CPPFLAGS) $(CPPFLAGS) $(bin_openmpt123_CXXFLAGS) $(CXXFLAGS) -c -o openmpt123/bin_openmpt123-openmpt123.obj `if test -f 'openmpt123/openmpt123.cpp'; then $(CYGPATH_W) 'openmpt123/openmpt123.cpp'; else $(CYGPATH_W) '$(srcdir)/openmpt123/openmpt123.cpp'; fi` examples/libopenmpt_example_cxx-libopenmpt_example_cxx.o: examples/libopenmpt_example_cxx.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_example_cxx_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_example_cxx_CXXFLAGS) $(CXXFLAGS) -MT examples/libopenmpt_example_cxx-libopenmpt_example_cxx.o -MD -MP -MF examples/$(DEPDIR)/libopenmpt_example_cxx-libopenmpt_example_cxx.Tpo -c -o examples/libopenmpt_example_cxx-libopenmpt_example_cxx.o `test -f 'examples/libopenmpt_example_cxx.cpp' || echo '$(srcdir)/'`examples/libopenmpt_example_cxx.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) examples/$(DEPDIR)/libopenmpt_example_cxx-libopenmpt_example_cxx.Tpo examples/$(DEPDIR)/libopenmpt_example_cxx-libopenmpt_example_cxx.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='examples/libopenmpt_example_cxx.cpp' object='examples/libopenmpt_example_cxx-libopenmpt_example_cxx.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_example_cxx_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_example_cxx_CXXFLAGS) $(CXXFLAGS) -c -o examples/libopenmpt_example_cxx-libopenmpt_example_cxx.o `test -f 'examples/libopenmpt_example_cxx.cpp' || echo '$(srcdir)/'`examples/libopenmpt_example_cxx.cpp examples/libopenmpt_example_cxx-libopenmpt_example_cxx.obj: examples/libopenmpt_example_cxx.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_example_cxx_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_example_cxx_CXXFLAGS) $(CXXFLAGS) -MT examples/libopenmpt_example_cxx-libopenmpt_example_cxx.obj -MD -MP -MF examples/$(DEPDIR)/libopenmpt_example_cxx-libopenmpt_example_cxx.Tpo -c -o examples/libopenmpt_example_cxx-libopenmpt_example_cxx.obj `if test -f 'examples/libopenmpt_example_cxx.cpp'; then $(CYGPATH_W) 'examples/libopenmpt_example_cxx.cpp'; else $(CYGPATH_W) '$(srcdir)/examples/libopenmpt_example_cxx.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) examples/$(DEPDIR)/libopenmpt_example_cxx-libopenmpt_example_cxx.Tpo examples/$(DEPDIR)/libopenmpt_example_cxx-libopenmpt_example_cxx.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='examples/libopenmpt_example_cxx.cpp' object='examples/libopenmpt_example_cxx-libopenmpt_example_cxx.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpt_example_cxx_CPPFLAGS) $(CPPFLAGS) $(libopenmpt_example_cxx_CXXFLAGS) $(CXXFLAGS) -c -o examples/libopenmpt_example_cxx-libopenmpt_example_cxx.obj `if test -f 'examples/libopenmpt_example_cxx.cpp'; then $(CYGPATH_W) 'examples/libopenmpt_example_cxx.cpp'; else $(CYGPATH_W) '$(srcdir)/examples/libopenmpt_example_cxx.cpp'; fi` libopenmpt/libopenmpttest-libopenmpt_test.o: libopenmpt/libopenmpt_test.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT libopenmpt/libopenmpttest-libopenmpt_test.o -MD -MP -MF libopenmpt/$(DEPDIR)/libopenmpttest-libopenmpt_test.Tpo -c -o libopenmpt/libopenmpttest-libopenmpt_test.o `test -f 'libopenmpt/libopenmpt_test.cpp' || echo '$(srcdir)/'`libopenmpt/libopenmpt_test.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) libopenmpt/$(DEPDIR)/libopenmpttest-libopenmpt_test.Tpo libopenmpt/$(DEPDIR)/libopenmpttest-libopenmpt_test.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='libopenmpt/libopenmpt_test.cpp' object='libopenmpt/libopenmpttest-libopenmpt_test.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o libopenmpt/libopenmpttest-libopenmpt_test.o `test -f 'libopenmpt/libopenmpt_test.cpp' || echo '$(srcdir)/'`libopenmpt/libopenmpt_test.cpp libopenmpt/libopenmpttest-libopenmpt_test.obj: libopenmpt/libopenmpt_test.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT libopenmpt/libopenmpttest-libopenmpt_test.obj -MD -MP -MF libopenmpt/$(DEPDIR)/libopenmpttest-libopenmpt_test.Tpo -c -o libopenmpt/libopenmpttest-libopenmpt_test.obj `if test -f 'libopenmpt/libopenmpt_test.cpp'; then $(CYGPATH_W) 'libopenmpt/libopenmpt_test.cpp'; else $(CYGPATH_W) '$(srcdir)/libopenmpt/libopenmpt_test.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) libopenmpt/$(DEPDIR)/libopenmpttest-libopenmpt_test.Tpo libopenmpt/$(DEPDIR)/libopenmpttest-libopenmpt_test.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='libopenmpt/libopenmpt_test.cpp' object='libopenmpt/libopenmpttest-libopenmpt_test.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o libopenmpt/libopenmpttest-libopenmpt_test.obj `if test -f 'libopenmpt/libopenmpt_test.cpp'; then $(CYGPATH_W) 'libopenmpt/libopenmpt_test.cpp'; else $(CYGPATH_W) '$(srcdir)/libopenmpt/libopenmpt_test.cpp'; fi` test/libopenmpttest-test.o: test/test.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT test/libopenmpttest-test.o -MD -MP -MF test/$(DEPDIR)/libopenmpttest-test.Tpo -c -o test/libopenmpttest-test.o `test -f 'test/test.cpp' || echo '$(srcdir)/'`test/test.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) test/$(DEPDIR)/libopenmpttest-test.Tpo test/$(DEPDIR)/libopenmpttest-test.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='test/test.cpp' object='test/libopenmpttest-test.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o test/libopenmpttest-test.o `test -f 'test/test.cpp' || echo '$(srcdir)/'`test/test.cpp test/libopenmpttest-test.obj: test/test.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT test/libopenmpttest-test.obj -MD -MP -MF test/$(DEPDIR)/libopenmpttest-test.Tpo -c -o test/libopenmpttest-test.obj `if test -f 'test/test.cpp'; then $(CYGPATH_W) 'test/test.cpp'; else $(CYGPATH_W) '$(srcdir)/test/test.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) test/$(DEPDIR)/libopenmpttest-test.Tpo test/$(DEPDIR)/libopenmpttest-test.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='test/test.cpp' object='test/libopenmpttest-test.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o test/libopenmpttest-test.obj `if test -f 'test/test.cpp'; then $(CYGPATH_W) 'test/test.cpp'; else $(CYGPATH_W) '$(srcdir)/test/test.cpp'; fi` test/libopenmpttest-TestToolsLib.o: test/TestToolsLib.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT test/libopenmpttest-TestToolsLib.o -MD -MP -MF test/$(DEPDIR)/libopenmpttest-TestToolsLib.Tpo -c -o test/libopenmpttest-TestToolsLib.o `test -f 'test/TestToolsLib.cpp' || echo '$(srcdir)/'`test/TestToolsLib.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) test/$(DEPDIR)/libopenmpttest-TestToolsLib.Tpo test/$(DEPDIR)/libopenmpttest-TestToolsLib.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='test/TestToolsLib.cpp' object='test/libopenmpttest-TestToolsLib.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o test/libopenmpttest-TestToolsLib.o `test -f 'test/TestToolsLib.cpp' || echo '$(srcdir)/'`test/TestToolsLib.cpp test/libopenmpttest-TestToolsLib.obj: test/TestToolsLib.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT test/libopenmpttest-TestToolsLib.obj -MD -MP -MF test/$(DEPDIR)/libopenmpttest-TestToolsLib.Tpo -c -o test/libopenmpttest-TestToolsLib.obj `if test -f 'test/TestToolsLib.cpp'; then $(CYGPATH_W) 'test/TestToolsLib.cpp'; else $(CYGPATH_W) '$(srcdir)/test/TestToolsLib.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) test/$(DEPDIR)/libopenmpttest-TestToolsLib.Tpo test/$(DEPDIR)/libopenmpttest-TestToolsLib.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='test/TestToolsLib.cpp' object='test/libopenmpttest-TestToolsLib.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o test/libopenmpttest-TestToolsLib.obj `if test -f 'test/TestToolsLib.cpp'; then $(CYGPATH_W) 'test/TestToolsLib.cpp'; else $(CYGPATH_W) '$(srcdir)/test/TestToolsLib.cpp'; fi` common/libopenmpttest-ComponentManager.o: common/ComponentManager.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-ComponentManager.o -MD -MP -MF common/$(DEPDIR)/libopenmpttest-ComponentManager.Tpo -c -o common/libopenmpttest-ComponentManager.o `test -f 'common/ComponentManager.cpp' || echo '$(srcdir)/'`common/ComponentManager.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-ComponentManager.Tpo common/$(DEPDIR)/libopenmpttest-ComponentManager.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/ComponentManager.cpp' object='common/libopenmpttest-ComponentManager.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-ComponentManager.o `test -f 'common/ComponentManager.cpp' || echo '$(srcdir)/'`common/ComponentManager.cpp common/libopenmpttest-ComponentManager.obj: common/ComponentManager.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-ComponentManager.obj -MD -MP -MF common/$(DEPDIR)/libopenmpttest-ComponentManager.Tpo -c -o common/libopenmpttest-ComponentManager.obj `if test -f 'common/ComponentManager.cpp'; then $(CYGPATH_W) 'common/ComponentManager.cpp'; else $(CYGPATH_W) '$(srcdir)/common/ComponentManager.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-ComponentManager.Tpo common/$(DEPDIR)/libopenmpttest-ComponentManager.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/ComponentManager.cpp' object='common/libopenmpttest-ComponentManager.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-ComponentManager.obj `if test -f 'common/ComponentManager.cpp'; then $(CYGPATH_W) 'common/ComponentManager.cpp'; else $(CYGPATH_W) '$(srcdir)/common/ComponentManager.cpp'; fi` common/libopenmpttest-FileReader.o: common/FileReader.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-FileReader.o -MD -MP -MF common/$(DEPDIR)/libopenmpttest-FileReader.Tpo -c -o common/libopenmpttest-FileReader.o `test -f 'common/FileReader.cpp' || echo '$(srcdir)/'`common/FileReader.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-FileReader.Tpo common/$(DEPDIR)/libopenmpttest-FileReader.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/FileReader.cpp' object='common/libopenmpttest-FileReader.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-FileReader.o `test -f 'common/FileReader.cpp' || echo '$(srcdir)/'`common/FileReader.cpp common/libopenmpttest-FileReader.obj: common/FileReader.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-FileReader.obj -MD -MP -MF common/$(DEPDIR)/libopenmpttest-FileReader.Tpo -c -o common/libopenmpttest-FileReader.obj `if test -f 'common/FileReader.cpp'; then $(CYGPATH_W) 'common/FileReader.cpp'; else $(CYGPATH_W) '$(srcdir)/common/FileReader.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-FileReader.Tpo common/$(DEPDIR)/libopenmpttest-FileReader.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/FileReader.cpp' object='common/libopenmpttest-FileReader.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-FileReader.obj `if test -f 'common/FileReader.cpp'; then $(CYGPATH_W) 'common/FileReader.cpp'; else $(CYGPATH_W) '$(srcdir)/common/FileReader.cpp'; fi` common/libopenmpttest-Logging.o: common/Logging.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-Logging.o -MD -MP -MF common/$(DEPDIR)/libopenmpttest-Logging.Tpo -c -o common/libopenmpttest-Logging.o `test -f 'common/Logging.cpp' || echo '$(srcdir)/'`common/Logging.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-Logging.Tpo common/$(DEPDIR)/libopenmpttest-Logging.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/Logging.cpp' object='common/libopenmpttest-Logging.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-Logging.o `test -f 'common/Logging.cpp' || echo '$(srcdir)/'`common/Logging.cpp common/libopenmpttest-Logging.obj: common/Logging.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-Logging.obj -MD -MP -MF common/$(DEPDIR)/libopenmpttest-Logging.Tpo -c -o common/libopenmpttest-Logging.obj `if test -f 'common/Logging.cpp'; then $(CYGPATH_W) 'common/Logging.cpp'; else $(CYGPATH_W) '$(srcdir)/common/Logging.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-Logging.Tpo common/$(DEPDIR)/libopenmpttest-Logging.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/Logging.cpp' object='common/libopenmpttest-Logging.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-Logging.obj `if test -f 'common/Logging.cpp'; then $(CYGPATH_W) 'common/Logging.cpp'; else $(CYGPATH_W) '$(srcdir)/common/Logging.cpp'; fi` common/libopenmpttest-misc_util.o: common/misc_util.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-misc_util.o -MD -MP -MF common/$(DEPDIR)/libopenmpttest-misc_util.Tpo -c -o common/libopenmpttest-misc_util.o `test -f 'common/misc_util.cpp' || echo '$(srcdir)/'`common/misc_util.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-misc_util.Tpo common/$(DEPDIR)/libopenmpttest-misc_util.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/misc_util.cpp' object='common/libopenmpttest-misc_util.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-misc_util.o `test -f 'common/misc_util.cpp' || echo '$(srcdir)/'`common/misc_util.cpp common/libopenmpttest-misc_util.obj: common/misc_util.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-misc_util.obj -MD -MP -MF common/$(DEPDIR)/libopenmpttest-misc_util.Tpo -c -o common/libopenmpttest-misc_util.obj `if test -f 'common/misc_util.cpp'; then $(CYGPATH_W) 'common/misc_util.cpp'; else $(CYGPATH_W) '$(srcdir)/common/misc_util.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-misc_util.Tpo common/$(DEPDIR)/libopenmpttest-misc_util.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/misc_util.cpp' object='common/libopenmpttest-misc_util.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-misc_util.obj `if test -f 'common/misc_util.cpp'; then $(CYGPATH_W) 'common/misc_util.cpp'; else $(CYGPATH_W) '$(srcdir)/common/misc_util.cpp'; fi` common/libopenmpttest-mptCPU.o: common/mptCPU.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-mptCPU.o -MD -MP -MF common/$(DEPDIR)/libopenmpttest-mptCPU.Tpo -c -o common/libopenmpttest-mptCPU.o `test -f 'common/mptCPU.cpp' || echo '$(srcdir)/'`common/mptCPU.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-mptCPU.Tpo common/$(DEPDIR)/libopenmpttest-mptCPU.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptCPU.cpp' object='common/libopenmpttest-mptCPU.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-mptCPU.o `test -f 'common/mptCPU.cpp' || echo '$(srcdir)/'`common/mptCPU.cpp common/libopenmpttest-mptCPU.obj: common/mptCPU.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-mptCPU.obj -MD -MP -MF common/$(DEPDIR)/libopenmpttest-mptCPU.Tpo -c -o common/libopenmpttest-mptCPU.obj `if test -f 'common/mptCPU.cpp'; then $(CYGPATH_W) 'common/mptCPU.cpp'; else $(CYGPATH_W) '$(srcdir)/common/mptCPU.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-mptCPU.Tpo common/$(DEPDIR)/libopenmpttest-mptCPU.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptCPU.cpp' object='common/libopenmpttest-mptCPU.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-mptCPU.obj `if test -f 'common/mptCPU.cpp'; then $(CYGPATH_W) 'common/mptCPU.cpp'; else $(CYGPATH_W) '$(srcdir)/common/mptCPU.cpp'; fi` common/libopenmpttest-mptFileIO.o: common/mptFileIO.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-mptFileIO.o -MD -MP -MF common/$(DEPDIR)/libopenmpttest-mptFileIO.Tpo -c -o common/libopenmpttest-mptFileIO.o `test -f 'common/mptFileIO.cpp' || echo '$(srcdir)/'`common/mptFileIO.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-mptFileIO.Tpo common/$(DEPDIR)/libopenmpttest-mptFileIO.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptFileIO.cpp' object='common/libopenmpttest-mptFileIO.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-mptFileIO.o `test -f 'common/mptFileIO.cpp' || echo '$(srcdir)/'`common/mptFileIO.cpp common/libopenmpttest-mptFileIO.obj: common/mptFileIO.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-mptFileIO.obj -MD -MP -MF common/$(DEPDIR)/libopenmpttest-mptFileIO.Tpo -c -o common/libopenmpttest-mptFileIO.obj `if test -f 'common/mptFileIO.cpp'; then $(CYGPATH_W) 'common/mptFileIO.cpp'; else $(CYGPATH_W) '$(srcdir)/common/mptFileIO.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-mptFileIO.Tpo common/$(DEPDIR)/libopenmpttest-mptFileIO.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptFileIO.cpp' object='common/libopenmpttest-mptFileIO.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-mptFileIO.obj `if test -f 'common/mptFileIO.cpp'; then $(CYGPATH_W) 'common/mptFileIO.cpp'; else $(CYGPATH_W) '$(srcdir)/common/mptFileIO.cpp'; fi` common/libopenmpttest-mptIO.o: common/mptIO.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-mptIO.o -MD -MP -MF common/$(DEPDIR)/libopenmpttest-mptIO.Tpo -c -o common/libopenmpttest-mptIO.o `test -f 'common/mptIO.cpp' || echo '$(srcdir)/'`common/mptIO.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-mptIO.Tpo common/$(DEPDIR)/libopenmpttest-mptIO.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptIO.cpp' object='common/libopenmpttest-mptIO.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-mptIO.o `test -f 'common/mptIO.cpp' || echo '$(srcdir)/'`common/mptIO.cpp common/libopenmpttest-mptIO.obj: common/mptIO.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-mptIO.obj -MD -MP -MF common/$(DEPDIR)/libopenmpttest-mptIO.Tpo -c -o common/libopenmpttest-mptIO.obj `if test -f 'common/mptIO.cpp'; then $(CYGPATH_W) 'common/mptIO.cpp'; else $(CYGPATH_W) '$(srcdir)/common/mptIO.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-mptIO.Tpo common/$(DEPDIR)/libopenmpttest-mptIO.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptIO.cpp' object='common/libopenmpttest-mptIO.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-mptIO.obj `if test -f 'common/mptIO.cpp'; then $(CYGPATH_W) 'common/mptIO.cpp'; else $(CYGPATH_W) '$(srcdir)/common/mptIO.cpp'; fi` common/libopenmpttest-mptLibrary.o: common/mptLibrary.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-mptLibrary.o -MD -MP -MF common/$(DEPDIR)/libopenmpttest-mptLibrary.Tpo -c -o common/libopenmpttest-mptLibrary.o `test -f 'common/mptLibrary.cpp' || echo '$(srcdir)/'`common/mptLibrary.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-mptLibrary.Tpo common/$(DEPDIR)/libopenmpttest-mptLibrary.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptLibrary.cpp' object='common/libopenmpttest-mptLibrary.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-mptLibrary.o `test -f 'common/mptLibrary.cpp' || echo '$(srcdir)/'`common/mptLibrary.cpp common/libopenmpttest-mptLibrary.obj: common/mptLibrary.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-mptLibrary.obj -MD -MP -MF common/$(DEPDIR)/libopenmpttest-mptLibrary.Tpo -c -o common/libopenmpttest-mptLibrary.obj `if test -f 'common/mptLibrary.cpp'; then $(CYGPATH_W) 'common/mptLibrary.cpp'; else $(CYGPATH_W) '$(srcdir)/common/mptLibrary.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-mptLibrary.Tpo common/$(DEPDIR)/libopenmpttest-mptLibrary.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptLibrary.cpp' object='common/libopenmpttest-mptLibrary.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-mptLibrary.obj `if test -f 'common/mptLibrary.cpp'; then $(CYGPATH_W) 'common/mptLibrary.cpp'; else $(CYGPATH_W) '$(srcdir)/common/mptLibrary.cpp'; fi` common/libopenmpttest-mptOS.o: common/mptOS.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-mptOS.o -MD -MP -MF common/$(DEPDIR)/libopenmpttest-mptOS.Tpo -c -o common/libopenmpttest-mptOS.o `test -f 'common/mptOS.cpp' || echo '$(srcdir)/'`common/mptOS.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-mptOS.Tpo common/$(DEPDIR)/libopenmpttest-mptOS.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptOS.cpp' object='common/libopenmpttest-mptOS.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-mptOS.o `test -f 'common/mptOS.cpp' || echo '$(srcdir)/'`common/mptOS.cpp common/libopenmpttest-mptOS.obj: common/mptOS.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-mptOS.obj -MD -MP -MF common/$(DEPDIR)/libopenmpttest-mptOS.Tpo -c -o common/libopenmpttest-mptOS.obj `if test -f 'common/mptOS.cpp'; then $(CYGPATH_W) 'common/mptOS.cpp'; else $(CYGPATH_W) '$(srcdir)/common/mptOS.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-mptOS.Tpo common/$(DEPDIR)/libopenmpttest-mptOS.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptOS.cpp' object='common/libopenmpttest-mptOS.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-mptOS.obj `if test -f 'common/mptOS.cpp'; then $(CYGPATH_W) 'common/mptOS.cpp'; else $(CYGPATH_W) '$(srcdir)/common/mptOS.cpp'; fi` common/libopenmpttest-mptPathString.o: common/mptPathString.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-mptPathString.o -MD -MP -MF common/$(DEPDIR)/libopenmpttest-mptPathString.Tpo -c -o common/libopenmpttest-mptPathString.o `test -f 'common/mptPathString.cpp' || echo '$(srcdir)/'`common/mptPathString.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-mptPathString.Tpo common/$(DEPDIR)/libopenmpttest-mptPathString.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptPathString.cpp' object='common/libopenmpttest-mptPathString.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-mptPathString.o `test -f 'common/mptPathString.cpp' || echo '$(srcdir)/'`common/mptPathString.cpp common/libopenmpttest-mptPathString.obj: common/mptPathString.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-mptPathString.obj -MD -MP -MF common/$(DEPDIR)/libopenmpttest-mptPathString.Tpo -c -o common/libopenmpttest-mptPathString.obj `if test -f 'common/mptPathString.cpp'; then $(CYGPATH_W) 'common/mptPathString.cpp'; else $(CYGPATH_W) '$(srcdir)/common/mptPathString.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-mptPathString.Tpo common/$(DEPDIR)/libopenmpttest-mptPathString.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptPathString.cpp' object='common/libopenmpttest-mptPathString.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-mptPathString.obj `if test -f 'common/mptPathString.cpp'; then $(CYGPATH_W) 'common/mptPathString.cpp'; else $(CYGPATH_W) '$(srcdir)/common/mptPathString.cpp'; fi` common/libopenmpttest-mptRandom.o: common/mptRandom.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-mptRandom.o -MD -MP -MF common/$(DEPDIR)/libopenmpttest-mptRandom.Tpo -c -o common/libopenmpttest-mptRandom.o `test -f 'common/mptRandom.cpp' || echo '$(srcdir)/'`common/mptRandom.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-mptRandom.Tpo common/$(DEPDIR)/libopenmpttest-mptRandom.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptRandom.cpp' object='common/libopenmpttest-mptRandom.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-mptRandom.o `test -f 'common/mptRandom.cpp' || echo '$(srcdir)/'`common/mptRandom.cpp common/libopenmpttest-mptRandom.obj: common/mptRandom.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-mptRandom.obj -MD -MP -MF common/$(DEPDIR)/libopenmpttest-mptRandom.Tpo -c -o common/libopenmpttest-mptRandom.obj `if test -f 'common/mptRandom.cpp'; then $(CYGPATH_W) 'common/mptRandom.cpp'; else $(CYGPATH_W) '$(srcdir)/common/mptRandom.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-mptRandom.Tpo common/$(DEPDIR)/libopenmpttest-mptRandom.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptRandom.cpp' object='common/libopenmpttest-mptRandom.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-mptRandom.obj `if test -f 'common/mptRandom.cpp'; then $(CYGPATH_W) 'common/mptRandom.cpp'; else $(CYGPATH_W) '$(srcdir)/common/mptRandom.cpp'; fi` common/libopenmpttest-mptString.o: common/mptString.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-mptString.o -MD -MP -MF common/$(DEPDIR)/libopenmpttest-mptString.Tpo -c -o common/libopenmpttest-mptString.o `test -f 'common/mptString.cpp' || echo '$(srcdir)/'`common/mptString.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-mptString.Tpo common/$(DEPDIR)/libopenmpttest-mptString.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptString.cpp' object='common/libopenmpttest-mptString.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-mptString.o `test -f 'common/mptString.cpp' || echo '$(srcdir)/'`common/mptString.cpp common/libopenmpttest-mptString.obj: common/mptString.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-mptString.obj -MD -MP -MF common/$(DEPDIR)/libopenmpttest-mptString.Tpo -c -o common/libopenmpttest-mptString.obj `if test -f 'common/mptString.cpp'; then $(CYGPATH_W) 'common/mptString.cpp'; else $(CYGPATH_W) '$(srcdir)/common/mptString.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-mptString.Tpo common/$(DEPDIR)/libopenmpttest-mptString.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptString.cpp' object='common/libopenmpttest-mptString.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-mptString.obj `if test -f 'common/mptString.cpp'; then $(CYGPATH_W) 'common/mptString.cpp'; else $(CYGPATH_W) '$(srcdir)/common/mptString.cpp'; fi` common/libopenmpttest-mptStringFormat.o: common/mptStringFormat.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-mptStringFormat.o -MD -MP -MF common/$(DEPDIR)/libopenmpttest-mptStringFormat.Tpo -c -o common/libopenmpttest-mptStringFormat.o `test -f 'common/mptStringFormat.cpp' || echo '$(srcdir)/'`common/mptStringFormat.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-mptStringFormat.Tpo common/$(DEPDIR)/libopenmpttest-mptStringFormat.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptStringFormat.cpp' object='common/libopenmpttest-mptStringFormat.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-mptStringFormat.o `test -f 'common/mptStringFormat.cpp' || echo '$(srcdir)/'`common/mptStringFormat.cpp common/libopenmpttest-mptStringFormat.obj: common/mptStringFormat.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-mptStringFormat.obj -MD -MP -MF common/$(DEPDIR)/libopenmpttest-mptStringFormat.Tpo -c -o common/libopenmpttest-mptStringFormat.obj `if test -f 'common/mptStringFormat.cpp'; then $(CYGPATH_W) 'common/mptStringFormat.cpp'; else $(CYGPATH_W) '$(srcdir)/common/mptStringFormat.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-mptStringFormat.Tpo common/$(DEPDIR)/libopenmpttest-mptStringFormat.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptStringFormat.cpp' object='common/libopenmpttest-mptStringFormat.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-mptStringFormat.obj `if test -f 'common/mptStringFormat.cpp'; then $(CYGPATH_W) 'common/mptStringFormat.cpp'; else $(CYGPATH_W) '$(srcdir)/common/mptStringFormat.cpp'; fi` common/libopenmpttest-mptStringParse.o: common/mptStringParse.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-mptStringParse.o -MD -MP -MF common/$(DEPDIR)/libopenmpttest-mptStringParse.Tpo -c -o common/libopenmpttest-mptStringParse.o `test -f 'common/mptStringParse.cpp' || echo '$(srcdir)/'`common/mptStringParse.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-mptStringParse.Tpo common/$(DEPDIR)/libopenmpttest-mptStringParse.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptStringParse.cpp' object='common/libopenmpttest-mptStringParse.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-mptStringParse.o `test -f 'common/mptStringParse.cpp' || echo '$(srcdir)/'`common/mptStringParse.cpp common/libopenmpttest-mptStringParse.obj: common/mptStringParse.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-mptStringParse.obj -MD -MP -MF common/$(DEPDIR)/libopenmpttest-mptStringParse.Tpo -c -o common/libopenmpttest-mptStringParse.obj `if test -f 'common/mptStringParse.cpp'; then $(CYGPATH_W) 'common/mptStringParse.cpp'; else $(CYGPATH_W) '$(srcdir)/common/mptStringParse.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-mptStringParse.Tpo common/$(DEPDIR)/libopenmpttest-mptStringParse.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptStringParse.cpp' object='common/libopenmpttest-mptStringParse.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-mptStringParse.obj `if test -f 'common/mptStringParse.cpp'; then $(CYGPATH_W) 'common/mptStringParse.cpp'; else $(CYGPATH_W) '$(srcdir)/common/mptStringParse.cpp'; fi` common/libopenmpttest-mptTime.o: common/mptTime.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-mptTime.o -MD -MP -MF common/$(DEPDIR)/libopenmpttest-mptTime.Tpo -c -o common/libopenmpttest-mptTime.o `test -f 'common/mptTime.cpp' || echo '$(srcdir)/'`common/mptTime.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-mptTime.Tpo common/$(DEPDIR)/libopenmpttest-mptTime.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptTime.cpp' object='common/libopenmpttest-mptTime.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-mptTime.o `test -f 'common/mptTime.cpp' || echo '$(srcdir)/'`common/mptTime.cpp common/libopenmpttest-mptTime.obj: common/mptTime.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-mptTime.obj -MD -MP -MF common/$(DEPDIR)/libopenmpttest-mptTime.Tpo -c -o common/libopenmpttest-mptTime.obj `if test -f 'common/mptTime.cpp'; then $(CYGPATH_W) 'common/mptTime.cpp'; else $(CYGPATH_W) '$(srcdir)/common/mptTime.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-mptTime.Tpo common/$(DEPDIR)/libopenmpttest-mptTime.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptTime.cpp' object='common/libopenmpttest-mptTime.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-mptTime.obj `if test -f 'common/mptTime.cpp'; then $(CYGPATH_W) 'common/mptTime.cpp'; else $(CYGPATH_W) '$(srcdir)/common/mptTime.cpp'; fi` common/libopenmpttest-mptUUID.o: common/mptUUID.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-mptUUID.o -MD -MP -MF common/$(DEPDIR)/libopenmpttest-mptUUID.Tpo -c -o common/libopenmpttest-mptUUID.o `test -f 'common/mptUUID.cpp' || echo '$(srcdir)/'`common/mptUUID.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-mptUUID.Tpo common/$(DEPDIR)/libopenmpttest-mptUUID.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptUUID.cpp' object='common/libopenmpttest-mptUUID.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-mptUUID.o `test -f 'common/mptUUID.cpp' || echo '$(srcdir)/'`common/mptUUID.cpp common/libopenmpttest-mptUUID.obj: common/mptUUID.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-mptUUID.obj -MD -MP -MF common/$(DEPDIR)/libopenmpttest-mptUUID.Tpo -c -o common/libopenmpttest-mptUUID.obj `if test -f 'common/mptUUID.cpp'; then $(CYGPATH_W) 'common/mptUUID.cpp'; else $(CYGPATH_W) '$(srcdir)/common/mptUUID.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-mptUUID.Tpo common/$(DEPDIR)/libopenmpttest-mptUUID.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptUUID.cpp' object='common/libopenmpttest-mptUUID.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-mptUUID.obj `if test -f 'common/mptUUID.cpp'; then $(CYGPATH_W) 'common/mptUUID.cpp'; else $(CYGPATH_W) '$(srcdir)/common/mptUUID.cpp'; fi` common/libopenmpttest-mptWine.o: common/mptWine.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-mptWine.o -MD -MP -MF common/$(DEPDIR)/libopenmpttest-mptWine.Tpo -c -o common/libopenmpttest-mptWine.o `test -f 'common/mptWine.cpp' || echo '$(srcdir)/'`common/mptWine.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-mptWine.Tpo common/$(DEPDIR)/libopenmpttest-mptWine.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptWine.cpp' object='common/libopenmpttest-mptWine.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-mptWine.o `test -f 'common/mptWine.cpp' || echo '$(srcdir)/'`common/mptWine.cpp common/libopenmpttest-mptWine.obj: common/mptWine.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-mptWine.obj -MD -MP -MF common/$(DEPDIR)/libopenmpttest-mptWine.Tpo -c -o common/libopenmpttest-mptWine.obj `if test -f 'common/mptWine.cpp'; then $(CYGPATH_W) 'common/mptWine.cpp'; else $(CYGPATH_W) '$(srcdir)/common/mptWine.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-mptWine.Tpo common/$(DEPDIR)/libopenmpttest-mptWine.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/mptWine.cpp' object='common/libopenmpttest-mptWine.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-mptWine.obj `if test -f 'common/mptWine.cpp'; then $(CYGPATH_W) 'common/mptWine.cpp'; else $(CYGPATH_W) '$(srcdir)/common/mptWine.cpp'; fi` common/libopenmpttest-Profiler.o: common/Profiler.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-Profiler.o -MD -MP -MF common/$(DEPDIR)/libopenmpttest-Profiler.Tpo -c -o common/libopenmpttest-Profiler.o `test -f 'common/Profiler.cpp' || echo '$(srcdir)/'`common/Profiler.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-Profiler.Tpo common/$(DEPDIR)/libopenmpttest-Profiler.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/Profiler.cpp' object='common/libopenmpttest-Profiler.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-Profiler.o `test -f 'common/Profiler.cpp' || echo '$(srcdir)/'`common/Profiler.cpp common/libopenmpttest-Profiler.obj: common/Profiler.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-Profiler.obj -MD -MP -MF common/$(DEPDIR)/libopenmpttest-Profiler.Tpo -c -o common/libopenmpttest-Profiler.obj `if test -f 'common/Profiler.cpp'; then $(CYGPATH_W) 'common/Profiler.cpp'; else $(CYGPATH_W) '$(srcdir)/common/Profiler.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-Profiler.Tpo common/$(DEPDIR)/libopenmpttest-Profiler.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/Profiler.cpp' object='common/libopenmpttest-Profiler.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-Profiler.obj `if test -f 'common/Profiler.cpp'; then $(CYGPATH_W) 'common/Profiler.cpp'; else $(CYGPATH_W) '$(srcdir)/common/Profiler.cpp'; fi` common/libopenmpttest-serialization_utils.o: common/serialization_utils.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-serialization_utils.o -MD -MP -MF common/$(DEPDIR)/libopenmpttest-serialization_utils.Tpo -c -o common/libopenmpttest-serialization_utils.o `test -f 'common/serialization_utils.cpp' || echo '$(srcdir)/'`common/serialization_utils.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-serialization_utils.Tpo common/$(DEPDIR)/libopenmpttest-serialization_utils.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/serialization_utils.cpp' object='common/libopenmpttest-serialization_utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-serialization_utils.o `test -f 'common/serialization_utils.cpp' || echo '$(srcdir)/'`common/serialization_utils.cpp common/libopenmpttest-serialization_utils.obj: common/serialization_utils.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-serialization_utils.obj -MD -MP -MF common/$(DEPDIR)/libopenmpttest-serialization_utils.Tpo -c -o common/libopenmpttest-serialization_utils.obj `if test -f 'common/serialization_utils.cpp'; then $(CYGPATH_W) 'common/serialization_utils.cpp'; else $(CYGPATH_W) '$(srcdir)/common/serialization_utils.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-serialization_utils.Tpo common/$(DEPDIR)/libopenmpttest-serialization_utils.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/serialization_utils.cpp' object='common/libopenmpttest-serialization_utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-serialization_utils.obj `if test -f 'common/serialization_utils.cpp'; then $(CYGPATH_W) 'common/serialization_utils.cpp'; else $(CYGPATH_W) '$(srcdir)/common/serialization_utils.cpp'; fi` common/libopenmpttest-stdafx.o: common/stdafx.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-stdafx.o -MD -MP -MF common/$(DEPDIR)/libopenmpttest-stdafx.Tpo -c -o common/libopenmpttest-stdafx.o `test -f 'common/stdafx.cpp' || echo '$(srcdir)/'`common/stdafx.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-stdafx.Tpo common/$(DEPDIR)/libopenmpttest-stdafx.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/stdafx.cpp' object='common/libopenmpttest-stdafx.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-stdafx.o `test -f 'common/stdafx.cpp' || echo '$(srcdir)/'`common/stdafx.cpp common/libopenmpttest-stdafx.obj: common/stdafx.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-stdafx.obj -MD -MP -MF common/$(DEPDIR)/libopenmpttest-stdafx.Tpo -c -o common/libopenmpttest-stdafx.obj `if test -f 'common/stdafx.cpp'; then $(CYGPATH_W) 'common/stdafx.cpp'; else $(CYGPATH_W) '$(srcdir)/common/stdafx.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-stdafx.Tpo common/$(DEPDIR)/libopenmpttest-stdafx.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/stdafx.cpp' object='common/libopenmpttest-stdafx.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-stdafx.obj `if test -f 'common/stdafx.cpp'; then $(CYGPATH_W) 'common/stdafx.cpp'; else $(CYGPATH_W) '$(srcdir)/common/stdafx.cpp'; fi` common/libopenmpttest-typedefs.o: common/typedefs.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-typedefs.o -MD -MP -MF common/$(DEPDIR)/libopenmpttest-typedefs.Tpo -c -o common/libopenmpttest-typedefs.o `test -f 'common/typedefs.cpp' || echo '$(srcdir)/'`common/typedefs.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-typedefs.Tpo common/$(DEPDIR)/libopenmpttest-typedefs.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/typedefs.cpp' object='common/libopenmpttest-typedefs.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-typedefs.o `test -f 'common/typedefs.cpp' || echo '$(srcdir)/'`common/typedefs.cpp common/libopenmpttest-typedefs.obj: common/typedefs.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-typedefs.obj -MD -MP -MF common/$(DEPDIR)/libopenmpttest-typedefs.Tpo -c -o common/libopenmpttest-typedefs.obj `if test -f 'common/typedefs.cpp'; then $(CYGPATH_W) 'common/typedefs.cpp'; else $(CYGPATH_W) '$(srcdir)/common/typedefs.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-typedefs.Tpo common/$(DEPDIR)/libopenmpttest-typedefs.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/typedefs.cpp' object='common/libopenmpttest-typedefs.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-typedefs.obj `if test -f 'common/typedefs.cpp'; then $(CYGPATH_W) 'common/typedefs.cpp'; else $(CYGPATH_W) '$(srcdir)/common/typedefs.cpp'; fi` common/libopenmpttest-version.o: common/version.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-version.o -MD -MP -MF common/$(DEPDIR)/libopenmpttest-version.Tpo -c -o common/libopenmpttest-version.o `test -f 'common/version.cpp' || echo '$(srcdir)/'`common/version.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-version.Tpo common/$(DEPDIR)/libopenmpttest-version.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/version.cpp' object='common/libopenmpttest-version.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-version.o `test -f 'common/version.cpp' || echo '$(srcdir)/'`common/version.cpp common/libopenmpttest-version.obj: common/version.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT common/libopenmpttest-version.obj -MD -MP -MF common/$(DEPDIR)/libopenmpttest-version.Tpo -c -o common/libopenmpttest-version.obj `if test -f 'common/version.cpp'; then $(CYGPATH_W) 'common/version.cpp'; else $(CYGPATH_W) '$(srcdir)/common/version.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/libopenmpttest-version.Tpo common/$(DEPDIR)/libopenmpttest-version.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/version.cpp' object='common/libopenmpttest-version.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o common/libopenmpttest-version.obj `if test -f 'common/version.cpp'; then $(CYGPATH_W) 'common/version.cpp'; else $(CYGPATH_W) '$(srcdir)/common/version.cpp'; fi` soundlib/libopenmpttest-AudioCriticalSection.o: soundlib/AudioCriticalSection.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-AudioCriticalSection.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-AudioCriticalSection.Tpo -c -o soundlib/libopenmpttest-AudioCriticalSection.o `test -f 'soundlib/AudioCriticalSection.cpp' || echo '$(srcdir)/'`soundlib/AudioCriticalSection.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-AudioCriticalSection.Tpo soundlib/$(DEPDIR)/libopenmpttest-AudioCriticalSection.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/AudioCriticalSection.cpp' object='soundlib/libopenmpttest-AudioCriticalSection.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-AudioCriticalSection.o `test -f 'soundlib/AudioCriticalSection.cpp' || echo '$(srcdir)/'`soundlib/AudioCriticalSection.cpp soundlib/libopenmpttest-AudioCriticalSection.obj: soundlib/AudioCriticalSection.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-AudioCriticalSection.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-AudioCriticalSection.Tpo -c -o soundlib/libopenmpttest-AudioCriticalSection.obj `if test -f 'soundlib/AudioCriticalSection.cpp'; then $(CYGPATH_W) 'soundlib/AudioCriticalSection.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/AudioCriticalSection.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-AudioCriticalSection.Tpo soundlib/$(DEPDIR)/libopenmpttest-AudioCriticalSection.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/AudioCriticalSection.cpp' object='soundlib/libopenmpttest-AudioCriticalSection.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-AudioCriticalSection.obj `if test -f 'soundlib/AudioCriticalSection.cpp'; then $(CYGPATH_W) 'soundlib/AudioCriticalSection.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/AudioCriticalSection.cpp'; fi` soundlib/libopenmpttest-ContainerMMCMP.o: soundlib/ContainerMMCMP.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-ContainerMMCMP.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-ContainerMMCMP.Tpo -c -o soundlib/libopenmpttest-ContainerMMCMP.o `test -f 'soundlib/ContainerMMCMP.cpp' || echo '$(srcdir)/'`soundlib/ContainerMMCMP.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-ContainerMMCMP.Tpo soundlib/$(DEPDIR)/libopenmpttest-ContainerMMCMP.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/ContainerMMCMP.cpp' object='soundlib/libopenmpttest-ContainerMMCMP.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-ContainerMMCMP.o `test -f 'soundlib/ContainerMMCMP.cpp' || echo '$(srcdir)/'`soundlib/ContainerMMCMP.cpp soundlib/libopenmpttest-ContainerMMCMP.obj: soundlib/ContainerMMCMP.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-ContainerMMCMP.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-ContainerMMCMP.Tpo -c -o soundlib/libopenmpttest-ContainerMMCMP.obj `if test -f 'soundlib/ContainerMMCMP.cpp'; then $(CYGPATH_W) 'soundlib/ContainerMMCMP.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/ContainerMMCMP.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-ContainerMMCMP.Tpo soundlib/$(DEPDIR)/libopenmpttest-ContainerMMCMP.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/ContainerMMCMP.cpp' object='soundlib/libopenmpttest-ContainerMMCMP.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-ContainerMMCMP.obj `if test -f 'soundlib/ContainerMMCMP.cpp'; then $(CYGPATH_W) 'soundlib/ContainerMMCMP.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/ContainerMMCMP.cpp'; fi` soundlib/libopenmpttest-ContainerPP20.o: soundlib/ContainerPP20.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-ContainerPP20.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-ContainerPP20.Tpo -c -o soundlib/libopenmpttest-ContainerPP20.o `test -f 'soundlib/ContainerPP20.cpp' || echo '$(srcdir)/'`soundlib/ContainerPP20.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-ContainerPP20.Tpo soundlib/$(DEPDIR)/libopenmpttest-ContainerPP20.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/ContainerPP20.cpp' object='soundlib/libopenmpttest-ContainerPP20.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-ContainerPP20.o `test -f 'soundlib/ContainerPP20.cpp' || echo '$(srcdir)/'`soundlib/ContainerPP20.cpp soundlib/libopenmpttest-ContainerPP20.obj: soundlib/ContainerPP20.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-ContainerPP20.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-ContainerPP20.Tpo -c -o soundlib/libopenmpttest-ContainerPP20.obj `if test -f 'soundlib/ContainerPP20.cpp'; then $(CYGPATH_W) 'soundlib/ContainerPP20.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/ContainerPP20.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-ContainerPP20.Tpo soundlib/$(DEPDIR)/libopenmpttest-ContainerPP20.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/ContainerPP20.cpp' object='soundlib/libopenmpttest-ContainerPP20.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-ContainerPP20.obj `if test -f 'soundlib/ContainerPP20.cpp'; then $(CYGPATH_W) 'soundlib/ContainerPP20.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/ContainerPP20.cpp'; fi` soundlib/libopenmpttest-ContainerUMX.o: soundlib/ContainerUMX.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-ContainerUMX.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-ContainerUMX.Tpo -c -o soundlib/libopenmpttest-ContainerUMX.o `test -f 'soundlib/ContainerUMX.cpp' || echo '$(srcdir)/'`soundlib/ContainerUMX.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-ContainerUMX.Tpo soundlib/$(DEPDIR)/libopenmpttest-ContainerUMX.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/ContainerUMX.cpp' object='soundlib/libopenmpttest-ContainerUMX.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-ContainerUMX.o `test -f 'soundlib/ContainerUMX.cpp' || echo '$(srcdir)/'`soundlib/ContainerUMX.cpp soundlib/libopenmpttest-ContainerUMX.obj: soundlib/ContainerUMX.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-ContainerUMX.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-ContainerUMX.Tpo -c -o soundlib/libopenmpttest-ContainerUMX.obj `if test -f 'soundlib/ContainerUMX.cpp'; then $(CYGPATH_W) 'soundlib/ContainerUMX.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/ContainerUMX.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-ContainerUMX.Tpo soundlib/$(DEPDIR)/libopenmpttest-ContainerUMX.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/ContainerUMX.cpp' object='soundlib/libopenmpttest-ContainerUMX.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-ContainerUMX.obj `if test -f 'soundlib/ContainerUMX.cpp'; then $(CYGPATH_W) 'soundlib/ContainerUMX.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/ContainerUMX.cpp'; fi` soundlib/libopenmpttest-ContainerXPK.o: soundlib/ContainerXPK.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-ContainerXPK.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-ContainerXPK.Tpo -c -o soundlib/libopenmpttest-ContainerXPK.o `test -f 'soundlib/ContainerXPK.cpp' || echo '$(srcdir)/'`soundlib/ContainerXPK.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-ContainerXPK.Tpo soundlib/$(DEPDIR)/libopenmpttest-ContainerXPK.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/ContainerXPK.cpp' object='soundlib/libopenmpttest-ContainerXPK.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-ContainerXPK.o `test -f 'soundlib/ContainerXPK.cpp' || echo '$(srcdir)/'`soundlib/ContainerXPK.cpp soundlib/libopenmpttest-ContainerXPK.obj: soundlib/ContainerXPK.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-ContainerXPK.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-ContainerXPK.Tpo -c -o soundlib/libopenmpttest-ContainerXPK.obj `if test -f 'soundlib/ContainerXPK.cpp'; then $(CYGPATH_W) 'soundlib/ContainerXPK.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/ContainerXPK.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-ContainerXPK.Tpo soundlib/$(DEPDIR)/libopenmpttest-ContainerXPK.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/ContainerXPK.cpp' object='soundlib/libopenmpttest-ContainerXPK.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-ContainerXPK.obj `if test -f 'soundlib/ContainerXPK.cpp'; then $(CYGPATH_W) 'soundlib/ContainerXPK.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/ContainerXPK.cpp'; fi` soundlib/libopenmpttest-Dither.o: soundlib/Dither.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Dither.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Dither.Tpo -c -o soundlib/libopenmpttest-Dither.o `test -f 'soundlib/Dither.cpp' || echo '$(srcdir)/'`soundlib/Dither.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Dither.Tpo soundlib/$(DEPDIR)/libopenmpttest-Dither.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Dither.cpp' object='soundlib/libopenmpttest-Dither.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Dither.o `test -f 'soundlib/Dither.cpp' || echo '$(srcdir)/'`soundlib/Dither.cpp soundlib/libopenmpttest-Dither.obj: soundlib/Dither.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Dither.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Dither.Tpo -c -o soundlib/libopenmpttest-Dither.obj `if test -f 'soundlib/Dither.cpp'; then $(CYGPATH_W) 'soundlib/Dither.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Dither.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Dither.Tpo soundlib/$(DEPDIR)/libopenmpttest-Dither.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Dither.cpp' object='soundlib/libopenmpttest-Dither.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Dither.obj `if test -f 'soundlib/Dither.cpp'; then $(CYGPATH_W) 'soundlib/Dither.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Dither.cpp'; fi` soundlib/libopenmpttest-Dlsbank.o: soundlib/Dlsbank.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Dlsbank.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Dlsbank.Tpo -c -o soundlib/libopenmpttest-Dlsbank.o `test -f 'soundlib/Dlsbank.cpp' || echo '$(srcdir)/'`soundlib/Dlsbank.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Dlsbank.Tpo soundlib/$(DEPDIR)/libopenmpttest-Dlsbank.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Dlsbank.cpp' object='soundlib/libopenmpttest-Dlsbank.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Dlsbank.o `test -f 'soundlib/Dlsbank.cpp' || echo '$(srcdir)/'`soundlib/Dlsbank.cpp soundlib/libopenmpttest-Dlsbank.obj: soundlib/Dlsbank.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Dlsbank.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Dlsbank.Tpo -c -o soundlib/libopenmpttest-Dlsbank.obj `if test -f 'soundlib/Dlsbank.cpp'; then $(CYGPATH_W) 'soundlib/Dlsbank.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Dlsbank.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Dlsbank.Tpo soundlib/$(DEPDIR)/libopenmpttest-Dlsbank.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Dlsbank.cpp' object='soundlib/libopenmpttest-Dlsbank.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Dlsbank.obj `if test -f 'soundlib/Dlsbank.cpp'; then $(CYGPATH_W) 'soundlib/Dlsbank.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Dlsbank.cpp'; fi` soundlib/libopenmpttest-Fastmix.o: soundlib/Fastmix.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Fastmix.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Fastmix.Tpo -c -o soundlib/libopenmpttest-Fastmix.o `test -f 'soundlib/Fastmix.cpp' || echo '$(srcdir)/'`soundlib/Fastmix.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Fastmix.Tpo soundlib/$(DEPDIR)/libopenmpttest-Fastmix.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Fastmix.cpp' object='soundlib/libopenmpttest-Fastmix.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Fastmix.o `test -f 'soundlib/Fastmix.cpp' || echo '$(srcdir)/'`soundlib/Fastmix.cpp soundlib/libopenmpttest-Fastmix.obj: soundlib/Fastmix.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Fastmix.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Fastmix.Tpo -c -o soundlib/libopenmpttest-Fastmix.obj `if test -f 'soundlib/Fastmix.cpp'; then $(CYGPATH_W) 'soundlib/Fastmix.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Fastmix.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Fastmix.Tpo soundlib/$(DEPDIR)/libopenmpttest-Fastmix.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Fastmix.cpp' object='soundlib/libopenmpttest-Fastmix.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Fastmix.obj `if test -f 'soundlib/Fastmix.cpp'; then $(CYGPATH_W) 'soundlib/Fastmix.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Fastmix.cpp'; fi` soundlib/libopenmpttest-InstrumentExtensions.o: soundlib/InstrumentExtensions.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-InstrumentExtensions.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-InstrumentExtensions.Tpo -c -o soundlib/libopenmpttest-InstrumentExtensions.o `test -f 'soundlib/InstrumentExtensions.cpp' || echo '$(srcdir)/'`soundlib/InstrumentExtensions.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-InstrumentExtensions.Tpo soundlib/$(DEPDIR)/libopenmpttest-InstrumentExtensions.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/InstrumentExtensions.cpp' object='soundlib/libopenmpttest-InstrumentExtensions.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-InstrumentExtensions.o `test -f 'soundlib/InstrumentExtensions.cpp' || echo '$(srcdir)/'`soundlib/InstrumentExtensions.cpp soundlib/libopenmpttest-InstrumentExtensions.obj: soundlib/InstrumentExtensions.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-InstrumentExtensions.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-InstrumentExtensions.Tpo -c -o soundlib/libopenmpttest-InstrumentExtensions.obj `if test -f 'soundlib/InstrumentExtensions.cpp'; then $(CYGPATH_W) 'soundlib/InstrumentExtensions.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/InstrumentExtensions.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-InstrumentExtensions.Tpo soundlib/$(DEPDIR)/libopenmpttest-InstrumentExtensions.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/InstrumentExtensions.cpp' object='soundlib/libopenmpttest-InstrumentExtensions.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-InstrumentExtensions.obj `if test -f 'soundlib/InstrumentExtensions.cpp'; then $(CYGPATH_W) 'soundlib/InstrumentExtensions.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/InstrumentExtensions.cpp'; fi` soundlib/libopenmpttest-ITCompression.o: soundlib/ITCompression.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-ITCompression.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-ITCompression.Tpo -c -o soundlib/libopenmpttest-ITCompression.o `test -f 'soundlib/ITCompression.cpp' || echo '$(srcdir)/'`soundlib/ITCompression.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-ITCompression.Tpo soundlib/$(DEPDIR)/libopenmpttest-ITCompression.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/ITCompression.cpp' object='soundlib/libopenmpttest-ITCompression.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-ITCompression.o `test -f 'soundlib/ITCompression.cpp' || echo '$(srcdir)/'`soundlib/ITCompression.cpp soundlib/libopenmpttest-ITCompression.obj: soundlib/ITCompression.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-ITCompression.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-ITCompression.Tpo -c -o soundlib/libopenmpttest-ITCompression.obj `if test -f 'soundlib/ITCompression.cpp'; then $(CYGPATH_W) 'soundlib/ITCompression.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/ITCompression.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-ITCompression.Tpo soundlib/$(DEPDIR)/libopenmpttest-ITCompression.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/ITCompression.cpp' object='soundlib/libopenmpttest-ITCompression.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-ITCompression.obj `if test -f 'soundlib/ITCompression.cpp'; then $(CYGPATH_W) 'soundlib/ITCompression.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/ITCompression.cpp'; fi` soundlib/libopenmpttest-ITTools.o: soundlib/ITTools.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-ITTools.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-ITTools.Tpo -c -o soundlib/libopenmpttest-ITTools.o `test -f 'soundlib/ITTools.cpp' || echo '$(srcdir)/'`soundlib/ITTools.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-ITTools.Tpo soundlib/$(DEPDIR)/libopenmpttest-ITTools.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/ITTools.cpp' object='soundlib/libopenmpttest-ITTools.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-ITTools.o `test -f 'soundlib/ITTools.cpp' || echo '$(srcdir)/'`soundlib/ITTools.cpp soundlib/libopenmpttest-ITTools.obj: soundlib/ITTools.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-ITTools.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-ITTools.Tpo -c -o soundlib/libopenmpttest-ITTools.obj `if test -f 'soundlib/ITTools.cpp'; then $(CYGPATH_W) 'soundlib/ITTools.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/ITTools.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-ITTools.Tpo soundlib/$(DEPDIR)/libopenmpttest-ITTools.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/ITTools.cpp' object='soundlib/libopenmpttest-ITTools.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-ITTools.obj `if test -f 'soundlib/ITTools.cpp'; then $(CYGPATH_W) 'soundlib/ITTools.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/ITTools.cpp'; fi` soundlib/libopenmpttest-Load_669.o: soundlib/Load_669.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_669.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_669.Tpo -c -o soundlib/libopenmpttest-Load_669.o `test -f 'soundlib/Load_669.cpp' || echo '$(srcdir)/'`soundlib/Load_669.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_669.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_669.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_669.cpp' object='soundlib/libopenmpttest-Load_669.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_669.o `test -f 'soundlib/Load_669.cpp' || echo '$(srcdir)/'`soundlib/Load_669.cpp soundlib/libopenmpttest-Load_669.obj: soundlib/Load_669.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_669.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_669.Tpo -c -o soundlib/libopenmpttest-Load_669.obj `if test -f 'soundlib/Load_669.cpp'; then $(CYGPATH_W) 'soundlib/Load_669.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_669.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_669.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_669.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_669.cpp' object='soundlib/libopenmpttest-Load_669.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_669.obj `if test -f 'soundlib/Load_669.cpp'; then $(CYGPATH_W) 'soundlib/Load_669.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_669.cpp'; fi` soundlib/libopenmpttest-Load_amf.o: soundlib/Load_amf.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_amf.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_amf.Tpo -c -o soundlib/libopenmpttest-Load_amf.o `test -f 'soundlib/Load_amf.cpp' || echo '$(srcdir)/'`soundlib/Load_amf.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_amf.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_amf.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_amf.cpp' object='soundlib/libopenmpttest-Load_amf.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_amf.o `test -f 'soundlib/Load_amf.cpp' || echo '$(srcdir)/'`soundlib/Load_amf.cpp soundlib/libopenmpttest-Load_amf.obj: soundlib/Load_amf.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_amf.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_amf.Tpo -c -o soundlib/libopenmpttest-Load_amf.obj `if test -f 'soundlib/Load_amf.cpp'; then $(CYGPATH_W) 'soundlib/Load_amf.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_amf.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_amf.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_amf.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_amf.cpp' object='soundlib/libopenmpttest-Load_amf.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_amf.obj `if test -f 'soundlib/Load_amf.cpp'; then $(CYGPATH_W) 'soundlib/Load_amf.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_amf.cpp'; fi` soundlib/libopenmpttest-Load_ams.o: soundlib/Load_ams.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_ams.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_ams.Tpo -c -o soundlib/libopenmpttest-Load_ams.o `test -f 'soundlib/Load_ams.cpp' || echo '$(srcdir)/'`soundlib/Load_ams.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_ams.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_ams.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_ams.cpp' object='soundlib/libopenmpttest-Load_ams.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_ams.o `test -f 'soundlib/Load_ams.cpp' || echo '$(srcdir)/'`soundlib/Load_ams.cpp soundlib/libopenmpttest-Load_ams.obj: soundlib/Load_ams.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_ams.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_ams.Tpo -c -o soundlib/libopenmpttest-Load_ams.obj `if test -f 'soundlib/Load_ams.cpp'; then $(CYGPATH_W) 'soundlib/Load_ams.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_ams.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_ams.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_ams.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_ams.cpp' object='soundlib/libopenmpttest-Load_ams.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_ams.obj `if test -f 'soundlib/Load_ams.cpp'; then $(CYGPATH_W) 'soundlib/Load_ams.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_ams.cpp'; fi` soundlib/libopenmpttest-Load_dbm.o: soundlib/Load_dbm.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_dbm.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_dbm.Tpo -c -o soundlib/libopenmpttest-Load_dbm.o `test -f 'soundlib/Load_dbm.cpp' || echo '$(srcdir)/'`soundlib/Load_dbm.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_dbm.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_dbm.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_dbm.cpp' object='soundlib/libopenmpttest-Load_dbm.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_dbm.o `test -f 'soundlib/Load_dbm.cpp' || echo '$(srcdir)/'`soundlib/Load_dbm.cpp soundlib/libopenmpttest-Load_dbm.obj: soundlib/Load_dbm.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_dbm.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_dbm.Tpo -c -o soundlib/libopenmpttest-Load_dbm.obj `if test -f 'soundlib/Load_dbm.cpp'; then $(CYGPATH_W) 'soundlib/Load_dbm.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_dbm.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_dbm.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_dbm.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_dbm.cpp' object='soundlib/libopenmpttest-Load_dbm.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_dbm.obj `if test -f 'soundlib/Load_dbm.cpp'; then $(CYGPATH_W) 'soundlib/Load_dbm.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_dbm.cpp'; fi` soundlib/libopenmpttest-Load_digi.o: soundlib/Load_digi.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_digi.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_digi.Tpo -c -o soundlib/libopenmpttest-Load_digi.o `test -f 'soundlib/Load_digi.cpp' || echo '$(srcdir)/'`soundlib/Load_digi.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_digi.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_digi.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_digi.cpp' object='soundlib/libopenmpttest-Load_digi.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_digi.o `test -f 'soundlib/Load_digi.cpp' || echo '$(srcdir)/'`soundlib/Load_digi.cpp soundlib/libopenmpttest-Load_digi.obj: soundlib/Load_digi.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_digi.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_digi.Tpo -c -o soundlib/libopenmpttest-Load_digi.obj `if test -f 'soundlib/Load_digi.cpp'; then $(CYGPATH_W) 'soundlib/Load_digi.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_digi.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_digi.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_digi.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_digi.cpp' object='soundlib/libopenmpttest-Load_digi.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_digi.obj `if test -f 'soundlib/Load_digi.cpp'; then $(CYGPATH_W) 'soundlib/Load_digi.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_digi.cpp'; fi` soundlib/libopenmpttest-Load_dmf.o: soundlib/Load_dmf.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_dmf.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_dmf.Tpo -c -o soundlib/libopenmpttest-Load_dmf.o `test -f 'soundlib/Load_dmf.cpp' || echo '$(srcdir)/'`soundlib/Load_dmf.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_dmf.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_dmf.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_dmf.cpp' object='soundlib/libopenmpttest-Load_dmf.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_dmf.o `test -f 'soundlib/Load_dmf.cpp' || echo '$(srcdir)/'`soundlib/Load_dmf.cpp soundlib/libopenmpttest-Load_dmf.obj: soundlib/Load_dmf.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_dmf.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_dmf.Tpo -c -o soundlib/libopenmpttest-Load_dmf.obj `if test -f 'soundlib/Load_dmf.cpp'; then $(CYGPATH_W) 'soundlib/Load_dmf.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_dmf.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_dmf.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_dmf.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_dmf.cpp' object='soundlib/libopenmpttest-Load_dmf.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_dmf.obj `if test -f 'soundlib/Load_dmf.cpp'; then $(CYGPATH_W) 'soundlib/Load_dmf.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_dmf.cpp'; fi` soundlib/libopenmpttest-Load_dsm.o: soundlib/Load_dsm.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_dsm.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_dsm.Tpo -c -o soundlib/libopenmpttest-Load_dsm.o `test -f 'soundlib/Load_dsm.cpp' || echo '$(srcdir)/'`soundlib/Load_dsm.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_dsm.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_dsm.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_dsm.cpp' object='soundlib/libopenmpttest-Load_dsm.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_dsm.o `test -f 'soundlib/Load_dsm.cpp' || echo '$(srcdir)/'`soundlib/Load_dsm.cpp soundlib/libopenmpttest-Load_dsm.obj: soundlib/Load_dsm.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_dsm.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_dsm.Tpo -c -o soundlib/libopenmpttest-Load_dsm.obj `if test -f 'soundlib/Load_dsm.cpp'; then $(CYGPATH_W) 'soundlib/Load_dsm.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_dsm.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_dsm.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_dsm.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_dsm.cpp' object='soundlib/libopenmpttest-Load_dsm.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_dsm.obj `if test -f 'soundlib/Load_dsm.cpp'; then $(CYGPATH_W) 'soundlib/Load_dsm.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_dsm.cpp'; fi` soundlib/libopenmpttest-Load_dtm.o: soundlib/Load_dtm.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_dtm.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_dtm.Tpo -c -o soundlib/libopenmpttest-Load_dtm.o `test -f 'soundlib/Load_dtm.cpp' || echo '$(srcdir)/'`soundlib/Load_dtm.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_dtm.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_dtm.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_dtm.cpp' object='soundlib/libopenmpttest-Load_dtm.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_dtm.o `test -f 'soundlib/Load_dtm.cpp' || echo '$(srcdir)/'`soundlib/Load_dtm.cpp soundlib/libopenmpttest-Load_dtm.obj: soundlib/Load_dtm.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_dtm.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_dtm.Tpo -c -o soundlib/libopenmpttest-Load_dtm.obj `if test -f 'soundlib/Load_dtm.cpp'; then $(CYGPATH_W) 'soundlib/Load_dtm.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_dtm.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_dtm.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_dtm.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_dtm.cpp' object='soundlib/libopenmpttest-Load_dtm.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_dtm.obj `if test -f 'soundlib/Load_dtm.cpp'; then $(CYGPATH_W) 'soundlib/Load_dtm.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_dtm.cpp'; fi` soundlib/libopenmpttest-Load_far.o: soundlib/Load_far.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_far.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_far.Tpo -c -o soundlib/libopenmpttest-Load_far.o `test -f 'soundlib/Load_far.cpp' || echo '$(srcdir)/'`soundlib/Load_far.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_far.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_far.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_far.cpp' object='soundlib/libopenmpttest-Load_far.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_far.o `test -f 'soundlib/Load_far.cpp' || echo '$(srcdir)/'`soundlib/Load_far.cpp soundlib/libopenmpttest-Load_far.obj: soundlib/Load_far.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_far.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_far.Tpo -c -o soundlib/libopenmpttest-Load_far.obj `if test -f 'soundlib/Load_far.cpp'; then $(CYGPATH_W) 'soundlib/Load_far.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_far.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_far.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_far.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_far.cpp' object='soundlib/libopenmpttest-Load_far.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_far.obj `if test -f 'soundlib/Load_far.cpp'; then $(CYGPATH_W) 'soundlib/Load_far.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_far.cpp'; fi` soundlib/libopenmpttest-Load_gdm.o: soundlib/Load_gdm.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_gdm.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_gdm.Tpo -c -o soundlib/libopenmpttest-Load_gdm.o `test -f 'soundlib/Load_gdm.cpp' || echo '$(srcdir)/'`soundlib/Load_gdm.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_gdm.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_gdm.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_gdm.cpp' object='soundlib/libopenmpttest-Load_gdm.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_gdm.o `test -f 'soundlib/Load_gdm.cpp' || echo '$(srcdir)/'`soundlib/Load_gdm.cpp soundlib/libopenmpttest-Load_gdm.obj: soundlib/Load_gdm.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_gdm.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_gdm.Tpo -c -o soundlib/libopenmpttest-Load_gdm.obj `if test -f 'soundlib/Load_gdm.cpp'; then $(CYGPATH_W) 'soundlib/Load_gdm.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_gdm.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_gdm.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_gdm.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_gdm.cpp' object='soundlib/libopenmpttest-Load_gdm.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_gdm.obj `if test -f 'soundlib/Load_gdm.cpp'; then $(CYGPATH_W) 'soundlib/Load_gdm.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_gdm.cpp'; fi` soundlib/libopenmpttest-Load_imf.o: soundlib/Load_imf.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_imf.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_imf.Tpo -c -o soundlib/libopenmpttest-Load_imf.o `test -f 'soundlib/Load_imf.cpp' || echo '$(srcdir)/'`soundlib/Load_imf.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_imf.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_imf.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_imf.cpp' object='soundlib/libopenmpttest-Load_imf.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_imf.o `test -f 'soundlib/Load_imf.cpp' || echo '$(srcdir)/'`soundlib/Load_imf.cpp soundlib/libopenmpttest-Load_imf.obj: soundlib/Load_imf.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_imf.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_imf.Tpo -c -o soundlib/libopenmpttest-Load_imf.obj `if test -f 'soundlib/Load_imf.cpp'; then $(CYGPATH_W) 'soundlib/Load_imf.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_imf.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_imf.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_imf.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_imf.cpp' object='soundlib/libopenmpttest-Load_imf.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_imf.obj `if test -f 'soundlib/Load_imf.cpp'; then $(CYGPATH_W) 'soundlib/Load_imf.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_imf.cpp'; fi` soundlib/libopenmpttest-Load_it.o: soundlib/Load_it.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_it.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_it.Tpo -c -o soundlib/libopenmpttest-Load_it.o `test -f 'soundlib/Load_it.cpp' || echo '$(srcdir)/'`soundlib/Load_it.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_it.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_it.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_it.cpp' object='soundlib/libopenmpttest-Load_it.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_it.o `test -f 'soundlib/Load_it.cpp' || echo '$(srcdir)/'`soundlib/Load_it.cpp soundlib/libopenmpttest-Load_it.obj: soundlib/Load_it.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_it.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_it.Tpo -c -o soundlib/libopenmpttest-Load_it.obj `if test -f 'soundlib/Load_it.cpp'; then $(CYGPATH_W) 'soundlib/Load_it.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_it.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_it.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_it.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_it.cpp' object='soundlib/libopenmpttest-Load_it.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_it.obj `if test -f 'soundlib/Load_it.cpp'; then $(CYGPATH_W) 'soundlib/Load_it.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_it.cpp'; fi` soundlib/libopenmpttest-Load_itp.o: soundlib/Load_itp.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_itp.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_itp.Tpo -c -o soundlib/libopenmpttest-Load_itp.o `test -f 'soundlib/Load_itp.cpp' || echo '$(srcdir)/'`soundlib/Load_itp.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_itp.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_itp.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_itp.cpp' object='soundlib/libopenmpttest-Load_itp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_itp.o `test -f 'soundlib/Load_itp.cpp' || echo '$(srcdir)/'`soundlib/Load_itp.cpp soundlib/libopenmpttest-Load_itp.obj: soundlib/Load_itp.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_itp.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_itp.Tpo -c -o soundlib/libopenmpttest-Load_itp.obj `if test -f 'soundlib/Load_itp.cpp'; then $(CYGPATH_W) 'soundlib/Load_itp.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_itp.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_itp.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_itp.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_itp.cpp' object='soundlib/libopenmpttest-Load_itp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_itp.obj `if test -f 'soundlib/Load_itp.cpp'; then $(CYGPATH_W) 'soundlib/Load_itp.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_itp.cpp'; fi` soundlib/libopenmpttest-load_j2b.o: soundlib/load_j2b.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-load_j2b.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-load_j2b.Tpo -c -o soundlib/libopenmpttest-load_j2b.o `test -f 'soundlib/load_j2b.cpp' || echo '$(srcdir)/'`soundlib/load_j2b.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-load_j2b.Tpo soundlib/$(DEPDIR)/libopenmpttest-load_j2b.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/load_j2b.cpp' object='soundlib/libopenmpttest-load_j2b.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-load_j2b.o `test -f 'soundlib/load_j2b.cpp' || echo '$(srcdir)/'`soundlib/load_j2b.cpp soundlib/libopenmpttest-load_j2b.obj: soundlib/load_j2b.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-load_j2b.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-load_j2b.Tpo -c -o soundlib/libopenmpttest-load_j2b.obj `if test -f 'soundlib/load_j2b.cpp'; then $(CYGPATH_W) 'soundlib/load_j2b.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/load_j2b.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-load_j2b.Tpo soundlib/$(DEPDIR)/libopenmpttest-load_j2b.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/load_j2b.cpp' object='soundlib/libopenmpttest-load_j2b.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-load_j2b.obj `if test -f 'soundlib/load_j2b.cpp'; then $(CYGPATH_W) 'soundlib/load_j2b.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/load_j2b.cpp'; fi` soundlib/libopenmpttest-Load_mdl.o: soundlib/Load_mdl.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_mdl.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_mdl.Tpo -c -o soundlib/libopenmpttest-Load_mdl.o `test -f 'soundlib/Load_mdl.cpp' || echo '$(srcdir)/'`soundlib/Load_mdl.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_mdl.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_mdl.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_mdl.cpp' object='soundlib/libopenmpttest-Load_mdl.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_mdl.o `test -f 'soundlib/Load_mdl.cpp' || echo '$(srcdir)/'`soundlib/Load_mdl.cpp soundlib/libopenmpttest-Load_mdl.obj: soundlib/Load_mdl.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_mdl.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_mdl.Tpo -c -o soundlib/libopenmpttest-Load_mdl.obj `if test -f 'soundlib/Load_mdl.cpp'; then $(CYGPATH_W) 'soundlib/Load_mdl.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_mdl.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_mdl.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_mdl.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_mdl.cpp' object='soundlib/libopenmpttest-Load_mdl.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_mdl.obj `if test -f 'soundlib/Load_mdl.cpp'; then $(CYGPATH_W) 'soundlib/Load_mdl.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_mdl.cpp'; fi` soundlib/libopenmpttest-Load_med.o: soundlib/Load_med.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_med.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_med.Tpo -c -o soundlib/libopenmpttest-Load_med.o `test -f 'soundlib/Load_med.cpp' || echo '$(srcdir)/'`soundlib/Load_med.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_med.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_med.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_med.cpp' object='soundlib/libopenmpttest-Load_med.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_med.o `test -f 'soundlib/Load_med.cpp' || echo '$(srcdir)/'`soundlib/Load_med.cpp soundlib/libopenmpttest-Load_med.obj: soundlib/Load_med.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_med.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_med.Tpo -c -o soundlib/libopenmpttest-Load_med.obj `if test -f 'soundlib/Load_med.cpp'; then $(CYGPATH_W) 'soundlib/Load_med.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_med.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_med.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_med.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_med.cpp' object='soundlib/libopenmpttest-Load_med.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_med.obj `if test -f 'soundlib/Load_med.cpp'; then $(CYGPATH_W) 'soundlib/Load_med.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_med.cpp'; fi` soundlib/libopenmpttest-Load_mid.o: soundlib/Load_mid.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_mid.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_mid.Tpo -c -o soundlib/libopenmpttest-Load_mid.o `test -f 'soundlib/Load_mid.cpp' || echo '$(srcdir)/'`soundlib/Load_mid.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_mid.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_mid.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_mid.cpp' object='soundlib/libopenmpttest-Load_mid.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_mid.o `test -f 'soundlib/Load_mid.cpp' || echo '$(srcdir)/'`soundlib/Load_mid.cpp soundlib/libopenmpttest-Load_mid.obj: soundlib/Load_mid.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_mid.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_mid.Tpo -c -o soundlib/libopenmpttest-Load_mid.obj `if test -f 'soundlib/Load_mid.cpp'; then $(CYGPATH_W) 'soundlib/Load_mid.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_mid.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_mid.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_mid.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_mid.cpp' object='soundlib/libopenmpttest-Load_mid.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_mid.obj `if test -f 'soundlib/Load_mid.cpp'; then $(CYGPATH_W) 'soundlib/Load_mid.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_mid.cpp'; fi` soundlib/libopenmpttest-Load_mo3.o: soundlib/Load_mo3.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_mo3.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_mo3.Tpo -c -o soundlib/libopenmpttest-Load_mo3.o `test -f 'soundlib/Load_mo3.cpp' || echo '$(srcdir)/'`soundlib/Load_mo3.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_mo3.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_mo3.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_mo3.cpp' object='soundlib/libopenmpttest-Load_mo3.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_mo3.o `test -f 'soundlib/Load_mo3.cpp' || echo '$(srcdir)/'`soundlib/Load_mo3.cpp soundlib/libopenmpttest-Load_mo3.obj: soundlib/Load_mo3.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_mo3.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_mo3.Tpo -c -o soundlib/libopenmpttest-Load_mo3.obj `if test -f 'soundlib/Load_mo3.cpp'; then $(CYGPATH_W) 'soundlib/Load_mo3.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_mo3.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_mo3.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_mo3.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_mo3.cpp' object='soundlib/libopenmpttest-Load_mo3.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_mo3.obj `if test -f 'soundlib/Load_mo3.cpp'; then $(CYGPATH_W) 'soundlib/Load_mo3.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_mo3.cpp'; fi` soundlib/libopenmpttest-Load_mod.o: soundlib/Load_mod.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_mod.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_mod.Tpo -c -o soundlib/libopenmpttest-Load_mod.o `test -f 'soundlib/Load_mod.cpp' || echo '$(srcdir)/'`soundlib/Load_mod.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_mod.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_mod.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_mod.cpp' object='soundlib/libopenmpttest-Load_mod.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_mod.o `test -f 'soundlib/Load_mod.cpp' || echo '$(srcdir)/'`soundlib/Load_mod.cpp soundlib/libopenmpttest-Load_mod.obj: soundlib/Load_mod.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_mod.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_mod.Tpo -c -o soundlib/libopenmpttest-Load_mod.obj `if test -f 'soundlib/Load_mod.cpp'; then $(CYGPATH_W) 'soundlib/Load_mod.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_mod.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_mod.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_mod.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_mod.cpp' object='soundlib/libopenmpttest-Load_mod.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_mod.obj `if test -f 'soundlib/Load_mod.cpp'; then $(CYGPATH_W) 'soundlib/Load_mod.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_mod.cpp'; fi` soundlib/libopenmpttest-Load_mt2.o: soundlib/Load_mt2.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_mt2.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_mt2.Tpo -c -o soundlib/libopenmpttest-Load_mt2.o `test -f 'soundlib/Load_mt2.cpp' || echo '$(srcdir)/'`soundlib/Load_mt2.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_mt2.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_mt2.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_mt2.cpp' object='soundlib/libopenmpttest-Load_mt2.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_mt2.o `test -f 'soundlib/Load_mt2.cpp' || echo '$(srcdir)/'`soundlib/Load_mt2.cpp soundlib/libopenmpttest-Load_mt2.obj: soundlib/Load_mt2.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_mt2.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_mt2.Tpo -c -o soundlib/libopenmpttest-Load_mt2.obj `if test -f 'soundlib/Load_mt2.cpp'; then $(CYGPATH_W) 'soundlib/Load_mt2.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_mt2.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_mt2.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_mt2.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_mt2.cpp' object='soundlib/libopenmpttest-Load_mt2.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_mt2.obj `if test -f 'soundlib/Load_mt2.cpp'; then $(CYGPATH_W) 'soundlib/Load_mt2.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_mt2.cpp'; fi` soundlib/libopenmpttest-Load_mtm.o: soundlib/Load_mtm.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_mtm.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_mtm.Tpo -c -o soundlib/libopenmpttest-Load_mtm.o `test -f 'soundlib/Load_mtm.cpp' || echo '$(srcdir)/'`soundlib/Load_mtm.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_mtm.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_mtm.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_mtm.cpp' object='soundlib/libopenmpttest-Load_mtm.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_mtm.o `test -f 'soundlib/Load_mtm.cpp' || echo '$(srcdir)/'`soundlib/Load_mtm.cpp soundlib/libopenmpttest-Load_mtm.obj: soundlib/Load_mtm.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_mtm.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_mtm.Tpo -c -o soundlib/libopenmpttest-Load_mtm.obj `if test -f 'soundlib/Load_mtm.cpp'; then $(CYGPATH_W) 'soundlib/Load_mtm.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_mtm.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_mtm.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_mtm.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_mtm.cpp' object='soundlib/libopenmpttest-Load_mtm.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_mtm.obj `if test -f 'soundlib/Load_mtm.cpp'; then $(CYGPATH_W) 'soundlib/Load_mtm.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_mtm.cpp'; fi` soundlib/libopenmpttest-Load_okt.o: soundlib/Load_okt.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_okt.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_okt.Tpo -c -o soundlib/libopenmpttest-Load_okt.o `test -f 'soundlib/Load_okt.cpp' || echo '$(srcdir)/'`soundlib/Load_okt.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_okt.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_okt.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_okt.cpp' object='soundlib/libopenmpttest-Load_okt.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_okt.o `test -f 'soundlib/Load_okt.cpp' || echo '$(srcdir)/'`soundlib/Load_okt.cpp soundlib/libopenmpttest-Load_okt.obj: soundlib/Load_okt.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_okt.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_okt.Tpo -c -o soundlib/libopenmpttest-Load_okt.obj `if test -f 'soundlib/Load_okt.cpp'; then $(CYGPATH_W) 'soundlib/Load_okt.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_okt.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_okt.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_okt.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_okt.cpp' object='soundlib/libopenmpttest-Load_okt.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_okt.obj `if test -f 'soundlib/Load_okt.cpp'; then $(CYGPATH_W) 'soundlib/Load_okt.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_okt.cpp'; fi` soundlib/libopenmpttest-Load_plm.o: soundlib/Load_plm.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_plm.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_plm.Tpo -c -o soundlib/libopenmpttest-Load_plm.o `test -f 'soundlib/Load_plm.cpp' || echo '$(srcdir)/'`soundlib/Load_plm.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_plm.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_plm.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_plm.cpp' object='soundlib/libopenmpttest-Load_plm.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_plm.o `test -f 'soundlib/Load_plm.cpp' || echo '$(srcdir)/'`soundlib/Load_plm.cpp soundlib/libopenmpttest-Load_plm.obj: soundlib/Load_plm.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_plm.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_plm.Tpo -c -o soundlib/libopenmpttest-Load_plm.obj `if test -f 'soundlib/Load_plm.cpp'; then $(CYGPATH_W) 'soundlib/Load_plm.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_plm.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_plm.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_plm.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_plm.cpp' object='soundlib/libopenmpttest-Load_plm.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_plm.obj `if test -f 'soundlib/Load_plm.cpp'; then $(CYGPATH_W) 'soundlib/Load_plm.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_plm.cpp'; fi` soundlib/libopenmpttest-Load_psm.o: soundlib/Load_psm.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_psm.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_psm.Tpo -c -o soundlib/libopenmpttest-Load_psm.o `test -f 'soundlib/Load_psm.cpp' || echo '$(srcdir)/'`soundlib/Load_psm.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_psm.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_psm.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_psm.cpp' object='soundlib/libopenmpttest-Load_psm.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_psm.o `test -f 'soundlib/Load_psm.cpp' || echo '$(srcdir)/'`soundlib/Load_psm.cpp soundlib/libopenmpttest-Load_psm.obj: soundlib/Load_psm.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_psm.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_psm.Tpo -c -o soundlib/libopenmpttest-Load_psm.obj `if test -f 'soundlib/Load_psm.cpp'; then $(CYGPATH_W) 'soundlib/Load_psm.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_psm.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_psm.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_psm.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_psm.cpp' object='soundlib/libopenmpttest-Load_psm.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_psm.obj `if test -f 'soundlib/Load_psm.cpp'; then $(CYGPATH_W) 'soundlib/Load_psm.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_psm.cpp'; fi` soundlib/libopenmpttest-Load_ptm.o: soundlib/Load_ptm.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_ptm.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_ptm.Tpo -c -o soundlib/libopenmpttest-Load_ptm.o `test -f 'soundlib/Load_ptm.cpp' || echo '$(srcdir)/'`soundlib/Load_ptm.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_ptm.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_ptm.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_ptm.cpp' object='soundlib/libopenmpttest-Load_ptm.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_ptm.o `test -f 'soundlib/Load_ptm.cpp' || echo '$(srcdir)/'`soundlib/Load_ptm.cpp soundlib/libopenmpttest-Load_ptm.obj: soundlib/Load_ptm.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_ptm.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_ptm.Tpo -c -o soundlib/libopenmpttest-Load_ptm.obj `if test -f 'soundlib/Load_ptm.cpp'; then $(CYGPATH_W) 'soundlib/Load_ptm.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_ptm.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_ptm.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_ptm.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_ptm.cpp' object='soundlib/libopenmpttest-Load_ptm.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_ptm.obj `if test -f 'soundlib/Load_ptm.cpp'; then $(CYGPATH_W) 'soundlib/Load_ptm.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_ptm.cpp'; fi` soundlib/libopenmpttest-Load_s3m.o: soundlib/Load_s3m.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_s3m.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_s3m.Tpo -c -o soundlib/libopenmpttest-Load_s3m.o `test -f 'soundlib/Load_s3m.cpp' || echo '$(srcdir)/'`soundlib/Load_s3m.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_s3m.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_s3m.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_s3m.cpp' object='soundlib/libopenmpttest-Load_s3m.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_s3m.o `test -f 'soundlib/Load_s3m.cpp' || echo '$(srcdir)/'`soundlib/Load_s3m.cpp soundlib/libopenmpttest-Load_s3m.obj: soundlib/Load_s3m.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_s3m.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_s3m.Tpo -c -o soundlib/libopenmpttest-Load_s3m.obj `if test -f 'soundlib/Load_s3m.cpp'; then $(CYGPATH_W) 'soundlib/Load_s3m.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_s3m.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_s3m.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_s3m.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_s3m.cpp' object='soundlib/libopenmpttest-Load_s3m.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_s3m.obj `if test -f 'soundlib/Load_s3m.cpp'; then $(CYGPATH_W) 'soundlib/Load_s3m.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_s3m.cpp'; fi` soundlib/libopenmpttest-Load_sfx.o: soundlib/Load_sfx.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_sfx.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_sfx.Tpo -c -o soundlib/libopenmpttest-Load_sfx.o `test -f 'soundlib/Load_sfx.cpp' || echo '$(srcdir)/'`soundlib/Load_sfx.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_sfx.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_sfx.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_sfx.cpp' object='soundlib/libopenmpttest-Load_sfx.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_sfx.o `test -f 'soundlib/Load_sfx.cpp' || echo '$(srcdir)/'`soundlib/Load_sfx.cpp soundlib/libopenmpttest-Load_sfx.obj: soundlib/Load_sfx.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_sfx.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_sfx.Tpo -c -o soundlib/libopenmpttest-Load_sfx.obj `if test -f 'soundlib/Load_sfx.cpp'; then $(CYGPATH_W) 'soundlib/Load_sfx.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_sfx.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_sfx.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_sfx.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_sfx.cpp' object='soundlib/libopenmpttest-Load_sfx.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_sfx.obj `if test -f 'soundlib/Load_sfx.cpp'; then $(CYGPATH_W) 'soundlib/Load_sfx.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_sfx.cpp'; fi` soundlib/libopenmpttest-Load_stm.o: soundlib/Load_stm.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_stm.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_stm.Tpo -c -o soundlib/libopenmpttest-Load_stm.o `test -f 'soundlib/Load_stm.cpp' || echo '$(srcdir)/'`soundlib/Load_stm.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_stm.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_stm.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_stm.cpp' object='soundlib/libopenmpttest-Load_stm.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_stm.o `test -f 'soundlib/Load_stm.cpp' || echo '$(srcdir)/'`soundlib/Load_stm.cpp soundlib/libopenmpttest-Load_stm.obj: soundlib/Load_stm.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_stm.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_stm.Tpo -c -o soundlib/libopenmpttest-Load_stm.obj `if test -f 'soundlib/Load_stm.cpp'; then $(CYGPATH_W) 'soundlib/Load_stm.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_stm.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_stm.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_stm.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_stm.cpp' object='soundlib/libopenmpttest-Load_stm.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_stm.obj `if test -f 'soundlib/Load_stm.cpp'; then $(CYGPATH_W) 'soundlib/Load_stm.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_stm.cpp'; fi` soundlib/libopenmpttest-Load_stp.o: soundlib/Load_stp.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_stp.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_stp.Tpo -c -o soundlib/libopenmpttest-Load_stp.o `test -f 'soundlib/Load_stp.cpp' || echo '$(srcdir)/'`soundlib/Load_stp.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_stp.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_stp.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_stp.cpp' object='soundlib/libopenmpttest-Load_stp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_stp.o `test -f 'soundlib/Load_stp.cpp' || echo '$(srcdir)/'`soundlib/Load_stp.cpp soundlib/libopenmpttest-Load_stp.obj: soundlib/Load_stp.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_stp.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_stp.Tpo -c -o soundlib/libopenmpttest-Load_stp.obj `if test -f 'soundlib/Load_stp.cpp'; then $(CYGPATH_W) 'soundlib/Load_stp.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_stp.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_stp.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_stp.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_stp.cpp' object='soundlib/libopenmpttest-Load_stp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_stp.obj `if test -f 'soundlib/Load_stp.cpp'; then $(CYGPATH_W) 'soundlib/Load_stp.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_stp.cpp'; fi` soundlib/libopenmpttest-Load_uax.o: soundlib/Load_uax.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_uax.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_uax.Tpo -c -o soundlib/libopenmpttest-Load_uax.o `test -f 'soundlib/Load_uax.cpp' || echo '$(srcdir)/'`soundlib/Load_uax.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_uax.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_uax.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_uax.cpp' object='soundlib/libopenmpttest-Load_uax.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_uax.o `test -f 'soundlib/Load_uax.cpp' || echo '$(srcdir)/'`soundlib/Load_uax.cpp soundlib/libopenmpttest-Load_uax.obj: soundlib/Load_uax.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_uax.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_uax.Tpo -c -o soundlib/libopenmpttest-Load_uax.obj `if test -f 'soundlib/Load_uax.cpp'; then $(CYGPATH_W) 'soundlib/Load_uax.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_uax.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_uax.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_uax.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_uax.cpp' object='soundlib/libopenmpttest-Load_uax.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_uax.obj `if test -f 'soundlib/Load_uax.cpp'; then $(CYGPATH_W) 'soundlib/Load_uax.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_uax.cpp'; fi` soundlib/libopenmpttest-Load_ult.o: soundlib/Load_ult.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_ult.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_ult.Tpo -c -o soundlib/libopenmpttest-Load_ult.o `test -f 'soundlib/Load_ult.cpp' || echo '$(srcdir)/'`soundlib/Load_ult.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_ult.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_ult.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_ult.cpp' object='soundlib/libopenmpttest-Load_ult.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_ult.o `test -f 'soundlib/Load_ult.cpp' || echo '$(srcdir)/'`soundlib/Load_ult.cpp soundlib/libopenmpttest-Load_ult.obj: soundlib/Load_ult.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_ult.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_ult.Tpo -c -o soundlib/libopenmpttest-Load_ult.obj `if test -f 'soundlib/Load_ult.cpp'; then $(CYGPATH_W) 'soundlib/Load_ult.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_ult.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_ult.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_ult.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_ult.cpp' object='soundlib/libopenmpttest-Load_ult.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_ult.obj `if test -f 'soundlib/Load_ult.cpp'; then $(CYGPATH_W) 'soundlib/Load_ult.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_ult.cpp'; fi` soundlib/libopenmpttest-Load_wav.o: soundlib/Load_wav.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_wav.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_wav.Tpo -c -o soundlib/libopenmpttest-Load_wav.o `test -f 'soundlib/Load_wav.cpp' || echo '$(srcdir)/'`soundlib/Load_wav.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_wav.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_wav.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_wav.cpp' object='soundlib/libopenmpttest-Load_wav.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_wav.o `test -f 'soundlib/Load_wav.cpp' || echo '$(srcdir)/'`soundlib/Load_wav.cpp soundlib/libopenmpttest-Load_wav.obj: soundlib/Load_wav.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_wav.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_wav.Tpo -c -o soundlib/libopenmpttest-Load_wav.obj `if test -f 'soundlib/Load_wav.cpp'; then $(CYGPATH_W) 'soundlib/Load_wav.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_wav.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_wav.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_wav.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_wav.cpp' object='soundlib/libopenmpttest-Load_wav.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_wav.obj `if test -f 'soundlib/Load_wav.cpp'; then $(CYGPATH_W) 'soundlib/Load_wav.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_wav.cpp'; fi` soundlib/libopenmpttest-Load_xm.o: soundlib/Load_xm.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_xm.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_xm.Tpo -c -o soundlib/libopenmpttest-Load_xm.o `test -f 'soundlib/Load_xm.cpp' || echo '$(srcdir)/'`soundlib/Load_xm.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_xm.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_xm.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_xm.cpp' object='soundlib/libopenmpttest-Load_xm.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_xm.o `test -f 'soundlib/Load_xm.cpp' || echo '$(srcdir)/'`soundlib/Load_xm.cpp soundlib/libopenmpttest-Load_xm.obj: soundlib/Load_xm.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Load_xm.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Load_xm.Tpo -c -o soundlib/libopenmpttest-Load_xm.obj `if test -f 'soundlib/Load_xm.cpp'; then $(CYGPATH_W) 'soundlib/Load_xm.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_xm.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Load_xm.Tpo soundlib/$(DEPDIR)/libopenmpttest-Load_xm.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Load_xm.cpp' object='soundlib/libopenmpttest-Load_xm.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Load_xm.obj `if test -f 'soundlib/Load_xm.cpp'; then $(CYGPATH_W) 'soundlib/Load_xm.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Load_xm.cpp'; fi` soundlib/libopenmpttest-Message.o: soundlib/Message.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Message.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Message.Tpo -c -o soundlib/libopenmpttest-Message.o `test -f 'soundlib/Message.cpp' || echo '$(srcdir)/'`soundlib/Message.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Message.Tpo soundlib/$(DEPDIR)/libopenmpttest-Message.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Message.cpp' object='soundlib/libopenmpttest-Message.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Message.o `test -f 'soundlib/Message.cpp' || echo '$(srcdir)/'`soundlib/Message.cpp soundlib/libopenmpttest-Message.obj: soundlib/Message.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Message.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Message.Tpo -c -o soundlib/libopenmpttest-Message.obj `if test -f 'soundlib/Message.cpp'; then $(CYGPATH_W) 'soundlib/Message.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Message.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Message.Tpo soundlib/$(DEPDIR)/libopenmpttest-Message.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Message.cpp' object='soundlib/libopenmpttest-Message.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Message.obj `if test -f 'soundlib/Message.cpp'; then $(CYGPATH_W) 'soundlib/Message.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Message.cpp'; fi` soundlib/libopenmpttest-MIDIEvents.o: soundlib/MIDIEvents.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-MIDIEvents.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-MIDIEvents.Tpo -c -o soundlib/libopenmpttest-MIDIEvents.o `test -f 'soundlib/MIDIEvents.cpp' || echo '$(srcdir)/'`soundlib/MIDIEvents.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-MIDIEvents.Tpo soundlib/$(DEPDIR)/libopenmpttest-MIDIEvents.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/MIDIEvents.cpp' object='soundlib/libopenmpttest-MIDIEvents.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-MIDIEvents.o `test -f 'soundlib/MIDIEvents.cpp' || echo '$(srcdir)/'`soundlib/MIDIEvents.cpp soundlib/libopenmpttest-MIDIEvents.obj: soundlib/MIDIEvents.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-MIDIEvents.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-MIDIEvents.Tpo -c -o soundlib/libopenmpttest-MIDIEvents.obj `if test -f 'soundlib/MIDIEvents.cpp'; then $(CYGPATH_W) 'soundlib/MIDIEvents.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/MIDIEvents.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-MIDIEvents.Tpo soundlib/$(DEPDIR)/libopenmpttest-MIDIEvents.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/MIDIEvents.cpp' object='soundlib/libopenmpttest-MIDIEvents.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-MIDIEvents.obj `if test -f 'soundlib/MIDIEvents.cpp'; then $(CYGPATH_W) 'soundlib/MIDIEvents.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/MIDIEvents.cpp'; fi` soundlib/libopenmpttest-MIDIMacros.o: soundlib/MIDIMacros.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-MIDIMacros.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-MIDIMacros.Tpo -c -o soundlib/libopenmpttest-MIDIMacros.o `test -f 'soundlib/MIDIMacros.cpp' || echo '$(srcdir)/'`soundlib/MIDIMacros.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-MIDIMacros.Tpo soundlib/$(DEPDIR)/libopenmpttest-MIDIMacros.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/MIDIMacros.cpp' object='soundlib/libopenmpttest-MIDIMacros.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-MIDIMacros.o `test -f 'soundlib/MIDIMacros.cpp' || echo '$(srcdir)/'`soundlib/MIDIMacros.cpp soundlib/libopenmpttest-MIDIMacros.obj: soundlib/MIDIMacros.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-MIDIMacros.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-MIDIMacros.Tpo -c -o soundlib/libopenmpttest-MIDIMacros.obj `if test -f 'soundlib/MIDIMacros.cpp'; then $(CYGPATH_W) 'soundlib/MIDIMacros.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/MIDIMacros.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-MIDIMacros.Tpo soundlib/$(DEPDIR)/libopenmpttest-MIDIMacros.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/MIDIMacros.cpp' object='soundlib/libopenmpttest-MIDIMacros.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-MIDIMacros.obj `if test -f 'soundlib/MIDIMacros.cpp'; then $(CYGPATH_W) 'soundlib/MIDIMacros.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/MIDIMacros.cpp'; fi` soundlib/libopenmpttest-MixerLoops.o: soundlib/MixerLoops.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-MixerLoops.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-MixerLoops.Tpo -c -o soundlib/libopenmpttest-MixerLoops.o `test -f 'soundlib/MixerLoops.cpp' || echo '$(srcdir)/'`soundlib/MixerLoops.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-MixerLoops.Tpo soundlib/$(DEPDIR)/libopenmpttest-MixerLoops.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/MixerLoops.cpp' object='soundlib/libopenmpttest-MixerLoops.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-MixerLoops.o `test -f 'soundlib/MixerLoops.cpp' || echo '$(srcdir)/'`soundlib/MixerLoops.cpp soundlib/libopenmpttest-MixerLoops.obj: soundlib/MixerLoops.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-MixerLoops.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-MixerLoops.Tpo -c -o soundlib/libopenmpttest-MixerLoops.obj `if test -f 'soundlib/MixerLoops.cpp'; then $(CYGPATH_W) 'soundlib/MixerLoops.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/MixerLoops.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-MixerLoops.Tpo soundlib/$(DEPDIR)/libopenmpttest-MixerLoops.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/MixerLoops.cpp' object='soundlib/libopenmpttest-MixerLoops.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-MixerLoops.obj `if test -f 'soundlib/MixerLoops.cpp'; then $(CYGPATH_W) 'soundlib/MixerLoops.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/MixerLoops.cpp'; fi` soundlib/libopenmpttest-MixerSettings.o: soundlib/MixerSettings.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-MixerSettings.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-MixerSettings.Tpo -c -o soundlib/libopenmpttest-MixerSettings.o `test -f 'soundlib/MixerSettings.cpp' || echo '$(srcdir)/'`soundlib/MixerSettings.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-MixerSettings.Tpo soundlib/$(DEPDIR)/libopenmpttest-MixerSettings.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/MixerSettings.cpp' object='soundlib/libopenmpttest-MixerSettings.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-MixerSettings.o `test -f 'soundlib/MixerSettings.cpp' || echo '$(srcdir)/'`soundlib/MixerSettings.cpp soundlib/libopenmpttest-MixerSettings.obj: soundlib/MixerSettings.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-MixerSettings.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-MixerSettings.Tpo -c -o soundlib/libopenmpttest-MixerSettings.obj `if test -f 'soundlib/MixerSettings.cpp'; then $(CYGPATH_W) 'soundlib/MixerSettings.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/MixerSettings.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-MixerSettings.Tpo soundlib/$(DEPDIR)/libopenmpttest-MixerSettings.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/MixerSettings.cpp' object='soundlib/libopenmpttest-MixerSettings.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-MixerSettings.obj `if test -f 'soundlib/MixerSettings.cpp'; then $(CYGPATH_W) 'soundlib/MixerSettings.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/MixerSettings.cpp'; fi` soundlib/libopenmpttest-MixFuncTable.o: soundlib/MixFuncTable.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-MixFuncTable.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-MixFuncTable.Tpo -c -o soundlib/libopenmpttest-MixFuncTable.o `test -f 'soundlib/MixFuncTable.cpp' || echo '$(srcdir)/'`soundlib/MixFuncTable.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-MixFuncTable.Tpo soundlib/$(DEPDIR)/libopenmpttest-MixFuncTable.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/MixFuncTable.cpp' object='soundlib/libopenmpttest-MixFuncTable.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-MixFuncTable.o `test -f 'soundlib/MixFuncTable.cpp' || echo '$(srcdir)/'`soundlib/MixFuncTable.cpp soundlib/libopenmpttest-MixFuncTable.obj: soundlib/MixFuncTable.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-MixFuncTable.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-MixFuncTable.Tpo -c -o soundlib/libopenmpttest-MixFuncTable.obj `if test -f 'soundlib/MixFuncTable.cpp'; then $(CYGPATH_W) 'soundlib/MixFuncTable.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/MixFuncTable.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-MixFuncTable.Tpo soundlib/$(DEPDIR)/libopenmpttest-MixFuncTable.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/MixFuncTable.cpp' object='soundlib/libopenmpttest-MixFuncTable.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-MixFuncTable.obj `if test -f 'soundlib/MixFuncTable.cpp'; then $(CYGPATH_W) 'soundlib/MixFuncTable.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/MixFuncTable.cpp'; fi` soundlib/libopenmpttest-ModChannel.o: soundlib/ModChannel.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-ModChannel.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-ModChannel.Tpo -c -o soundlib/libopenmpttest-ModChannel.o `test -f 'soundlib/ModChannel.cpp' || echo '$(srcdir)/'`soundlib/ModChannel.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-ModChannel.Tpo soundlib/$(DEPDIR)/libopenmpttest-ModChannel.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/ModChannel.cpp' object='soundlib/libopenmpttest-ModChannel.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-ModChannel.o `test -f 'soundlib/ModChannel.cpp' || echo '$(srcdir)/'`soundlib/ModChannel.cpp soundlib/libopenmpttest-ModChannel.obj: soundlib/ModChannel.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-ModChannel.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-ModChannel.Tpo -c -o soundlib/libopenmpttest-ModChannel.obj `if test -f 'soundlib/ModChannel.cpp'; then $(CYGPATH_W) 'soundlib/ModChannel.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/ModChannel.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-ModChannel.Tpo soundlib/$(DEPDIR)/libopenmpttest-ModChannel.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/ModChannel.cpp' object='soundlib/libopenmpttest-ModChannel.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-ModChannel.obj `if test -f 'soundlib/ModChannel.cpp'; then $(CYGPATH_W) 'soundlib/ModChannel.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/ModChannel.cpp'; fi` soundlib/libopenmpttest-modcommand.o: soundlib/modcommand.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-modcommand.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-modcommand.Tpo -c -o soundlib/libopenmpttest-modcommand.o `test -f 'soundlib/modcommand.cpp' || echo '$(srcdir)/'`soundlib/modcommand.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-modcommand.Tpo soundlib/$(DEPDIR)/libopenmpttest-modcommand.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/modcommand.cpp' object='soundlib/libopenmpttest-modcommand.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-modcommand.o `test -f 'soundlib/modcommand.cpp' || echo '$(srcdir)/'`soundlib/modcommand.cpp soundlib/libopenmpttest-modcommand.obj: soundlib/modcommand.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-modcommand.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-modcommand.Tpo -c -o soundlib/libopenmpttest-modcommand.obj `if test -f 'soundlib/modcommand.cpp'; then $(CYGPATH_W) 'soundlib/modcommand.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/modcommand.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-modcommand.Tpo soundlib/$(DEPDIR)/libopenmpttest-modcommand.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/modcommand.cpp' object='soundlib/libopenmpttest-modcommand.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-modcommand.obj `if test -f 'soundlib/modcommand.cpp'; then $(CYGPATH_W) 'soundlib/modcommand.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/modcommand.cpp'; fi` soundlib/libopenmpttest-ModInstrument.o: soundlib/ModInstrument.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-ModInstrument.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-ModInstrument.Tpo -c -o soundlib/libopenmpttest-ModInstrument.o `test -f 'soundlib/ModInstrument.cpp' || echo '$(srcdir)/'`soundlib/ModInstrument.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-ModInstrument.Tpo soundlib/$(DEPDIR)/libopenmpttest-ModInstrument.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/ModInstrument.cpp' object='soundlib/libopenmpttest-ModInstrument.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-ModInstrument.o `test -f 'soundlib/ModInstrument.cpp' || echo '$(srcdir)/'`soundlib/ModInstrument.cpp soundlib/libopenmpttest-ModInstrument.obj: soundlib/ModInstrument.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-ModInstrument.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-ModInstrument.Tpo -c -o soundlib/libopenmpttest-ModInstrument.obj `if test -f 'soundlib/ModInstrument.cpp'; then $(CYGPATH_W) 'soundlib/ModInstrument.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/ModInstrument.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-ModInstrument.Tpo soundlib/$(DEPDIR)/libopenmpttest-ModInstrument.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/ModInstrument.cpp' object='soundlib/libopenmpttest-ModInstrument.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-ModInstrument.obj `if test -f 'soundlib/ModInstrument.cpp'; then $(CYGPATH_W) 'soundlib/ModInstrument.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/ModInstrument.cpp'; fi` soundlib/libopenmpttest-ModSample.o: soundlib/ModSample.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-ModSample.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-ModSample.Tpo -c -o soundlib/libopenmpttest-ModSample.o `test -f 'soundlib/ModSample.cpp' || echo '$(srcdir)/'`soundlib/ModSample.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-ModSample.Tpo soundlib/$(DEPDIR)/libopenmpttest-ModSample.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/ModSample.cpp' object='soundlib/libopenmpttest-ModSample.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-ModSample.o `test -f 'soundlib/ModSample.cpp' || echo '$(srcdir)/'`soundlib/ModSample.cpp soundlib/libopenmpttest-ModSample.obj: soundlib/ModSample.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-ModSample.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-ModSample.Tpo -c -o soundlib/libopenmpttest-ModSample.obj `if test -f 'soundlib/ModSample.cpp'; then $(CYGPATH_W) 'soundlib/ModSample.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/ModSample.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-ModSample.Tpo soundlib/$(DEPDIR)/libopenmpttest-ModSample.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/ModSample.cpp' object='soundlib/libopenmpttest-ModSample.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-ModSample.obj `if test -f 'soundlib/ModSample.cpp'; then $(CYGPATH_W) 'soundlib/ModSample.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/ModSample.cpp'; fi` soundlib/libopenmpttest-ModSequence.o: soundlib/ModSequence.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-ModSequence.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-ModSequence.Tpo -c -o soundlib/libopenmpttest-ModSequence.o `test -f 'soundlib/ModSequence.cpp' || echo '$(srcdir)/'`soundlib/ModSequence.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-ModSequence.Tpo soundlib/$(DEPDIR)/libopenmpttest-ModSequence.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/ModSequence.cpp' object='soundlib/libopenmpttest-ModSequence.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-ModSequence.o `test -f 'soundlib/ModSequence.cpp' || echo '$(srcdir)/'`soundlib/ModSequence.cpp soundlib/libopenmpttest-ModSequence.obj: soundlib/ModSequence.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-ModSequence.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-ModSequence.Tpo -c -o soundlib/libopenmpttest-ModSequence.obj `if test -f 'soundlib/ModSequence.cpp'; then $(CYGPATH_W) 'soundlib/ModSequence.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/ModSequence.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-ModSequence.Tpo soundlib/$(DEPDIR)/libopenmpttest-ModSequence.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/ModSequence.cpp' object='soundlib/libopenmpttest-ModSequence.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-ModSequence.obj `if test -f 'soundlib/ModSequence.cpp'; then $(CYGPATH_W) 'soundlib/ModSequence.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/ModSequence.cpp'; fi` soundlib/libopenmpttest-modsmp_ctrl.o: soundlib/modsmp_ctrl.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-modsmp_ctrl.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-modsmp_ctrl.Tpo -c -o soundlib/libopenmpttest-modsmp_ctrl.o `test -f 'soundlib/modsmp_ctrl.cpp' || echo '$(srcdir)/'`soundlib/modsmp_ctrl.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-modsmp_ctrl.Tpo soundlib/$(DEPDIR)/libopenmpttest-modsmp_ctrl.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/modsmp_ctrl.cpp' object='soundlib/libopenmpttest-modsmp_ctrl.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-modsmp_ctrl.o `test -f 'soundlib/modsmp_ctrl.cpp' || echo '$(srcdir)/'`soundlib/modsmp_ctrl.cpp soundlib/libopenmpttest-modsmp_ctrl.obj: soundlib/modsmp_ctrl.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-modsmp_ctrl.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-modsmp_ctrl.Tpo -c -o soundlib/libopenmpttest-modsmp_ctrl.obj `if test -f 'soundlib/modsmp_ctrl.cpp'; then $(CYGPATH_W) 'soundlib/modsmp_ctrl.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/modsmp_ctrl.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-modsmp_ctrl.Tpo soundlib/$(DEPDIR)/libopenmpttest-modsmp_ctrl.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/modsmp_ctrl.cpp' object='soundlib/libopenmpttest-modsmp_ctrl.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-modsmp_ctrl.obj `if test -f 'soundlib/modsmp_ctrl.cpp'; then $(CYGPATH_W) 'soundlib/modsmp_ctrl.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/modsmp_ctrl.cpp'; fi` soundlib/libopenmpttest-mod_specifications.o: soundlib/mod_specifications.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-mod_specifications.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-mod_specifications.Tpo -c -o soundlib/libopenmpttest-mod_specifications.o `test -f 'soundlib/mod_specifications.cpp' || echo '$(srcdir)/'`soundlib/mod_specifications.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-mod_specifications.Tpo soundlib/$(DEPDIR)/libopenmpttest-mod_specifications.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/mod_specifications.cpp' object='soundlib/libopenmpttest-mod_specifications.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-mod_specifications.o `test -f 'soundlib/mod_specifications.cpp' || echo '$(srcdir)/'`soundlib/mod_specifications.cpp soundlib/libopenmpttest-mod_specifications.obj: soundlib/mod_specifications.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-mod_specifications.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-mod_specifications.Tpo -c -o soundlib/libopenmpttest-mod_specifications.obj `if test -f 'soundlib/mod_specifications.cpp'; then $(CYGPATH_W) 'soundlib/mod_specifications.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/mod_specifications.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-mod_specifications.Tpo soundlib/$(DEPDIR)/libopenmpttest-mod_specifications.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/mod_specifications.cpp' object='soundlib/libopenmpttest-mod_specifications.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-mod_specifications.obj `if test -f 'soundlib/mod_specifications.cpp'; then $(CYGPATH_W) 'soundlib/mod_specifications.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/mod_specifications.cpp'; fi` soundlib/libopenmpttest-MPEGFrame.o: soundlib/MPEGFrame.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-MPEGFrame.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-MPEGFrame.Tpo -c -o soundlib/libopenmpttest-MPEGFrame.o `test -f 'soundlib/MPEGFrame.cpp' || echo '$(srcdir)/'`soundlib/MPEGFrame.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-MPEGFrame.Tpo soundlib/$(DEPDIR)/libopenmpttest-MPEGFrame.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/MPEGFrame.cpp' object='soundlib/libopenmpttest-MPEGFrame.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-MPEGFrame.o `test -f 'soundlib/MPEGFrame.cpp' || echo '$(srcdir)/'`soundlib/MPEGFrame.cpp soundlib/libopenmpttest-MPEGFrame.obj: soundlib/MPEGFrame.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-MPEGFrame.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-MPEGFrame.Tpo -c -o soundlib/libopenmpttest-MPEGFrame.obj `if test -f 'soundlib/MPEGFrame.cpp'; then $(CYGPATH_W) 'soundlib/MPEGFrame.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/MPEGFrame.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-MPEGFrame.Tpo soundlib/$(DEPDIR)/libopenmpttest-MPEGFrame.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/MPEGFrame.cpp' object='soundlib/libopenmpttest-MPEGFrame.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-MPEGFrame.obj `if test -f 'soundlib/MPEGFrame.cpp'; then $(CYGPATH_W) 'soundlib/MPEGFrame.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/MPEGFrame.cpp'; fi` soundlib/libopenmpttest-OggStream.o: soundlib/OggStream.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-OggStream.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-OggStream.Tpo -c -o soundlib/libopenmpttest-OggStream.o `test -f 'soundlib/OggStream.cpp' || echo '$(srcdir)/'`soundlib/OggStream.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-OggStream.Tpo soundlib/$(DEPDIR)/libopenmpttest-OggStream.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/OggStream.cpp' object='soundlib/libopenmpttest-OggStream.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-OggStream.o `test -f 'soundlib/OggStream.cpp' || echo '$(srcdir)/'`soundlib/OggStream.cpp soundlib/libopenmpttest-OggStream.obj: soundlib/OggStream.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-OggStream.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-OggStream.Tpo -c -o soundlib/libopenmpttest-OggStream.obj `if test -f 'soundlib/OggStream.cpp'; then $(CYGPATH_W) 'soundlib/OggStream.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/OggStream.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-OggStream.Tpo soundlib/$(DEPDIR)/libopenmpttest-OggStream.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/OggStream.cpp' object='soundlib/libopenmpttest-OggStream.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-OggStream.obj `if test -f 'soundlib/OggStream.cpp'; then $(CYGPATH_W) 'soundlib/OggStream.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/OggStream.cpp'; fi` soundlib/libopenmpttest-Paula.o: soundlib/Paula.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Paula.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Paula.Tpo -c -o soundlib/libopenmpttest-Paula.o `test -f 'soundlib/Paula.cpp' || echo '$(srcdir)/'`soundlib/Paula.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Paula.Tpo soundlib/$(DEPDIR)/libopenmpttest-Paula.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Paula.cpp' object='soundlib/libopenmpttest-Paula.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Paula.o `test -f 'soundlib/Paula.cpp' || echo '$(srcdir)/'`soundlib/Paula.cpp soundlib/libopenmpttest-Paula.obj: soundlib/Paula.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Paula.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Paula.Tpo -c -o soundlib/libopenmpttest-Paula.obj `if test -f 'soundlib/Paula.cpp'; then $(CYGPATH_W) 'soundlib/Paula.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Paula.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Paula.Tpo soundlib/$(DEPDIR)/libopenmpttest-Paula.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Paula.cpp' object='soundlib/libopenmpttest-Paula.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Paula.obj `if test -f 'soundlib/Paula.cpp'; then $(CYGPATH_W) 'soundlib/Paula.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Paula.cpp'; fi` soundlib/libopenmpttest-patternContainer.o: soundlib/patternContainer.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-patternContainer.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-patternContainer.Tpo -c -o soundlib/libopenmpttest-patternContainer.o `test -f 'soundlib/patternContainer.cpp' || echo '$(srcdir)/'`soundlib/patternContainer.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-patternContainer.Tpo soundlib/$(DEPDIR)/libopenmpttest-patternContainer.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/patternContainer.cpp' object='soundlib/libopenmpttest-patternContainer.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-patternContainer.o `test -f 'soundlib/patternContainer.cpp' || echo '$(srcdir)/'`soundlib/patternContainer.cpp soundlib/libopenmpttest-patternContainer.obj: soundlib/patternContainer.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-patternContainer.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-patternContainer.Tpo -c -o soundlib/libopenmpttest-patternContainer.obj `if test -f 'soundlib/patternContainer.cpp'; then $(CYGPATH_W) 'soundlib/patternContainer.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/patternContainer.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-patternContainer.Tpo soundlib/$(DEPDIR)/libopenmpttest-patternContainer.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/patternContainer.cpp' object='soundlib/libopenmpttest-patternContainer.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-patternContainer.obj `if test -f 'soundlib/patternContainer.cpp'; then $(CYGPATH_W) 'soundlib/patternContainer.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/patternContainer.cpp'; fi` soundlib/libopenmpttest-pattern.o: soundlib/pattern.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-pattern.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-pattern.Tpo -c -o soundlib/libopenmpttest-pattern.o `test -f 'soundlib/pattern.cpp' || echo '$(srcdir)/'`soundlib/pattern.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-pattern.Tpo soundlib/$(DEPDIR)/libopenmpttest-pattern.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/pattern.cpp' object='soundlib/libopenmpttest-pattern.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-pattern.o `test -f 'soundlib/pattern.cpp' || echo '$(srcdir)/'`soundlib/pattern.cpp soundlib/libopenmpttest-pattern.obj: soundlib/pattern.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-pattern.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-pattern.Tpo -c -o soundlib/libopenmpttest-pattern.obj `if test -f 'soundlib/pattern.cpp'; then $(CYGPATH_W) 'soundlib/pattern.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/pattern.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-pattern.Tpo soundlib/$(DEPDIR)/libopenmpttest-pattern.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/pattern.cpp' object='soundlib/libopenmpttest-pattern.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-pattern.obj `if test -f 'soundlib/pattern.cpp'; then $(CYGPATH_W) 'soundlib/pattern.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/pattern.cpp'; fi` soundlib/libopenmpttest-RowVisitor.o: soundlib/RowVisitor.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-RowVisitor.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-RowVisitor.Tpo -c -o soundlib/libopenmpttest-RowVisitor.o `test -f 'soundlib/RowVisitor.cpp' || echo '$(srcdir)/'`soundlib/RowVisitor.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-RowVisitor.Tpo soundlib/$(DEPDIR)/libopenmpttest-RowVisitor.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/RowVisitor.cpp' object='soundlib/libopenmpttest-RowVisitor.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-RowVisitor.o `test -f 'soundlib/RowVisitor.cpp' || echo '$(srcdir)/'`soundlib/RowVisitor.cpp soundlib/libopenmpttest-RowVisitor.obj: soundlib/RowVisitor.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-RowVisitor.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-RowVisitor.Tpo -c -o soundlib/libopenmpttest-RowVisitor.obj `if test -f 'soundlib/RowVisitor.cpp'; then $(CYGPATH_W) 'soundlib/RowVisitor.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/RowVisitor.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-RowVisitor.Tpo soundlib/$(DEPDIR)/libopenmpttest-RowVisitor.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/RowVisitor.cpp' object='soundlib/libopenmpttest-RowVisitor.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-RowVisitor.obj `if test -f 'soundlib/RowVisitor.cpp'; then $(CYGPATH_W) 'soundlib/RowVisitor.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/RowVisitor.cpp'; fi` soundlib/libopenmpttest-S3MTools.o: soundlib/S3MTools.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-S3MTools.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-S3MTools.Tpo -c -o soundlib/libopenmpttest-S3MTools.o `test -f 'soundlib/S3MTools.cpp' || echo '$(srcdir)/'`soundlib/S3MTools.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-S3MTools.Tpo soundlib/$(DEPDIR)/libopenmpttest-S3MTools.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/S3MTools.cpp' object='soundlib/libopenmpttest-S3MTools.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-S3MTools.o `test -f 'soundlib/S3MTools.cpp' || echo '$(srcdir)/'`soundlib/S3MTools.cpp soundlib/libopenmpttest-S3MTools.obj: soundlib/S3MTools.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-S3MTools.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-S3MTools.Tpo -c -o soundlib/libopenmpttest-S3MTools.obj `if test -f 'soundlib/S3MTools.cpp'; then $(CYGPATH_W) 'soundlib/S3MTools.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/S3MTools.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-S3MTools.Tpo soundlib/$(DEPDIR)/libopenmpttest-S3MTools.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/S3MTools.cpp' object='soundlib/libopenmpttest-S3MTools.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-S3MTools.obj `if test -f 'soundlib/S3MTools.cpp'; then $(CYGPATH_W) 'soundlib/S3MTools.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/S3MTools.cpp'; fi` soundlib/libopenmpttest-SampleFormats.o: soundlib/SampleFormats.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-SampleFormats.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-SampleFormats.Tpo -c -o soundlib/libopenmpttest-SampleFormats.o `test -f 'soundlib/SampleFormats.cpp' || echo '$(srcdir)/'`soundlib/SampleFormats.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-SampleFormats.Tpo soundlib/$(DEPDIR)/libopenmpttest-SampleFormats.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/SampleFormats.cpp' object='soundlib/libopenmpttest-SampleFormats.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-SampleFormats.o `test -f 'soundlib/SampleFormats.cpp' || echo '$(srcdir)/'`soundlib/SampleFormats.cpp soundlib/libopenmpttest-SampleFormats.obj: soundlib/SampleFormats.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-SampleFormats.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-SampleFormats.Tpo -c -o soundlib/libopenmpttest-SampleFormats.obj `if test -f 'soundlib/SampleFormats.cpp'; then $(CYGPATH_W) 'soundlib/SampleFormats.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/SampleFormats.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-SampleFormats.Tpo soundlib/$(DEPDIR)/libopenmpttest-SampleFormats.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/SampleFormats.cpp' object='soundlib/libopenmpttest-SampleFormats.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-SampleFormats.obj `if test -f 'soundlib/SampleFormats.cpp'; then $(CYGPATH_W) 'soundlib/SampleFormats.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/SampleFormats.cpp'; fi` soundlib/libopenmpttest-SampleFormatFLAC.o: soundlib/SampleFormatFLAC.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-SampleFormatFLAC.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-SampleFormatFLAC.Tpo -c -o soundlib/libopenmpttest-SampleFormatFLAC.o `test -f 'soundlib/SampleFormatFLAC.cpp' || echo '$(srcdir)/'`soundlib/SampleFormatFLAC.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-SampleFormatFLAC.Tpo soundlib/$(DEPDIR)/libopenmpttest-SampleFormatFLAC.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/SampleFormatFLAC.cpp' object='soundlib/libopenmpttest-SampleFormatFLAC.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-SampleFormatFLAC.o `test -f 'soundlib/SampleFormatFLAC.cpp' || echo '$(srcdir)/'`soundlib/SampleFormatFLAC.cpp soundlib/libopenmpttest-SampleFormatFLAC.obj: soundlib/SampleFormatFLAC.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-SampleFormatFLAC.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-SampleFormatFLAC.Tpo -c -o soundlib/libopenmpttest-SampleFormatFLAC.obj `if test -f 'soundlib/SampleFormatFLAC.cpp'; then $(CYGPATH_W) 'soundlib/SampleFormatFLAC.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/SampleFormatFLAC.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-SampleFormatFLAC.Tpo soundlib/$(DEPDIR)/libopenmpttest-SampleFormatFLAC.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/SampleFormatFLAC.cpp' object='soundlib/libopenmpttest-SampleFormatFLAC.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-SampleFormatFLAC.obj `if test -f 'soundlib/SampleFormatFLAC.cpp'; then $(CYGPATH_W) 'soundlib/SampleFormatFLAC.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/SampleFormatFLAC.cpp'; fi` soundlib/libopenmpttest-SampleFormatMediaFoundation.o: soundlib/SampleFormatMediaFoundation.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-SampleFormatMediaFoundation.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-SampleFormatMediaFoundation.Tpo -c -o soundlib/libopenmpttest-SampleFormatMediaFoundation.o `test -f 'soundlib/SampleFormatMediaFoundation.cpp' || echo '$(srcdir)/'`soundlib/SampleFormatMediaFoundation.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-SampleFormatMediaFoundation.Tpo soundlib/$(DEPDIR)/libopenmpttest-SampleFormatMediaFoundation.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/SampleFormatMediaFoundation.cpp' object='soundlib/libopenmpttest-SampleFormatMediaFoundation.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-SampleFormatMediaFoundation.o `test -f 'soundlib/SampleFormatMediaFoundation.cpp' || echo '$(srcdir)/'`soundlib/SampleFormatMediaFoundation.cpp soundlib/libopenmpttest-SampleFormatMediaFoundation.obj: soundlib/SampleFormatMediaFoundation.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-SampleFormatMediaFoundation.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-SampleFormatMediaFoundation.Tpo -c -o soundlib/libopenmpttest-SampleFormatMediaFoundation.obj `if test -f 'soundlib/SampleFormatMediaFoundation.cpp'; then $(CYGPATH_W) 'soundlib/SampleFormatMediaFoundation.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/SampleFormatMediaFoundation.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-SampleFormatMediaFoundation.Tpo soundlib/$(DEPDIR)/libopenmpttest-SampleFormatMediaFoundation.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/SampleFormatMediaFoundation.cpp' object='soundlib/libopenmpttest-SampleFormatMediaFoundation.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-SampleFormatMediaFoundation.obj `if test -f 'soundlib/SampleFormatMediaFoundation.cpp'; then $(CYGPATH_W) 'soundlib/SampleFormatMediaFoundation.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/SampleFormatMediaFoundation.cpp'; fi` soundlib/libopenmpttest-SampleFormatMP3.o: soundlib/SampleFormatMP3.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-SampleFormatMP3.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-SampleFormatMP3.Tpo -c -o soundlib/libopenmpttest-SampleFormatMP3.o `test -f 'soundlib/SampleFormatMP3.cpp' || echo '$(srcdir)/'`soundlib/SampleFormatMP3.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-SampleFormatMP3.Tpo soundlib/$(DEPDIR)/libopenmpttest-SampleFormatMP3.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/SampleFormatMP3.cpp' object='soundlib/libopenmpttest-SampleFormatMP3.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-SampleFormatMP3.o `test -f 'soundlib/SampleFormatMP3.cpp' || echo '$(srcdir)/'`soundlib/SampleFormatMP3.cpp soundlib/libopenmpttest-SampleFormatMP3.obj: soundlib/SampleFormatMP3.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-SampleFormatMP3.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-SampleFormatMP3.Tpo -c -o soundlib/libopenmpttest-SampleFormatMP3.obj `if test -f 'soundlib/SampleFormatMP3.cpp'; then $(CYGPATH_W) 'soundlib/SampleFormatMP3.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/SampleFormatMP3.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-SampleFormatMP3.Tpo soundlib/$(DEPDIR)/libopenmpttest-SampleFormatMP3.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/SampleFormatMP3.cpp' object='soundlib/libopenmpttest-SampleFormatMP3.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-SampleFormatMP3.obj `if test -f 'soundlib/SampleFormatMP3.cpp'; then $(CYGPATH_W) 'soundlib/SampleFormatMP3.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/SampleFormatMP3.cpp'; fi` soundlib/libopenmpttest-SampleFormatOpus.o: soundlib/SampleFormatOpus.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-SampleFormatOpus.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-SampleFormatOpus.Tpo -c -o soundlib/libopenmpttest-SampleFormatOpus.o `test -f 'soundlib/SampleFormatOpus.cpp' || echo '$(srcdir)/'`soundlib/SampleFormatOpus.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-SampleFormatOpus.Tpo soundlib/$(DEPDIR)/libopenmpttest-SampleFormatOpus.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/SampleFormatOpus.cpp' object='soundlib/libopenmpttest-SampleFormatOpus.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-SampleFormatOpus.o `test -f 'soundlib/SampleFormatOpus.cpp' || echo '$(srcdir)/'`soundlib/SampleFormatOpus.cpp soundlib/libopenmpttest-SampleFormatOpus.obj: soundlib/SampleFormatOpus.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-SampleFormatOpus.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-SampleFormatOpus.Tpo -c -o soundlib/libopenmpttest-SampleFormatOpus.obj `if test -f 'soundlib/SampleFormatOpus.cpp'; then $(CYGPATH_W) 'soundlib/SampleFormatOpus.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/SampleFormatOpus.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-SampleFormatOpus.Tpo soundlib/$(DEPDIR)/libopenmpttest-SampleFormatOpus.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/SampleFormatOpus.cpp' object='soundlib/libopenmpttest-SampleFormatOpus.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-SampleFormatOpus.obj `if test -f 'soundlib/SampleFormatOpus.cpp'; then $(CYGPATH_W) 'soundlib/SampleFormatOpus.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/SampleFormatOpus.cpp'; fi` soundlib/libopenmpttest-SampleFormatVorbis.o: soundlib/SampleFormatVorbis.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-SampleFormatVorbis.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-SampleFormatVorbis.Tpo -c -o soundlib/libopenmpttest-SampleFormatVorbis.o `test -f 'soundlib/SampleFormatVorbis.cpp' || echo '$(srcdir)/'`soundlib/SampleFormatVorbis.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-SampleFormatVorbis.Tpo soundlib/$(DEPDIR)/libopenmpttest-SampleFormatVorbis.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/SampleFormatVorbis.cpp' object='soundlib/libopenmpttest-SampleFormatVorbis.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-SampleFormatVorbis.o `test -f 'soundlib/SampleFormatVorbis.cpp' || echo '$(srcdir)/'`soundlib/SampleFormatVorbis.cpp soundlib/libopenmpttest-SampleFormatVorbis.obj: soundlib/SampleFormatVorbis.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-SampleFormatVorbis.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-SampleFormatVorbis.Tpo -c -o soundlib/libopenmpttest-SampleFormatVorbis.obj `if test -f 'soundlib/SampleFormatVorbis.cpp'; then $(CYGPATH_W) 'soundlib/SampleFormatVorbis.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/SampleFormatVorbis.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-SampleFormatVorbis.Tpo soundlib/$(DEPDIR)/libopenmpttest-SampleFormatVorbis.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/SampleFormatVorbis.cpp' object='soundlib/libopenmpttest-SampleFormatVorbis.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-SampleFormatVorbis.obj `if test -f 'soundlib/SampleFormatVorbis.cpp'; then $(CYGPATH_W) 'soundlib/SampleFormatVorbis.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/SampleFormatVorbis.cpp'; fi` soundlib/libopenmpttest-SampleIO.o: soundlib/SampleIO.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-SampleIO.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-SampleIO.Tpo -c -o soundlib/libopenmpttest-SampleIO.o `test -f 'soundlib/SampleIO.cpp' || echo '$(srcdir)/'`soundlib/SampleIO.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-SampleIO.Tpo soundlib/$(DEPDIR)/libopenmpttest-SampleIO.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/SampleIO.cpp' object='soundlib/libopenmpttest-SampleIO.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-SampleIO.o `test -f 'soundlib/SampleIO.cpp' || echo '$(srcdir)/'`soundlib/SampleIO.cpp soundlib/libopenmpttest-SampleIO.obj: soundlib/SampleIO.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-SampleIO.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-SampleIO.Tpo -c -o soundlib/libopenmpttest-SampleIO.obj `if test -f 'soundlib/SampleIO.cpp'; then $(CYGPATH_W) 'soundlib/SampleIO.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/SampleIO.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-SampleIO.Tpo soundlib/$(DEPDIR)/libopenmpttest-SampleIO.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/SampleIO.cpp' object='soundlib/libopenmpttest-SampleIO.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-SampleIO.obj `if test -f 'soundlib/SampleIO.cpp'; then $(CYGPATH_W) 'soundlib/SampleIO.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/SampleIO.cpp'; fi` soundlib/libopenmpttest-Sndfile.o: soundlib/Sndfile.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Sndfile.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Sndfile.Tpo -c -o soundlib/libopenmpttest-Sndfile.o `test -f 'soundlib/Sndfile.cpp' || echo '$(srcdir)/'`soundlib/Sndfile.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Sndfile.Tpo soundlib/$(DEPDIR)/libopenmpttest-Sndfile.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Sndfile.cpp' object='soundlib/libopenmpttest-Sndfile.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Sndfile.o `test -f 'soundlib/Sndfile.cpp' || echo '$(srcdir)/'`soundlib/Sndfile.cpp soundlib/libopenmpttest-Sndfile.obj: soundlib/Sndfile.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Sndfile.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Sndfile.Tpo -c -o soundlib/libopenmpttest-Sndfile.obj `if test -f 'soundlib/Sndfile.cpp'; then $(CYGPATH_W) 'soundlib/Sndfile.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Sndfile.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Sndfile.Tpo soundlib/$(DEPDIR)/libopenmpttest-Sndfile.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Sndfile.cpp' object='soundlib/libopenmpttest-Sndfile.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Sndfile.obj `if test -f 'soundlib/Sndfile.cpp'; then $(CYGPATH_W) 'soundlib/Sndfile.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Sndfile.cpp'; fi` soundlib/libopenmpttest-Snd_flt.o: soundlib/Snd_flt.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Snd_flt.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Snd_flt.Tpo -c -o soundlib/libopenmpttest-Snd_flt.o `test -f 'soundlib/Snd_flt.cpp' || echo '$(srcdir)/'`soundlib/Snd_flt.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Snd_flt.Tpo soundlib/$(DEPDIR)/libopenmpttest-Snd_flt.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Snd_flt.cpp' object='soundlib/libopenmpttest-Snd_flt.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Snd_flt.o `test -f 'soundlib/Snd_flt.cpp' || echo '$(srcdir)/'`soundlib/Snd_flt.cpp soundlib/libopenmpttest-Snd_flt.obj: soundlib/Snd_flt.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Snd_flt.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Snd_flt.Tpo -c -o soundlib/libopenmpttest-Snd_flt.obj `if test -f 'soundlib/Snd_flt.cpp'; then $(CYGPATH_W) 'soundlib/Snd_flt.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Snd_flt.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Snd_flt.Tpo soundlib/$(DEPDIR)/libopenmpttest-Snd_flt.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Snd_flt.cpp' object='soundlib/libopenmpttest-Snd_flt.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Snd_flt.obj `if test -f 'soundlib/Snd_flt.cpp'; then $(CYGPATH_W) 'soundlib/Snd_flt.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Snd_flt.cpp'; fi` soundlib/libopenmpttest-Snd_fx.o: soundlib/Snd_fx.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Snd_fx.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Snd_fx.Tpo -c -o soundlib/libopenmpttest-Snd_fx.o `test -f 'soundlib/Snd_fx.cpp' || echo '$(srcdir)/'`soundlib/Snd_fx.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Snd_fx.Tpo soundlib/$(DEPDIR)/libopenmpttest-Snd_fx.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Snd_fx.cpp' object='soundlib/libopenmpttest-Snd_fx.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Snd_fx.o `test -f 'soundlib/Snd_fx.cpp' || echo '$(srcdir)/'`soundlib/Snd_fx.cpp soundlib/libopenmpttest-Snd_fx.obj: soundlib/Snd_fx.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Snd_fx.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Snd_fx.Tpo -c -o soundlib/libopenmpttest-Snd_fx.obj `if test -f 'soundlib/Snd_fx.cpp'; then $(CYGPATH_W) 'soundlib/Snd_fx.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Snd_fx.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Snd_fx.Tpo soundlib/$(DEPDIR)/libopenmpttest-Snd_fx.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Snd_fx.cpp' object='soundlib/libopenmpttest-Snd_fx.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Snd_fx.obj `if test -f 'soundlib/Snd_fx.cpp'; then $(CYGPATH_W) 'soundlib/Snd_fx.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Snd_fx.cpp'; fi` soundlib/libopenmpttest-Sndmix.o: soundlib/Sndmix.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Sndmix.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Sndmix.Tpo -c -o soundlib/libopenmpttest-Sndmix.o `test -f 'soundlib/Sndmix.cpp' || echo '$(srcdir)/'`soundlib/Sndmix.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Sndmix.Tpo soundlib/$(DEPDIR)/libopenmpttest-Sndmix.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Sndmix.cpp' object='soundlib/libopenmpttest-Sndmix.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Sndmix.o `test -f 'soundlib/Sndmix.cpp' || echo '$(srcdir)/'`soundlib/Sndmix.cpp soundlib/libopenmpttest-Sndmix.obj: soundlib/Sndmix.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Sndmix.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Sndmix.Tpo -c -o soundlib/libopenmpttest-Sndmix.obj `if test -f 'soundlib/Sndmix.cpp'; then $(CYGPATH_W) 'soundlib/Sndmix.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Sndmix.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Sndmix.Tpo soundlib/$(DEPDIR)/libopenmpttest-Sndmix.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Sndmix.cpp' object='soundlib/libopenmpttest-Sndmix.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Sndmix.obj `if test -f 'soundlib/Sndmix.cpp'; then $(CYGPATH_W) 'soundlib/Sndmix.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Sndmix.cpp'; fi` soundlib/libopenmpttest-SoundFilePlayConfig.o: soundlib/SoundFilePlayConfig.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-SoundFilePlayConfig.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-SoundFilePlayConfig.Tpo -c -o soundlib/libopenmpttest-SoundFilePlayConfig.o `test -f 'soundlib/SoundFilePlayConfig.cpp' || echo '$(srcdir)/'`soundlib/SoundFilePlayConfig.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-SoundFilePlayConfig.Tpo soundlib/$(DEPDIR)/libopenmpttest-SoundFilePlayConfig.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/SoundFilePlayConfig.cpp' object='soundlib/libopenmpttest-SoundFilePlayConfig.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-SoundFilePlayConfig.o `test -f 'soundlib/SoundFilePlayConfig.cpp' || echo '$(srcdir)/'`soundlib/SoundFilePlayConfig.cpp soundlib/libopenmpttest-SoundFilePlayConfig.obj: soundlib/SoundFilePlayConfig.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-SoundFilePlayConfig.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-SoundFilePlayConfig.Tpo -c -o soundlib/libopenmpttest-SoundFilePlayConfig.obj `if test -f 'soundlib/SoundFilePlayConfig.cpp'; then $(CYGPATH_W) 'soundlib/SoundFilePlayConfig.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/SoundFilePlayConfig.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-SoundFilePlayConfig.Tpo soundlib/$(DEPDIR)/libopenmpttest-SoundFilePlayConfig.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/SoundFilePlayConfig.cpp' object='soundlib/libopenmpttest-SoundFilePlayConfig.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-SoundFilePlayConfig.obj `if test -f 'soundlib/SoundFilePlayConfig.cpp'; then $(CYGPATH_W) 'soundlib/SoundFilePlayConfig.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/SoundFilePlayConfig.cpp'; fi` soundlib/libopenmpttest-Tables.o: soundlib/Tables.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Tables.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Tables.Tpo -c -o soundlib/libopenmpttest-Tables.o `test -f 'soundlib/Tables.cpp' || echo '$(srcdir)/'`soundlib/Tables.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Tables.Tpo soundlib/$(DEPDIR)/libopenmpttest-Tables.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Tables.cpp' object='soundlib/libopenmpttest-Tables.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Tables.o `test -f 'soundlib/Tables.cpp' || echo '$(srcdir)/'`soundlib/Tables.cpp soundlib/libopenmpttest-Tables.obj: soundlib/Tables.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Tables.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Tables.Tpo -c -o soundlib/libopenmpttest-Tables.obj `if test -f 'soundlib/Tables.cpp'; then $(CYGPATH_W) 'soundlib/Tables.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Tables.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Tables.Tpo soundlib/$(DEPDIR)/libopenmpttest-Tables.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Tables.cpp' object='soundlib/libopenmpttest-Tables.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Tables.obj `if test -f 'soundlib/Tables.cpp'; then $(CYGPATH_W) 'soundlib/Tables.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Tables.cpp'; fi` soundlib/libopenmpttest-Tagging.o: soundlib/Tagging.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Tagging.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Tagging.Tpo -c -o soundlib/libopenmpttest-Tagging.o `test -f 'soundlib/Tagging.cpp' || echo '$(srcdir)/'`soundlib/Tagging.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Tagging.Tpo soundlib/$(DEPDIR)/libopenmpttest-Tagging.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Tagging.cpp' object='soundlib/libopenmpttest-Tagging.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Tagging.o `test -f 'soundlib/Tagging.cpp' || echo '$(srcdir)/'`soundlib/Tagging.cpp soundlib/libopenmpttest-Tagging.obj: soundlib/Tagging.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-Tagging.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-Tagging.Tpo -c -o soundlib/libopenmpttest-Tagging.obj `if test -f 'soundlib/Tagging.cpp'; then $(CYGPATH_W) 'soundlib/Tagging.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Tagging.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-Tagging.Tpo soundlib/$(DEPDIR)/libopenmpttest-Tagging.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/Tagging.cpp' object='soundlib/libopenmpttest-Tagging.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-Tagging.obj `if test -f 'soundlib/Tagging.cpp'; then $(CYGPATH_W) 'soundlib/Tagging.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/Tagging.cpp'; fi` soundlib/libopenmpttest-tuningbase.o: soundlib/tuningbase.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-tuningbase.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-tuningbase.Tpo -c -o soundlib/libopenmpttest-tuningbase.o `test -f 'soundlib/tuningbase.cpp' || echo '$(srcdir)/'`soundlib/tuningbase.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-tuningbase.Tpo soundlib/$(DEPDIR)/libopenmpttest-tuningbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/tuningbase.cpp' object='soundlib/libopenmpttest-tuningbase.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-tuningbase.o `test -f 'soundlib/tuningbase.cpp' || echo '$(srcdir)/'`soundlib/tuningbase.cpp soundlib/libopenmpttest-tuningbase.obj: soundlib/tuningbase.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-tuningbase.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-tuningbase.Tpo -c -o soundlib/libopenmpttest-tuningbase.obj `if test -f 'soundlib/tuningbase.cpp'; then $(CYGPATH_W) 'soundlib/tuningbase.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/tuningbase.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-tuningbase.Tpo soundlib/$(DEPDIR)/libopenmpttest-tuningbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/tuningbase.cpp' object='soundlib/libopenmpttest-tuningbase.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-tuningbase.obj `if test -f 'soundlib/tuningbase.cpp'; then $(CYGPATH_W) 'soundlib/tuningbase.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/tuningbase.cpp'; fi` soundlib/libopenmpttest-tuningCollection.o: soundlib/tuningCollection.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-tuningCollection.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-tuningCollection.Tpo -c -o soundlib/libopenmpttest-tuningCollection.o `test -f 'soundlib/tuningCollection.cpp' || echo '$(srcdir)/'`soundlib/tuningCollection.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-tuningCollection.Tpo soundlib/$(DEPDIR)/libopenmpttest-tuningCollection.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/tuningCollection.cpp' object='soundlib/libopenmpttest-tuningCollection.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-tuningCollection.o `test -f 'soundlib/tuningCollection.cpp' || echo '$(srcdir)/'`soundlib/tuningCollection.cpp soundlib/libopenmpttest-tuningCollection.obj: soundlib/tuningCollection.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-tuningCollection.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-tuningCollection.Tpo -c -o soundlib/libopenmpttest-tuningCollection.obj `if test -f 'soundlib/tuningCollection.cpp'; then $(CYGPATH_W) 'soundlib/tuningCollection.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/tuningCollection.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-tuningCollection.Tpo soundlib/$(DEPDIR)/libopenmpttest-tuningCollection.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/tuningCollection.cpp' object='soundlib/libopenmpttest-tuningCollection.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-tuningCollection.obj `if test -f 'soundlib/tuningCollection.cpp'; then $(CYGPATH_W) 'soundlib/tuningCollection.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/tuningCollection.cpp'; fi` soundlib/libopenmpttest-tuning.o: soundlib/tuning.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-tuning.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-tuning.Tpo -c -o soundlib/libopenmpttest-tuning.o `test -f 'soundlib/tuning.cpp' || echo '$(srcdir)/'`soundlib/tuning.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-tuning.Tpo soundlib/$(DEPDIR)/libopenmpttest-tuning.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/tuning.cpp' object='soundlib/libopenmpttest-tuning.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-tuning.o `test -f 'soundlib/tuning.cpp' || echo '$(srcdir)/'`soundlib/tuning.cpp soundlib/libopenmpttest-tuning.obj: soundlib/tuning.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-tuning.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-tuning.Tpo -c -o soundlib/libopenmpttest-tuning.obj `if test -f 'soundlib/tuning.cpp'; then $(CYGPATH_W) 'soundlib/tuning.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/tuning.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-tuning.Tpo soundlib/$(DEPDIR)/libopenmpttest-tuning.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/tuning.cpp' object='soundlib/libopenmpttest-tuning.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-tuning.obj `if test -f 'soundlib/tuning.cpp'; then $(CYGPATH_W) 'soundlib/tuning.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/tuning.cpp'; fi` soundlib/libopenmpttest-UMXTools.o: soundlib/UMXTools.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-UMXTools.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-UMXTools.Tpo -c -o soundlib/libopenmpttest-UMXTools.o `test -f 'soundlib/UMXTools.cpp' || echo '$(srcdir)/'`soundlib/UMXTools.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-UMXTools.Tpo soundlib/$(DEPDIR)/libopenmpttest-UMXTools.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/UMXTools.cpp' object='soundlib/libopenmpttest-UMXTools.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-UMXTools.o `test -f 'soundlib/UMXTools.cpp' || echo '$(srcdir)/'`soundlib/UMXTools.cpp soundlib/libopenmpttest-UMXTools.obj: soundlib/UMXTools.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-UMXTools.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-UMXTools.Tpo -c -o soundlib/libopenmpttest-UMXTools.obj `if test -f 'soundlib/UMXTools.cpp'; then $(CYGPATH_W) 'soundlib/UMXTools.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/UMXTools.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-UMXTools.Tpo soundlib/$(DEPDIR)/libopenmpttest-UMXTools.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/UMXTools.cpp' object='soundlib/libopenmpttest-UMXTools.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-UMXTools.obj `if test -f 'soundlib/UMXTools.cpp'; then $(CYGPATH_W) 'soundlib/UMXTools.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/UMXTools.cpp'; fi` soundlib/libopenmpttest-UpgradeModule.o: soundlib/UpgradeModule.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-UpgradeModule.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-UpgradeModule.Tpo -c -o soundlib/libopenmpttest-UpgradeModule.o `test -f 'soundlib/UpgradeModule.cpp' || echo '$(srcdir)/'`soundlib/UpgradeModule.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-UpgradeModule.Tpo soundlib/$(DEPDIR)/libopenmpttest-UpgradeModule.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/UpgradeModule.cpp' object='soundlib/libopenmpttest-UpgradeModule.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-UpgradeModule.o `test -f 'soundlib/UpgradeModule.cpp' || echo '$(srcdir)/'`soundlib/UpgradeModule.cpp soundlib/libopenmpttest-UpgradeModule.obj: soundlib/UpgradeModule.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-UpgradeModule.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-UpgradeModule.Tpo -c -o soundlib/libopenmpttest-UpgradeModule.obj `if test -f 'soundlib/UpgradeModule.cpp'; then $(CYGPATH_W) 'soundlib/UpgradeModule.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/UpgradeModule.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-UpgradeModule.Tpo soundlib/$(DEPDIR)/libopenmpttest-UpgradeModule.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/UpgradeModule.cpp' object='soundlib/libopenmpttest-UpgradeModule.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-UpgradeModule.obj `if test -f 'soundlib/UpgradeModule.cpp'; then $(CYGPATH_W) 'soundlib/UpgradeModule.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/UpgradeModule.cpp'; fi` soundlib/libopenmpttest-WAVTools.o: soundlib/WAVTools.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-WAVTools.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-WAVTools.Tpo -c -o soundlib/libopenmpttest-WAVTools.o `test -f 'soundlib/WAVTools.cpp' || echo '$(srcdir)/'`soundlib/WAVTools.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-WAVTools.Tpo soundlib/$(DEPDIR)/libopenmpttest-WAVTools.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/WAVTools.cpp' object='soundlib/libopenmpttest-WAVTools.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-WAVTools.o `test -f 'soundlib/WAVTools.cpp' || echo '$(srcdir)/'`soundlib/WAVTools.cpp soundlib/libopenmpttest-WAVTools.obj: soundlib/WAVTools.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-WAVTools.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-WAVTools.Tpo -c -o soundlib/libopenmpttest-WAVTools.obj `if test -f 'soundlib/WAVTools.cpp'; then $(CYGPATH_W) 'soundlib/WAVTools.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/WAVTools.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-WAVTools.Tpo soundlib/$(DEPDIR)/libopenmpttest-WAVTools.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/WAVTools.cpp' object='soundlib/libopenmpttest-WAVTools.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-WAVTools.obj `if test -f 'soundlib/WAVTools.cpp'; then $(CYGPATH_W) 'soundlib/WAVTools.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/WAVTools.cpp'; fi` soundlib/libopenmpttest-WindowedFIR.o: soundlib/WindowedFIR.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-WindowedFIR.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-WindowedFIR.Tpo -c -o soundlib/libopenmpttest-WindowedFIR.o `test -f 'soundlib/WindowedFIR.cpp' || echo '$(srcdir)/'`soundlib/WindowedFIR.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-WindowedFIR.Tpo soundlib/$(DEPDIR)/libopenmpttest-WindowedFIR.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/WindowedFIR.cpp' object='soundlib/libopenmpttest-WindowedFIR.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-WindowedFIR.o `test -f 'soundlib/WindowedFIR.cpp' || echo '$(srcdir)/'`soundlib/WindowedFIR.cpp soundlib/libopenmpttest-WindowedFIR.obj: soundlib/WindowedFIR.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-WindowedFIR.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-WindowedFIR.Tpo -c -o soundlib/libopenmpttest-WindowedFIR.obj `if test -f 'soundlib/WindowedFIR.cpp'; then $(CYGPATH_W) 'soundlib/WindowedFIR.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/WindowedFIR.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-WindowedFIR.Tpo soundlib/$(DEPDIR)/libopenmpttest-WindowedFIR.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/WindowedFIR.cpp' object='soundlib/libopenmpttest-WindowedFIR.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-WindowedFIR.obj `if test -f 'soundlib/WindowedFIR.cpp'; then $(CYGPATH_W) 'soundlib/WindowedFIR.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/WindowedFIR.cpp'; fi` soundlib/libopenmpttest-XMTools.o: soundlib/XMTools.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-XMTools.o -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-XMTools.Tpo -c -o soundlib/libopenmpttest-XMTools.o `test -f 'soundlib/XMTools.cpp' || echo '$(srcdir)/'`soundlib/XMTools.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-XMTools.Tpo soundlib/$(DEPDIR)/libopenmpttest-XMTools.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/XMTools.cpp' object='soundlib/libopenmpttest-XMTools.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-XMTools.o `test -f 'soundlib/XMTools.cpp' || echo '$(srcdir)/'`soundlib/XMTools.cpp soundlib/libopenmpttest-XMTools.obj: soundlib/XMTools.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/libopenmpttest-XMTools.obj -MD -MP -MF soundlib/$(DEPDIR)/libopenmpttest-XMTools.Tpo -c -o soundlib/libopenmpttest-XMTools.obj `if test -f 'soundlib/XMTools.cpp'; then $(CYGPATH_W) 'soundlib/XMTools.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/XMTools.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/$(DEPDIR)/libopenmpttest-XMTools.Tpo soundlib/$(DEPDIR)/libopenmpttest-XMTools.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/XMTools.cpp' object='soundlib/libopenmpttest-XMTools.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/libopenmpttest-XMTools.obj `if test -f 'soundlib/XMTools.cpp'; then $(CYGPATH_W) 'soundlib/XMTools.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/XMTools.cpp'; fi` soundlib/plugins/dmo/libopenmpttest-DMOPlugin.o: soundlib/plugins/dmo/DMOPlugin.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/dmo/libopenmpttest-DMOPlugin.o -MD -MP -MF soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-DMOPlugin.Tpo -c -o soundlib/plugins/dmo/libopenmpttest-DMOPlugin.o `test -f 'soundlib/plugins/dmo/DMOPlugin.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/DMOPlugin.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-DMOPlugin.Tpo soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-DMOPlugin.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/dmo/DMOPlugin.cpp' object='soundlib/plugins/dmo/libopenmpttest-DMOPlugin.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/dmo/libopenmpttest-DMOPlugin.o `test -f 'soundlib/plugins/dmo/DMOPlugin.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/DMOPlugin.cpp soundlib/plugins/dmo/libopenmpttest-DMOPlugin.obj: soundlib/plugins/dmo/DMOPlugin.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/dmo/libopenmpttest-DMOPlugin.obj -MD -MP -MF soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-DMOPlugin.Tpo -c -o soundlib/plugins/dmo/libopenmpttest-DMOPlugin.obj `if test -f 'soundlib/plugins/dmo/DMOPlugin.cpp'; then $(CYGPATH_W) 'soundlib/plugins/dmo/DMOPlugin.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/plugins/dmo/DMOPlugin.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-DMOPlugin.Tpo soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-DMOPlugin.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/dmo/DMOPlugin.cpp' object='soundlib/plugins/dmo/libopenmpttest-DMOPlugin.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/dmo/libopenmpttest-DMOPlugin.obj `if test -f 'soundlib/plugins/dmo/DMOPlugin.cpp'; then $(CYGPATH_W) 'soundlib/plugins/dmo/DMOPlugin.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/plugins/dmo/DMOPlugin.cpp'; fi` soundlib/plugins/dmo/libopenmpttest-Chorus.o: soundlib/plugins/dmo/Chorus.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/dmo/libopenmpttest-Chorus.o -MD -MP -MF soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Chorus.Tpo -c -o soundlib/plugins/dmo/libopenmpttest-Chorus.o `test -f 'soundlib/plugins/dmo/Chorus.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/Chorus.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Chorus.Tpo soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Chorus.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/dmo/Chorus.cpp' object='soundlib/plugins/dmo/libopenmpttest-Chorus.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/dmo/libopenmpttest-Chorus.o `test -f 'soundlib/plugins/dmo/Chorus.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/Chorus.cpp soundlib/plugins/dmo/libopenmpttest-Chorus.obj: soundlib/plugins/dmo/Chorus.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/dmo/libopenmpttest-Chorus.obj -MD -MP -MF soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Chorus.Tpo -c -o soundlib/plugins/dmo/libopenmpttest-Chorus.obj `if test -f 'soundlib/plugins/dmo/Chorus.cpp'; then $(CYGPATH_W) 'soundlib/plugins/dmo/Chorus.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/plugins/dmo/Chorus.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Chorus.Tpo soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Chorus.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/dmo/Chorus.cpp' object='soundlib/plugins/dmo/libopenmpttest-Chorus.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/dmo/libopenmpttest-Chorus.obj `if test -f 'soundlib/plugins/dmo/Chorus.cpp'; then $(CYGPATH_W) 'soundlib/plugins/dmo/Chorus.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/plugins/dmo/Chorus.cpp'; fi` soundlib/plugins/dmo/libopenmpttest-Compressor.o: soundlib/plugins/dmo/Compressor.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/dmo/libopenmpttest-Compressor.o -MD -MP -MF soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Compressor.Tpo -c -o soundlib/plugins/dmo/libopenmpttest-Compressor.o `test -f 'soundlib/plugins/dmo/Compressor.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/Compressor.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Compressor.Tpo soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Compressor.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/dmo/Compressor.cpp' object='soundlib/plugins/dmo/libopenmpttest-Compressor.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/dmo/libopenmpttest-Compressor.o `test -f 'soundlib/plugins/dmo/Compressor.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/Compressor.cpp soundlib/plugins/dmo/libopenmpttest-Compressor.obj: soundlib/plugins/dmo/Compressor.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/dmo/libopenmpttest-Compressor.obj -MD -MP -MF soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Compressor.Tpo -c -o soundlib/plugins/dmo/libopenmpttest-Compressor.obj `if test -f 'soundlib/plugins/dmo/Compressor.cpp'; then $(CYGPATH_W) 'soundlib/plugins/dmo/Compressor.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/plugins/dmo/Compressor.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Compressor.Tpo soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Compressor.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/dmo/Compressor.cpp' object='soundlib/plugins/dmo/libopenmpttest-Compressor.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/dmo/libopenmpttest-Compressor.obj `if test -f 'soundlib/plugins/dmo/Compressor.cpp'; then $(CYGPATH_W) 'soundlib/plugins/dmo/Compressor.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/plugins/dmo/Compressor.cpp'; fi` soundlib/plugins/dmo/libopenmpttest-Distortion.o: soundlib/plugins/dmo/Distortion.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/dmo/libopenmpttest-Distortion.o -MD -MP -MF soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Distortion.Tpo -c -o soundlib/plugins/dmo/libopenmpttest-Distortion.o `test -f 'soundlib/plugins/dmo/Distortion.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/Distortion.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Distortion.Tpo soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Distortion.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/dmo/Distortion.cpp' object='soundlib/plugins/dmo/libopenmpttest-Distortion.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/dmo/libopenmpttest-Distortion.o `test -f 'soundlib/plugins/dmo/Distortion.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/Distortion.cpp soundlib/plugins/dmo/libopenmpttest-Distortion.obj: soundlib/plugins/dmo/Distortion.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/dmo/libopenmpttest-Distortion.obj -MD -MP -MF soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Distortion.Tpo -c -o soundlib/plugins/dmo/libopenmpttest-Distortion.obj `if test -f 'soundlib/plugins/dmo/Distortion.cpp'; then $(CYGPATH_W) 'soundlib/plugins/dmo/Distortion.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/plugins/dmo/Distortion.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Distortion.Tpo soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Distortion.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/dmo/Distortion.cpp' object='soundlib/plugins/dmo/libopenmpttest-Distortion.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/dmo/libopenmpttest-Distortion.obj `if test -f 'soundlib/plugins/dmo/Distortion.cpp'; then $(CYGPATH_W) 'soundlib/plugins/dmo/Distortion.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/plugins/dmo/Distortion.cpp'; fi` soundlib/plugins/dmo/libopenmpttest-Echo.o: soundlib/plugins/dmo/Echo.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/dmo/libopenmpttest-Echo.o -MD -MP -MF soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Echo.Tpo -c -o soundlib/plugins/dmo/libopenmpttest-Echo.o `test -f 'soundlib/plugins/dmo/Echo.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/Echo.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Echo.Tpo soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Echo.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/dmo/Echo.cpp' object='soundlib/plugins/dmo/libopenmpttest-Echo.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/dmo/libopenmpttest-Echo.o `test -f 'soundlib/plugins/dmo/Echo.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/Echo.cpp soundlib/plugins/dmo/libopenmpttest-Echo.obj: soundlib/plugins/dmo/Echo.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/dmo/libopenmpttest-Echo.obj -MD -MP -MF soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Echo.Tpo -c -o soundlib/plugins/dmo/libopenmpttest-Echo.obj `if test -f 'soundlib/plugins/dmo/Echo.cpp'; then $(CYGPATH_W) 'soundlib/plugins/dmo/Echo.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/plugins/dmo/Echo.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Echo.Tpo soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Echo.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/dmo/Echo.cpp' object='soundlib/plugins/dmo/libopenmpttest-Echo.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/dmo/libopenmpttest-Echo.obj `if test -f 'soundlib/plugins/dmo/Echo.cpp'; then $(CYGPATH_W) 'soundlib/plugins/dmo/Echo.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/plugins/dmo/Echo.cpp'; fi` soundlib/plugins/dmo/libopenmpttest-Flanger.o: soundlib/plugins/dmo/Flanger.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/dmo/libopenmpttest-Flanger.o -MD -MP -MF soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Flanger.Tpo -c -o soundlib/plugins/dmo/libopenmpttest-Flanger.o `test -f 'soundlib/plugins/dmo/Flanger.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/Flanger.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Flanger.Tpo soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Flanger.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/dmo/Flanger.cpp' object='soundlib/plugins/dmo/libopenmpttest-Flanger.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/dmo/libopenmpttest-Flanger.o `test -f 'soundlib/plugins/dmo/Flanger.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/Flanger.cpp soundlib/plugins/dmo/libopenmpttest-Flanger.obj: soundlib/plugins/dmo/Flanger.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/dmo/libopenmpttest-Flanger.obj -MD -MP -MF soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Flanger.Tpo -c -o soundlib/plugins/dmo/libopenmpttest-Flanger.obj `if test -f 'soundlib/plugins/dmo/Flanger.cpp'; then $(CYGPATH_W) 'soundlib/plugins/dmo/Flanger.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/plugins/dmo/Flanger.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Flanger.Tpo soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Flanger.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/dmo/Flanger.cpp' object='soundlib/plugins/dmo/libopenmpttest-Flanger.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/dmo/libopenmpttest-Flanger.obj `if test -f 'soundlib/plugins/dmo/Flanger.cpp'; then $(CYGPATH_W) 'soundlib/plugins/dmo/Flanger.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/plugins/dmo/Flanger.cpp'; fi` soundlib/plugins/dmo/libopenmpttest-Gargle.o: soundlib/plugins/dmo/Gargle.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/dmo/libopenmpttest-Gargle.o -MD -MP -MF soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Gargle.Tpo -c -o soundlib/plugins/dmo/libopenmpttest-Gargle.o `test -f 'soundlib/plugins/dmo/Gargle.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/Gargle.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Gargle.Tpo soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Gargle.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/dmo/Gargle.cpp' object='soundlib/plugins/dmo/libopenmpttest-Gargle.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/dmo/libopenmpttest-Gargle.o `test -f 'soundlib/plugins/dmo/Gargle.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/Gargle.cpp soundlib/plugins/dmo/libopenmpttest-Gargle.obj: soundlib/plugins/dmo/Gargle.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/dmo/libopenmpttest-Gargle.obj -MD -MP -MF soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Gargle.Tpo -c -o soundlib/plugins/dmo/libopenmpttest-Gargle.obj `if test -f 'soundlib/plugins/dmo/Gargle.cpp'; then $(CYGPATH_W) 'soundlib/plugins/dmo/Gargle.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/plugins/dmo/Gargle.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Gargle.Tpo soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-Gargle.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/dmo/Gargle.cpp' object='soundlib/plugins/dmo/libopenmpttest-Gargle.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/dmo/libopenmpttest-Gargle.obj `if test -f 'soundlib/plugins/dmo/Gargle.cpp'; then $(CYGPATH_W) 'soundlib/plugins/dmo/Gargle.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/plugins/dmo/Gargle.cpp'; fi` soundlib/plugins/dmo/libopenmpttest-I3DL2Reverb.o: soundlib/plugins/dmo/I3DL2Reverb.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/dmo/libopenmpttest-I3DL2Reverb.o -MD -MP -MF soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-I3DL2Reverb.Tpo -c -o soundlib/plugins/dmo/libopenmpttest-I3DL2Reverb.o `test -f 'soundlib/plugins/dmo/I3DL2Reverb.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/I3DL2Reverb.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-I3DL2Reverb.Tpo soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-I3DL2Reverb.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/dmo/I3DL2Reverb.cpp' object='soundlib/plugins/dmo/libopenmpttest-I3DL2Reverb.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/dmo/libopenmpttest-I3DL2Reverb.o `test -f 'soundlib/plugins/dmo/I3DL2Reverb.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/I3DL2Reverb.cpp soundlib/plugins/dmo/libopenmpttest-I3DL2Reverb.obj: soundlib/plugins/dmo/I3DL2Reverb.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/dmo/libopenmpttest-I3DL2Reverb.obj -MD -MP -MF soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-I3DL2Reverb.Tpo -c -o soundlib/plugins/dmo/libopenmpttest-I3DL2Reverb.obj `if test -f 'soundlib/plugins/dmo/I3DL2Reverb.cpp'; then $(CYGPATH_W) 'soundlib/plugins/dmo/I3DL2Reverb.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/plugins/dmo/I3DL2Reverb.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-I3DL2Reverb.Tpo soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-I3DL2Reverb.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/dmo/I3DL2Reverb.cpp' object='soundlib/plugins/dmo/libopenmpttest-I3DL2Reverb.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/dmo/libopenmpttest-I3DL2Reverb.obj `if test -f 'soundlib/plugins/dmo/I3DL2Reverb.cpp'; then $(CYGPATH_W) 'soundlib/plugins/dmo/I3DL2Reverb.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/plugins/dmo/I3DL2Reverb.cpp'; fi` soundlib/plugins/dmo/libopenmpttest-ParamEq.o: soundlib/plugins/dmo/ParamEq.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/dmo/libopenmpttest-ParamEq.o -MD -MP -MF soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-ParamEq.Tpo -c -o soundlib/plugins/dmo/libopenmpttest-ParamEq.o `test -f 'soundlib/plugins/dmo/ParamEq.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/ParamEq.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-ParamEq.Tpo soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-ParamEq.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/dmo/ParamEq.cpp' object='soundlib/plugins/dmo/libopenmpttest-ParamEq.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/dmo/libopenmpttest-ParamEq.o `test -f 'soundlib/plugins/dmo/ParamEq.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/ParamEq.cpp soundlib/plugins/dmo/libopenmpttest-ParamEq.obj: soundlib/plugins/dmo/ParamEq.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/dmo/libopenmpttest-ParamEq.obj -MD -MP -MF soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-ParamEq.Tpo -c -o soundlib/plugins/dmo/libopenmpttest-ParamEq.obj `if test -f 'soundlib/plugins/dmo/ParamEq.cpp'; then $(CYGPATH_W) 'soundlib/plugins/dmo/ParamEq.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/plugins/dmo/ParamEq.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-ParamEq.Tpo soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-ParamEq.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/dmo/ParamEq.cpp' object='soundlib/plugins/dmo/libopenmpttest-ParamEq.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/dmo/libopenmpttest-ParamEq.obj `if test -f 'soundlib/plugins/dmo/ParamEq.cpp'; then $(CYGPATH_W) 'soundlib/plugins/dmo/ParamEq.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/plugins/dmo/ParamEq.cpp'; fi` soundlib/plugins/dmo/libopenmpttest-WavesReverb.o: soundlib/plugins/dmo/WavesReverb.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/dmo/libopenmpttest-WavesReverb.o -MD -MP -MF soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-WavesReverb.Tpo -c -o soundlib/plugins/dmo/libopenmpttest-WavesReverb.o `test -f 'soundlib/plugins/dmo/WavesReverb.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/WavesReverb.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-WavesReverb.Tpo soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-WavesReverb.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/dmo/WavesReverb.cpp' object='soundlib/plugins/dmo/libopenmpttest-WavesReverb.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/dmo/libopenmpttest-WavesReverb.o `test -f 'soundlib/plugins/dmo/WavesReverb.cpp' || echo '$(srcdir)/'`soundlib/plugins/dmo/WavesReverb.cpp soundlib/plugins/dmo/libopenmpttest-WavesReverb.obj: soundlib/plugins/dmo/WavesReverb.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/dmo/libopenmpttest-WavesReverb.obj -MD -MP -MF soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-WavesReverb.Tpo -c -o soundlib/plugins/dmo/libopenmpttest-WavesReverb.obj `if test -f 'soundlib/plugins/dmo/WavesReverb.cpp'; then $(CYGPATH_W) 'soundlib/plugins/dmo/WavesReverb.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/plugins/dmo/WavesReverb.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-WavesReverb.Tpo soundlib/plugins/dmo/$(DEPDIR)/libopenmpttest-WavesReverb.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/dmo/WavesReverb.cpp' object='soundlib/plugins/dmo/libopenmpttest-WavesReverb.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/dmo/libopenmpttest-WavesReverb.obj `if test -f 'soundlib/plugins/dmo/WavesReverb.cpp'; then $(CYGPATH_W) 'soundlib/plugins/dmo/WavesReverb.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/plugins/dmo/WavesReverb.cpp'; fi` soundlib/plugins/libopenmpttest-DigiBoosterEcho.o: soundlib/plugins/DigiBoosterEcho.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/libopenmpttest-DigiBoosterEcho.o -MD -MP -MF soundlib/plugins/$(DEPDIR)/libopenmpttest-DigiBoosterEcho.Tpo -c -o soundlib/plugins/libopenmpttest-DigiBoosterEcho.o `test -f 'soundlib/plugins/DigiBoosterEcho.cpp' || echo '$(srcdir)/'`soundlib/plugins/DigiBoosterEcho.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/$(DEPDIR)/libopenmpttest-DigiBoosterEcho.Tpo soundlib/plugins/$(DEPDIR)/libopenmpttest-DigiBoosterEcho.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/DigiBoosterEcho.cpp' object='soundlib/plugins/libopenmpttest-DigiBoosterEcho.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/libopenmpttest-DigiBoosterEcho.o `test -f 'soundlib/plugins/DigiBoosterEcho.cpp' || echo '$(srcdir)/'`soundlib/plugins/DigiBoosterEcho.cpp soundlib/plugins/libopenmpttest-DigiBoosterEcho.obj: soundlib/plugins/DigiBoosterEcho.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/libopenmpttest-DigiBoosterEcho.obj -MD -MP -MF soundlib/plugins/$(DEPDIR)/libopenmpttest-DigiBoosterEcho.Tpo -c -o soundlib/plugins/libopenmpttest-DigiBoosterEcho.obj `if test -f 'soundlib/plugins/DigiBoosterEcho.cpp'; then $(CYGPATH_W) 'soundlib/plugins/DigiBoosterEcho.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/plugins/DigiBoosterEcho.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/$(DEPDIR)/libopenmpttest-DigiBoosterEcho.Tpo soundlib/plugins/$(DEPDIR)/libopenmpttest-DigiBoosterEcho.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/DigiBoosterEcho.cpp' object='soundlib/plugins/libopenmpttest-DigiBoosterEcho.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/libopenmpttest-DigiBoosterEcho.obj `if test -f 'soundlib/plugins/DigiBoosterEcho.cpp'; then $(CYGPATH_W) 'soundlib/plugins/DigiBoosterEcho.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/plugins/DigiBoosterEcho.cpp'; fi` soundlib/plugins/libopenmpttest-LFOPlugin.o: soundlib/plugins/LFOPlugin.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/libopenmpttest-LFOPlugin.o -MD -MP -MF soundlib/plugins/$(DEPDIR)/libopenmpttest-LFOPlugin.Tpo -c -o soundlib/plugins/libopenmpttest-LFOPlugin.o `test -f 'soundlib/plugins/LFOPlugin.cpp' || echo '$(srcdir)/'`soundlib/plugins/LFOPlugin.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/$(DEPDIR)/libopenmpttest-LFOPlugin.Tpo soundlib/plugins/$(DEPDIR)/libopenmpttest-LFOPlugin.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/LFOPlugin.cpp' object='soundlib/plugins/libopenmpttest-LFOPlugin.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/libopenmpttest-LFOPlugin.o `test -f 'soundlib/plugins/LFOPlugin.cpp' || echo '$(srcdir)/'`soundlib/plugins/LFOPlugin.cpp soundlib/plugins/libopenmpttest-LFOPlugin.obj: soundlib/plugins/LFOPlugin.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/libopenmpttest-LFOPlugin.obj -MD -MP -MF soundlib/plugins/$(DEPDIR)/libopenmpttest-LFOPlugin.Tpo -c -o soundlib/plugins/libopenmpttest-LFOPlugin.obj `if test -f 'soundlib/plugins/LFOPlugin.cpp'; then $(CYGPATH_W) 'soundlib/plugins/LFOPlugin.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/plugins/LFOPlugin.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/$(DEPDIR)/libopenmpttest-LFOPlugin.Tpo soundlib/plugins/$(DEPDIR)/libopenmpttest-LFOPlugin.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/LFOPlugin.cpp' object='soundlib/plugins/libopenmpttest-LFOPlugin.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/libopenmpttest-LFOPlugin.obj `if test -f 'soundlib/plugins/LFOPlugin.cpp'; then $(CYGPATH_W) 'soundlib/plugins/LFOPlugin.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/plugins/LFOPlugin.cpp'; fi` soundlib/plugins/libopenmpttest-PluginManager.o: soundlib/plugins/PluginManager.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/libopenmpttest-PluginManager.o -MD -MP -MF soundlib/plugins/$(DEPDIR)/libopenmpttest-PluginManager.Tpo -c -o soundlib/plugins/libopenmpttest-PluginManager.o `test -f 'soundlib/plugins/PluginManager.cpp' || echo '$(srcdir)/'`soundlib/plugins/PluginManager.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/$(DEPDIR)/libopenmpttest-PluginManager.Tpo soundlib/plugins/$(DEPDIR)/libopenmpttest-PluginManager.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/PluginManager.cpp' object='soundlib/plugins/libopenmpttest-PluginManager.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/libopenmpttest-PluginManager.o `test -f 'soundlib/plugins/PluginManager.cpp' || echo '$(srcdir)/'`soundlib/plugins/PluginManager.cpp soundlib/plugins/libopenmpttest-PluginManager.obj: soundlib/plugins/PluginManager.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/libopenmpttest-PluginManager.obj -MD -MP -MF soundlib/plugins/$(DEPDIR)/libopenmpttest-PluginManager.Tpo -c -o soundlib/plugins/libopenmpttest-PluginManager.obj `if test -f 'soundlib/plugins/PluginManager.cpp'; then $(CYGPATH_W) 'soundlib/plugins/PluginManager.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/plugins/PluginManager.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/$(DEPDIR)/libopenmpttest-PluginManager.Tpo soundlib/plugins/$(DEPDIR)/libopenmpttest-PluginManager.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/PluginManager.cpp' object='soundlib/plugins/libopenmpttest-PluginManager.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/libopenmpttest-PluginManager.obj `if test -f 'soundlib/plugins/PluginManager.cpp'; then $(CYGPATH_W) 'soundlib/plugins/PluginManager.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/plugins/PluginManager.cpp'; fi` soundlib/plugins/libopenmpttest-PlugInterface.o: soundlib/plugins/PlugInterface.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/libopenmpttest-PlugInterface.o -MD -MP -MF soundlib/plugins/$(DEPDIR)/libopenmpttest-PlugInterface.Tpo -c -o soundlib/plugins/libopenmpttest-PlugInterface.o `test -f 'soundlib/plugins/PlugInterface.cpp' || echo '$(srcdir)/'`soundlib/plugins/PlugInterface.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/$(DEPDIR)/libopenmpttest-PlugInterface.Tpo soundlib/plugins/$(DEPDIR)/libopenmpttest-PlugInterface.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/PlugInterface.cpp' object='soundlib/plugins/libopenmpttest-PlugInterface.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/libopenmpttest-PlugInterface.o `test -f 'soundlib/plugins/PlugInterface.cpp' || echo '$(srcdir)/'`soundlib/plugins/PlugInterface.cpp soundlib/plugins/libopenmpttest-PlugInterface.obj: soundlib/plugins/PlugInterface.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT soundlib/plugins/libopenmpttest-PlugInterface.obj -MD -MP -MF soundlib/plugins/$(DEPDIR)/libopenmpttest-PlugInterface.Tpo -c -o soundlib/plugins/libopenmpttest-PlugInterface.obj `if test -f 'soundlib/plugins/PlugInterface.cpp'; then $(CYGPATH_W) 'soundlib/plugins/PlugInterface.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/plugins/PlugInterface.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) soundlib/plugins/$(DEPDIR)/libopenmpttest-PlugInterface.Tpo soundlib/plugins/$(DEPDIR)/libopenmpttest-PlugInterface.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='soundlib/plugins/PlugInterface.cpp' object='soundlib/plugins/libopenmpttest-PlugInterface.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o soundlib/plugins/libopenmpttest-PlugInterface.obj `if test -f 'soundlib/plugins/PlugInterface.cpp'; then $(CYGPATH_W) 'soundlib/plugins/PlugInterface.cpp'; else $(CYGPATH_W) '$(srcdir)/soundlib/plugins/PlugInterface.cpp'; fi` sounddsp/libopenmpttest-AGC.o: sounddsp/AGC.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT sounddsp/libopenmpttest-AGC.o -MD -MP -MF sounddsp/$(DEPDIR)/libopenmpttest-AGC.Tpo -c -o sounddsp/libopenmpttest-AGC.o `test -f 'sounddsp/AGC.cpp' || echo '$(srcdir)/'`sounddsp/AGC.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) sounddsp/$(DEPDIR)/libopenmpttest-AGC.Tpo sounddsp/$(DEPDIR)/libopenmpttest-AGC.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='sounddsp/AGC.cpp' object='sounddsp/libopenmpttest-AGC.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o sounddsp/libopenmpttest-AGC.o `test -f 'sounddsp/AGC.cpp' || echo '$(srcdir)/'`sounddsp/AGC.cpp sounddsp/libopenmpttest-AGC.obj: sounddsp/AGC.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT sounddsp/libopenmpttest-AGC.obj -MD -MP -MF sounddsp/$(DEPDIR)/libopenmpttest-AGC.Tpo -c -o sounddsp/libopenmpttest-AGC.obj `if test -f 'sounddsp/AGC.cpp'; then $(CYGPATH_W) 'sounddsp/AGC.cpp'; else $(CYGPATH_W) '$(srcdir)/sounddsp/AGC.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) sounddsp/$(DEPDIR)/libopenmpttest-AGC.Tpo sounddsp/$(DEPDIR)/libopenmpttest-AGC.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='sounddsp/AGC.cpp' object='sounddsp/libopenmpttest-AGC.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o sounddsp/libopenmpttest-AGC.obj `if test -f 'sounddsp/AGC.cpp'; then $(CYGPATH_W) 'sounddsp/AGC.cpp'; else $(CYGPATH_W) '$(srcdir)/sounddsp/AGC.cpp'; fi` sounddsp/libopenmpttest-DSP.o: sounddsp/DSP.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT sounddsp/libopenmpttest-DSP.o -MD -MP -MF sounddsp/$(DEPDIR)/libopenmpttest-DSP.Tpo -c -o sounddsp/libopenmpttest-DSP.o `test -f 'sounddsp/DSP.cpp' || echo '$(srcdir)/'`sounddsp/DSP.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) sounddsp/$(DEPDIR)/libopenmpttest-DSP.Tpo sounddsp/$(DEPDIR)/libopenmpttest-DSP.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='sounddsp/DSP.cpp' object='sounddsp/libopenmpttest-DSP.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o sounddsp/libopenmpttest-DSP.o `test -f 'sounddsp/DSP.cpp' || echo '$(srcdir)/'`sounddsp/DSP.cpp sounddsp/libopenmpttest-DSP.obj: sounddsp/DSP.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT sounddsp/libopenmpttest-DSP.obj -MD -MP -MF sounddsp/$(DEPDIR)/libopenmpttest-DSP.Tpo -c -o sounddsp/libopenmpttest-DSP.obj `if test -f 'sounddsp/DSP.cpp'; then $(CYGPATH_W) 'sounddsp/DSP.cpp'; else $(CYGPATH_W) '$(srcdir)/sounddsp/DSP.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) sounddsp/$(DEPDIR)/libopenmpttest-DSP.Tpo sounddsp/$(DEPDIR)/libopenmpttest-DSP.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='sounddsp/DSP.cpp' object='sounddsp/libopenmpttest-DSP.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o sounddsp/libopenmpttest-DSP.obj `if test -f 'sounddsp/DSP.cpp'; then $(CYGPATH_W) 'sounddsp/DSP.cpp'; else $(CYGPATH_W) '$(srcdir)/sounddsp/DSP.cpp'; fi` sounddsp/libopenmpttest-EQ.o: sounddsp/EQ.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT sounddsp/libopenmpttest-EQ.o -MD -MP -MF sounddsp/$(DEPDIR)/libopenmpttest-EQ.Tpo -c -o sounddsp/libopenmpttest-EQ.o `test -f 'sounddsp/EQ.cpp' || echo '$(srcdir)/'`sounddsp/EQ.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) sounddsp/$(DEPDIR)/libopenmpttest-EQ.Tpo sounddsp/$(DEPDIR)/libopenmpttest-EQ.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='sounddsp/EQ.cpp' object='sounddsp/libopenmpttest-EQ.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o sounddsp/libopenmpttest-EQ.o `test -f 'sounddsp/EQ.cpp' || echo '$(srcdir)/'`sounddsp/EQ.cpp sounddsp/libopenmpttest-EQ.obj: sounddsp/EQ.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT sounddsp/libopenmpttest-EQ.obj -MD -MP -MF sounddsp/$(DEPDIR)/libopenmpttest-EQ.Tpo -c -o sounddsp/libopenmpttest-EQ.obj `if test -f 'sounddsp/EQ.cpp'; then $(CYGPATH_W) 'sounddsp/EQ.cpp'; else $(CYGPATH_W) '$(srcdir)/sounddsp/EQ.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) sounddsp/$(DEPDIR)/libopenmpttest-EQ.Tpo sounddsp/$(DEPDIR)/libopenmpttest-EQ.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='sounddsp/EQ.cpp' object='sounddsp/libopenmpttest-EQ.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o sounddsp/libopenmpttest-EQ.obj `if test -f 'sounddsp/EQ.cpp'; then $(CYGPATH_W) 'sounddsp/EQ.cpp'; else $(CYGPATH_W) '$(srcdir)/sounddsp/EQ.cpp'; fi` sounddsp/libopenmpttest-Reverb.o: sounddsp/Reverb.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT sounddsp/libopenmpttest-Reverb.o -MD -MP -MF sounddsp/$(DEPDIR)/libopenmpttest-Reverb.Tpo -c -o sounddsp/libopenmpttest-Reverb.o `test -f 'sounddsp/Reverb.cpp' || echo '$(srcdir)/'`sounddsp/Reverb.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) sounddsp/$(DEPDIR)/libopenmpttest-Reverb.Tpo sounddsp/$(DEPDIR)/libopenmpttest-Reverb.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='sounddsp/Reverb.cpp' object='sounddsp/libopenmpttest-Reverb.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o sounddsp/libopenmpttest-Reverb.o `test -f 'sounddsp/Reverb.cpp' || echo '$(srcdir)/'`sounddsp/Reverb.cpp sounddsp/libopenmpttest-Reverb.obj: sounddsp/Reverb.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT sounddsp/libopenmpttest-Reverb.obj -MD -MP -MF sounddsp/$(DEPDIR)/libopenmpttest-Reverb.Tpo -c -o sounddsp/libopenmpttest-Reverb.obj `if test -f 'sounddsp/Reverb.cpp'; then $(CYGPATH_W) 'sounddsp/Reverb.cpp'; else $(CYGPATH_W) '$(srcdir)/sounddsp/Reverb.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) sounddsp/$(DEPDIR)/libopenmpttest-Reverb.Tpo sounddsp/$(DEPDIR)/libopenmpttest-Reverb.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='sounddsp/Reverb.cpp' object='sounddsp/libopenmpttest-Reverb.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o sounddsp/libopenmpttest-Reverb.obj `if test -f 'sounddsp/Reverb.cpp'; then $(CYGPATH_W) 'sounddsp/Reverb.cpp'; else $(CYGPATH_W) '$(srcdir)/sounddsp/Reverb.cpp'; fi` libopenmpt/libopenmpttest-libopenmpt_c.o: libopenmpt/libopenmpt_c.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT libopenmpt/libopenmpttest-libopenmpt_c.o -MD -MP -MF libopenmpt/$(DEPDIR)/libopenmpttest-libopenmpt_c.Tpo -c -o libopenmpt/libopenmpttest-libopenmpt_c.o `test -f 'libopenmpt/libopenmpt_c.cpp' || echo '$(srcdir)/'`libopenmpt/libopenmpt_c.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) libopenmpt/$(DEPDIR)/libopenmpttest-libopenmpt_c.Tpo libopenmpt/$(DEPDIR)/libopenmpttest-libopenmpt_c.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='libopenmpt/libopenmpt_c.cpp' object='libopenmpt/libopenmpttest-libopenmpt_c.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o libopenmpt/libopenmpttest-libopenmpt_c.o `test -f 'libopenmpt/libopenmpt_c.cpp' || echo '$(srcdir)/'`libopenmpt/libopenmpt_c.cpp libopenmpt/libopenmpttest-libopenmpt_c.obj: libopenmpt/libopenmpt_c.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT libopenmpt/libopenmpttest-libopenmpt_c.obj -MD -MP -MF libopenmpt/$(DEPDIR)/libopenmpttest-libopenmpt_c.Tpo -c -o libopenmpt/libopenmpttest-libopenmpt_c.obj `if test -f 'libopenmpt/libopenmpt_c.cpp'; then $(CYGPATH_W) 'libopenmpt/libopenmpt_c.cpp'; else $(CYGPATH_W) '$(srcdir)/libopenmpt/libopenmpt_c.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) libopenmpt/$(DEPDIR)/libopenmpttest-libopenmpt_c.Tpo libopenmpt/$(DEPDIR)/libopenmpttest-libopenmpt_c.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='libopenmpt/libopenmpt_c.cpp' object='libopenmpt/libopenmpttest-libopenmpt_c.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o libopenmpt/libopenmpttest-libopenmpt_c.obj `if test -f 'libopenmpt/libopenmpt_c.cpp'; then $(CYGPATH_W) 'libopenmpt/libopenmpt_c.cpp'; else $(CYGPATH_W) '$(srcdir)/libopenmpt/libopenmpt_c.cpp'; fi` libopenmpt/libopenmpttest-libopenmpt_cxx.o: libopenmpt/libopenmpt_cxx.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT libopenmpt/libopenmpttest-libopenmpt_cxx.o -MD -MP -MF libopenmpt/$(DEPDIR)/libopenmpttest-libopenmpt_cxx.Tpo -c -o libopenmpt/libopenmpttest-libopenmpt_cxx.o `test -f 'libopenmpt/libopenmpt_cxx.cpp' || echo '$(srcdir)/'`libopenmpt/libopenmpt_cxx.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) libopenmpt/$(DEPDIR)/libopenmpttest-libopenmpt_cxx.Tpo libopenmpt/$(DEPDIR)/libopenmpttest-libopenmpt_cxx.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='libopenmpt/libopenmpt_cxx.cpp' object='libopenmpt/libopenmpttest-libopenmpt_cxx.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o libopenmpt/libopenmpttest-libopenmpt_cxx.o `test -f 'libopenmpt/libopenmpt_cxx.cpp' || echo '$(srcdir)/'`libopenmpt/libopenmpt_cxx.cpp libopenmpt/libopenmpttest-libopenmpt_cxx.obj: libopenmpt/libopenmpt_cxx.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT libopenmpt/libopenmpttest-libopenmpt_cxx.obj -MD -MP -MF libopenmpt/$(DEPDIR)/libopenmpttest-libopenmpt_cxx.Tpo -c -o libopenmpt/libopenmpttest-libopenmpt_cxx.obj `if test -f 'libopenmpt/libopenmpt_cxx.cpp'; then $(CYGPATH_W) 'libopenmpt/libopenmpt_cxx.cpp'; else $(CYGPATH_W) '$(srcdir)/libopenmpt/libopenmpt_cxx.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) libopenmpt/$(DEPDIR)/libopenmpttest-libopenmpt_cxx.Tpo libopenmpt/$(DEPDIR)/libopenmpttest-libopenmpt_cxx.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='libopenmpt/libopenmpt_cxx.cpp' object='libopenmpt/libopenmpttest-libopenmpt_cxx.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o libopenmpt/libopenmpttest-libopenmpt_cxx.obj `if test -f 'libopenmpt/libopenmpt_cxx.cpp'; then $(CYGPATH_W) 'libopenmpt/libopenmpt_cxx.cpp'; else $(CYGPATH_W) '$(srcdir)/libopenmpt/libopenmpt_cxx.cpp'; fi` libopenmpt/libopenmpttest-libopenmpt_ext_impl.o: libopenmpt/libopenmpt_ext_impl.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT libopenmpt/libopenmpttest-libopenmpt_ext_impl.o -MD -MP -MF libopenmpt/$(DEPDIR)/libopenmpttest-libopenmpt_ext_impl.Tpo -c -o libopenmpt/libopenmpttest-libopenmpt_ext_impl.o `test -f 'libopenmpt/libopenmpt_ext_impl.cpp' || echo '$(srcdir)/'`libopenmpt/libopenmpt_ext_impl.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) libopenmpt/$(DEPDIR)/libopenmpttest-libopenmpt_ext_impl.Tpo libopenmpt/$(DEPDIR)/libopenmpttest-libopenmpt_ext_impl.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='libopenmpt/libopenmpt_ext_impl.cpp' object='libopenmpt/libopenmpttest-libopenmpt_ext_impl.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o libopenmpt/libopenmpttest-libopenmpt_ext_impl.o `test -f 'libopenmpt/libopenmpt_ext_impl.cpp' || echo '$(srcdir)/'`libopenmpt/libopenmpt_ext_impl.cpp libopenmpt/libopenmpttest-libopenmpt_ext_impl.obj: libopenmpt/libopenmpt_ext_impl.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT libopenmpt/libopenmpttest-libopenmpt_ext_impl.obj -MD -MP -MF libopenmpt/$(DEPDIR)/libopenmpttest-libopenmpt_ext_impl.Tpo -c -o libopenmpt/libopenmpttest-libopenmpt_ext_impl.obj `if test -f 'libopenmpt/libopenmpt_ext_impl.cpp'; then $(CYGPATH_W) 'libopenmpt/libopenmpt_ext_impl.cpp'; else $(CYGPATH_W) '$(srcdir)/libopenmpt/libopenmpt_ext_impl.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) libopenmpt/$(DEPDIR)/libopenmpttest-libopenmpt_ext_impl.Tpo libopenmpt/$(DEPDIR)/libopenmpttest-libopenmpt_ext_impl.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='libopenmpt/libopenmpt_ext_impl.cpp' object='libopenmpt/libopenmpttest-libopenmpt_ext_impl.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o libopenmpt/libopenmpttest-libopenmpt_ext_impl.obj `if test -f 'libopenmpt/libopenmpt_ext_impl.cpp'; then $(CYGPATH_W) 'libopenmpt/libopenmpt_ext_impl.cpp'; else $(CYGPATH_W) '$(srcdir)/libopenmpt/libopenmpt_ext_impl.cpp'; fi` libopenmpt/libopenmpttest-libopenmpt_impl.o: libopenmpt/libopenmpt_impl.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT libopenmpt/libopenmpttest-libopenmpt_impl.o -MD -MP -MF libopenmpt/$(DEPDIR)/libopenmpttest-libopenmpt_impl.Tpo -c -o libopenmpt/libopenmpttest-libopenmpt_impl.o `test -f 'libopenmpt/libopenmpt_impl.cpp' || echo '$(srcdir)/'`libopenmpt/libopenmpt_impl.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) libopenmpt/$(DEPDIR)/libopenmpttest-libopenmpt_impl.Tpo libopenmpt/$(DEPDIR)/libopenmpttest-libopenmpt_impl.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='libopenmpt/libopenmpt_impl.cpp' object='libopenmpt/libopenmpttest-libopenmpt_impl.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o libopenmpt/libopenmpttest-libopenmpt_impl.o `test -f 'libopenmpt/libopenmpt_impl.cpp' || echo '$(srcdir)/'`libopenmpt/libopenmpt_impl.cpp libopenmpt/libopenmpttest-libopenmpt_impl.obj: libopenmpt/libopenmpt_impl.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -MT libopenmpt/libopenmpttest-libopenmpt_impl.obj -MD -MP -MF libopenmpt/$(DEPDIR)/libopenmpttest-libopenmpt_impl.Tpo -c -o libopenmpt/libopenmpttest-libopenmpt_impl.obj `if test -f 'libopenmpt/libopenmpt_impl.cpp'; then $(CYGPATH_W) 'libopenmpt/libopenmpt_impl.cpp'; else $(CYGPATH_W) '$(srcdir)/libopenmpt/libopenmpt_impl.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) libopenmpt/$(DEPDIR)/libopenmpttest-libopenmpt_impl.Tpo libopenmpt/$(DEPDIR)/libopenmpttest-libopenmpt_impl.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='libopenmpt/libopenmpt_impl.cpp' object='libopenmpt/libopenmpttest-libopenmpt_impl.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopenmpttest_CPPFLAGS) $(CPPFLAGS) $(libopenmpttest_CXXFLAGS) $(CXXFLAGS) -c -o libopenmpt/libopenmpttest-libopenmpt_impl.obj `if test -f 'libopenmpt/libopenmpt_impl.cpp'; then $(CYGPATH_W) 'libopenmpt/libopenmpt_impl.cpp'; else $(CYGPATH_W) '$(srcdir)/libopenmpt/libopenmpt_impl.cpp'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs -rm -rf bin/.libs bin/_libs -rm -rf common/.libs common/_libs -rm -rf libopenmpt/.libs libopenmpt/_libs -rm -rf sounddsp/.libs sounddsp/_libs -rm -rf soundlib/.libs soundlib/_libs -rm -rf soundlib/plugins/.libs soundlib/plugins/_libs -rm -rf soundlib/plugins/dmo/.libs soundlib/plugins/dmo/_libs distclean-libtool: -rm -f libtool config.lt install-man1: $(man1_MANS) @$(NORMAL_INSTALL) @list1='$(man1_MANS)'; \ list2=''; \ test -n "$(man1dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.1[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list='$(man1_MANS)'; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) install-dist_docDATA: $(dist_doc_DATA) @$(NORMAL_INSTALL) @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(docdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(docdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \ done uninstall-dist_docDATA: @$(NORMAL_UNINSTALL) @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir) install-nobase_dist_docDATA: $(nobase_dist_doc_DATA) @$(NORMAL_INSTALL) @list='$(nobase_dist_doc_DATA)'; test -n "$(docdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(docdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(docdir)" || exit 1; \ fi; \ $(am__nobase_list) | while read dir files; do \ xfiles=; for file in $$files; do \ if test -f "$$file"; then xfiles="$$xfiles $$file"; \ else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ test -z "$$xfiles" || { \ test "x$$dir" = x. || { \ echo " $(MKDIR_P) '$(DESTDIR)$(docdir)/$$dir'"; \ $(MKDIR_P) "$(DESTDIR)$(docdir)/$$dir"; }; \ echo " $(INSTALL_DATA) $$xfiles '$(DESTDIR)$(docdir)/$$dir'"; \ $(INSTALL_DATA) $$xfiles "$(DESTDIR)$(docdir)/$$dir" || exit $$?; }; \ done uninstall-nobase_dist_docDATA: @$(NORMAL_UNINSTALL) @list='$(nobase_dist_doc_DATA)'; test -n "$(docdir)" || list=; \ $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ dir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir) install-pkgconfigDATA: $(pkgconfig_DATA) @$(NORMAL_INSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ done uninstall-pkgconfigDATA: @$(NORMAL_UNINSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) install-nobase_includeHEADERS: $(nobase_include_HEADERS) @$(NORMAL_INSTALL) @list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ fi; \ $(am__nobase_list) | while read dir files; do \ xfiles=; for file in $$files; do \ if test -f "$$file"; then xfiles="$$xfiles $$file"; \ else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ test -z "$$xfiles" || { \ test "x$$dir" = x. || { \ echo " $(MKDIR_P) '$(DESTDIR)$(includedir)/$$dir'"; \ $(MKDIR_P) "$(DESTDIR)$(includedir)/$$dir"; }; \ echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(includedir)/$$dir'"; \ $(INSTALL_HEADER) $$xfiles "$(DESTDIR)$(includedir)/$$dir" || exit $$?; }; \ done uninstall-nobase_includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \ $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscope: cscope.files test ! -s cscope.files \ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) clean-cscope: -rm -f cscope.files cscope.files: clean-cscope cscopelist cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ if test -n "$(PACKAGE_BUGREPORT)"; then \ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ trs_list=`for i in $$bases; do echo $$i.trs; done`; \ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all $(check_PROGRAMS) @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? libopenmpttest.log: libopenmpttest$(EXEEXT) @p='libopenmpttest$(EXEEXT)'; \ b='libopenmpttest'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.test$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) dist-tarZ: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__post_remove_distdir) dist dist-all: $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build/sub \ && ../../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ --srcdir=../.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(MANS) $(DATA) $(HEADERS) \ config.h install-binPROGRAMS: install-libLTLIBRARIES installdirs: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(includedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -rm -f bin/$(am__dirstamp) -rm -f common/$(DEPDIR)/$(am__dirstamp) -rm -f common/$(am__dirstamp) -rm -f examples/$(DEPDIR)/$(am__dirstamp) -rm -f examples/$(am__dirstamp) -rm -f libopenmpt/$(DEPDIR)/$(am__dirstamp) -rm -f libopenmpt/$(am__dirstamp) -rm -f openmpt123/$(DEPDIR)/$(am__dirstamp) -rm -f openmpt123/$(am__dirstamp) -rm -f sounddsp/$(DEPDIR)/$(am__dirstamp) -rm -f sounddsp/$(am__dirstamp) -rm -f soundlib/$(DEPDIR)/$(am__dirstamp) -rm -f soundlib/$(am__dirstamp) -rm -f soundlib/plugins/$(DEPDIR)/$(am__dirstamp) -rm -f soundlib/plugins/$(am__dirstamp) -rm -f soundlib/plugins/dmo/$(DEPDIR)/$(am__dirstamp) -rm -f soundlib/plugins/dmo/$(am__dirstamp) -rm -f test/$(DEPDIR)/$(am__dirstamp) -rm -f test/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ clean-libLTLIBRARIES clean-libtool mostlyclean-am distclean: distclean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf common/$(DEPDIR) examples/$(DEPDIR) libopenmpt/$(DEPDIR) openmpt123/$(DEPDIR) sounddsp/$(DEPDIR) soundlib/$(DEPDIR) soundlib/plugins/$(DEPDIR) soundlib/plugins/dmo/$(DEPDIR) test/$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-hdr distclean-libtool distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dist_docDATA install-man \ install-nobase_dist_docDATA install-nobase_includeHEADERS \ install-pkgconfigDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-libLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -rf common/$(DEPDIR) examples/$(DEPDIR) libopenmpt/$(DEPDIR) openmpt123/$(DEPDIR) sounddsp/$(DEPDIR) soundlib/$(DEPDIR) soundlib/plugins/$(DEPDIR) soundlib/plugins/dmo/$(DEPDIR) test/$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-dist_docDATA \ uninstall-libLTLIBRARIES uninstall-man \ uninstall-nobase_dist_docDATA uninstall-nobase_includeHEADERS \ uninstall-pkgconfigDATA uninstall-man: uninstall-man1 .MAKE: all check-am install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-TESTS \ check-am clean clean-binPROGRAMS clean-checkPROGRAMS \ clean-cscope clean-generic clean-libLTLIBRARIES clean-libtool \ cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \ dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \ distcheck distclean distclean-compile distclean-generic \ distclean-hdr distclean-libtool distclean-tags distcleancheck \ distdir distuninstallcheck dvi dvi-am html html-am info \ info-am install install-am install-binPROGRAMS install-data \ install-data-am install-dist_docDATA install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am \ install-libLTLIBRARIES install-man install-man1 \ install-nobase_dist_docDATA install-nobase_includeHEADERS \ install-pdf install-pdf-am install-pkgconfigDATA install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am recheck tags tags-am \ uninstall uninstall-am uninstall-binPROGRAMS \ uninstall-dist_docDATA uninstall-libLTLIBRARIES uninstall-man \ uninstall-man1 uninstall-nobase_dist_docDATA \ uninstall-nobase_includeHEADERS uninstall-pkgconfigDATA .PRECIOUS: Makefile @DX_RULES@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libopenmpt-0.3.6+release.autotools/Doxyfile.in0000644000372100037210000032341413235362207016403 00000000000000# Doxyfile 1.8.13 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a double hash (##) is considered a comment and is placed in # front of the TAG it is preceding. # # All text after a single hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists, items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (\" \"). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all text # before the first occurrence of this tag. Doxygen uses libiconv (or the iconv # built into libc) for the transcoding. See http://www.gnu.org/software/libiconv # for the list of possible encodings. # The default value is: UTF-8. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded by # double-quotes, unless you are using Doxywizard) that should identify the # project for which the documentation is generated. This name is used in the # title of most generated pages and in a few other places. # The default value is: My Project. PROJECT_NAME = "libopenmpt" # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version # control system is used. # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a # quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = "cross-platform C++ and C library to decode tracked music files" # With the PROJECT_LOGO tag one can specify a logo or an icon that is included # in the documentation. The maximum height of the logo should not exceed 55 # pixels and the maximum width should not exceed 200 pixels. Doxygen will copy # the logo to the output directory. PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path # into which the generated documentation will be written. If a relative path is # entered, it will be relative to the location where doxygen was started. If # left blank the current directory will be used. OUTPUT_DIRECTORY = bin/docs # If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- # directories (in 2 levels) under the output directory of each output format and # will distribute the generated files over these directories. Enabling this # option can be useful when feeding doxygen a huge amount of source files, where # putting all generated files in the same directory would otherwise causes # performance problems for the file system. # The default value is: NO. CREATE_SUBDIRS = NO # If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII # characters to appear in the names of generated files. If set to NO, non-ASCII # characters will be escaped, for example _xE3_x81_x84 will be used for Unicode # U+3044. # The default value is: NO. ALLOW_UNICODE_NAMES = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, # Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), # Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, # Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), # Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, # Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, # Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, # Ukrainian and Vietnamese. # The default value is: English. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member # descriptions after the members that are listed in the file and class # documentation (similar to Javadoc). Set to NO to disable this. # The default value is: YES. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief # description of a member or function before the detailed description # # Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. # The default value is: YES. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator that is # used to form the text in various listings. Each string in this list, if found # as the leading text of the brief description, will be stripped from the text # and the result, after processing the whole list, is used as the annotated # text. Otherwise, the brief description is used as-is. If left blank, the # following values are used ($name is automatically replaced with the name of # the entity):The $name class, The $name widget, The $name file, is, provides, # specifies, contains, represents, a, an and the. ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # doxygen will generate a detailed section even if there is only a brief # description. # The default value is: NO. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. # The default value is: NO. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path # before files name in the file list and in the header files. If set to NO the # shortest path that makes the file name unique will be used # The default value is: YES. FULL_PATH_NAMES = YES # The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. # Stripping is only done if one of the specified strings matches the left-hand # part of the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the path to # strip. # # Note that you can specify absolute paths here, but also relative paths, which # will be relative from the directory where doxygen is started. # This tag requires that the tag FULL_PATH_NAMES is set to YES. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the # path mentioned in the documentation of a class, which tells the reader which # header file to include in order to use a class. If left blank only the name of # the header file containing the class definition is used. Otherwise one should # specify the list of include paths that are normally passed to the compiler # using the -I flag. STRIP_FROM_INC_PATH = . # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but # less readable) file names. This can be useful is your file systems doesn't # support long names like on DOS, Mac, or CD-ROM. # The default value is: NO. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the # first line (until the first dot) of a Javadoc-style comment as the brief # description. If set to NO, the Javadoc-style will behave just like regular Qt- # style comments (thus requiring an explicit @brief command for a brief # description.) # The default value is: NO. JAVADOC_AUTOBRIEF = NO # If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first # line (until the first dot) of a Qt-style comment as the brief description. If # set to NO, the Qt-style will behave just like regular Qt-style comments (thus # requiring an explicit \brief command for a brief description.) # The default value is: NO. QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a # multi-line C++ special comment block (i.e. a block of //! or /// comments) as # a brief description. This used to be the default behavior. The new default is # to treat a multi-line C++ comment block as a detailed description. Set this # tag to YES if you prefer the old behavior instead. # # Note that setting this tag to YES also means that rational rose comments are # not recognized any more. # The default value is: NO. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the # documentation from any documented member that it re-implements. # The default value is: YES. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new # page for each member. If set to NO, the documentation of a member will be part # of the file/class/namespace that contains it. # The default value is: NO. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen # uses this value to replace tabs by spaces in code fragments. # Minimum value: 1, maximum value: 16, default value: 4. TAB_SIZE = 2 # This tag can be used to specify a number of aliases that act as commands in # the documentation. An alias has the form: # name=value # For example adding # "sideeffect=@par Side Effects:\n" # will allow you to put the command \sideeffect (or @sideeffect) in the # documentation, which will result in a user-defined paragraph with heading # "Side Effects:". You can put \n's in the value part of an alias to insert # newlines. ALIASES = # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding "class=itcl::class" # will allow you to use the command class in the itcl::class meaning. TCL_SUBST = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources # only. Doxygen will then generate output that is more tailored for C. For # instance, some of the names that are used will be different. The list of all # members will be omitted, etc. # The default value is: NO. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or # Python sources only. Doxygen will then generate output that is more tailored # for that language. For instance, namespaces will be presented as packages, # qualified scopes will look different, etc. # The default value is: NO. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources. Doxygen will then generate output that is tailored for Fortran. # The default value is: NO. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for VHDL. # The default value is: NO. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and # language is one of the parsers supported by doxygen: IDL, Java, Javascript, # C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: # FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: # Fortran. In the later case the parser tries to guess whether the code is fixed # or free formatted code, this is the default for Fortran type files), VHDL. For # instance to make doxygen treat .inc files as Fortran files (default is PHP), # and .f files as C (default is Fortran), use: inc=Fortran f=C. # # Note: For files without extension you can use no_extension as a placeholder. # # Note that for custom extensions you also need to set FILE_PATTERNS otherwise # the files are not read by doxygen. EXTENSION_MAPPING = # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments # according to the Markdown format, which allows for more readable # documentation. See http://daringfireball.net/projects/markdown/ for details. # The output of markdown processing is further processed by doxygen, so you can # mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in # case of backward compatibilities issues. # The default value is: YES. MARKDOWN_SUPPORT = YES # When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up # to that level are automatically included in the table of contents, even if # they do not have an id attribute. # Note: This feature currently applies only to Markdown headings. # Minimum value: 0, maximum value: 99, default value: 0. # This tag requires that the tag MARKDOWN_SUPPORT is set to YES. TOC_INCLUDE_HEADINGS = 0 # When enabled doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can # be prevented in individual cases by putting a % sign in front of the word or # globally by setting AUTOLINK_SUPPORT to NO. # The default value is: YES. AUTOLINK_SUPPORT = YES # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should set this # tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); # versus func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. # The default value is: NO. BUILTIN_STL_SUPPORT = YES # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. # The default value is: NO. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip (see: # http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen # will parse them like normal C++ but will assume all classes use public instead # of private inheritance when no explicit protection keyword is present. # The default value is: NO. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate # getter and setter methods for a property. Setting this option to YES will make # doxygen to replace the get and set methods by a property in the documentation. # This will only work if the methods are indeed getting or setting a simple # type. If this is not the case, or you want to show the methods anyway, you # should set this option to NO. # The default value is: YES. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. # The default value is: NO. DISTRIBUTE_GROUP_DOC = NO # If one adds a struct or class to a group and this option is enabled, then also # any nested class or struct is added to the same group. By default this option # is disabled and one has to add nested compounds explicitly via \ingroup. # The default value is: NO. GROUP_NESTED_COMPOUNDS = NO # Set the SUBGROUPING tag to YES to allow class member groups of the same type # (for instance a group of public functions) to be put as a subgroup of that # type (e.g. under the Public Functions section). Set it to NO to prevent # subgrouping. Alternatively, this can be done per class using the # \nosubgrouping command. # The default value is: YES. SUBGROUPING = YES # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions # are shown inside the group in which they are included (e.g. using \ingroup) # instead of on a separate page (for HTML and Man pages) or section (for LaTeX # and RTF). # # Note that this feature does not work in combination with # SEPARATE_MEMBER_PAGES. # The default value is: NO. INLINE_GROUPED_CLASSES = NO # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions # with only public data fields or simple typedef fields will be shown inline in # the documentation of the scope in which they are defined (i.e. file, # namespace, or group documentation), provided this scope is documented. If set # to NO, structs, classes, and unions are shown on a separate page (for HTML and # Man pages) or section (for LaTeX and RTF). # The default value is: NO. INLINE_SIMPLE_STRUCTS = NO # When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or # enum is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically be # useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. # The default value is: NO. TYPEDEF_HIDES_STRUCT = NO # The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This # cache is used to resolve symbols given their name and scope. Since this can be # an expensive process and often the same symbol appears multiple times in the # code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small # doxygen will become slower. If the cache is too large, memory is wasted. The # cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range # is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 # symbols. At the end of a run doxygen will report the cache usage and suggest # the optimal cache size from a speed point of view. # Minimum value: 0, maximum value: 9, default value: 0. LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in # documentation are documented, even if no documentation was available. Private # class members and static file members will be hidden unless the # EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. # Note: This will also disable the warnings about undocumented members that are # normally produced when WARNINGS is set to YES. # The default value is: NO. EXTRACT_ALL = YES # If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will # be included in the documentation. # The default value is: NO. EXTRACT_PRIVATE = NO # If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal # scope will be included in the documentation. # The default value is: NO. EXTRACT_PACKAGE = NO # If the EXTRACT_STATIC tag is set to YES, all static members of a file will be # included in the documentation. # The default value is: NO. EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined # locally in source files will be included in the documentation. If set to NO, # only classes defined in header files are included. Does not have any effect # for Java sources. # The default value is: YES. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. If set to YES, local methods, # which are defined in the implementation section but not in the interface are # included in the documentation. If set to NO, only methods in the interface are # included. # The default value is: NO. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base name of # the file that contains the anonymous namespace. By default anonymous namespace # are hidden. # The default value is: NO. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all # undocumented members inside documented classes or files. If set to NO these # members will be included in the various overviews, but no documentation # section is generated. This option has no effect if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. If set # to NO, these classes will be included in the various overviews. This option # has no effect if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend # (class|struct|union) declarations. If set to NO, these declarations will be # included in the documentation. # The default value is: NO. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any # documentation blocks found inside the body of a function. If set to NO, these # blocks will be appended to the function's detailed documentation block. # The default value is: NO. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation that is typed after a # \internal command is included. If the tag is set to NO then the documentation # will be excluded. Set it to YES to include the internal documentation. # The default value is: NO. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file # names in lower-case letters. If set to YES, upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. # The default value is: system dependent. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with # their full class and namespace scopes in the documentation. If set to YES, the # scope will be hidden. # The default value is: NO. HIDE_SCOPE_NAMES = NO # If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will # append additional text to a page's title, such as Class Reference. If set to # YES the compound reference will be hidden. # The default value is: NO. HIDE_COMPOUND_REFERENCE= NO # If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of # the files that are included by a file in the documentation of that file. # The default value is: YES. SHOW_INCLUDE_FILES = YES # If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each # grouped member an include statement to the documentation, telling the reader # which file to include in order to use the member. # The default value is: NO. SHOW_GROUPED_MEMB_INC = NO # If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include # files with double quotes in the documentation rather than with sharp brackets. # The default value is: NO. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the # documentation for inline members. # The default value is: YES. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the # (detailed) documentation of file and class members alphabetically by member # name. If set to NO, the members will appear in declaration order. # The default value is: YES. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief # descriptions of file, namespace and class members alphabetically by member # name. If set to NO, the members will appear in declaration order. Note that # this will also influence the order of the classes in the class list. # The default value is: NO. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the # (brief and detailed) documentation of class members so that constructors and # destructors are listed first. If set to NO the constructors will appear in the # respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. # Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief # member documentation. # Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting # detailed member documentation. # The default value is: NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy # of group names into alphabetical order. If set to NO the group names will # appear in their defined order. # The default value is: NO. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by # fully-qualified names, including namespaces. If set to NO, the class list will # be sorted only by class name, not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the alphabetical # list. # The default value is: NO. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper # type resolution of all parameters of a function it will reject a match between # the prototype and the implementation of a member function even if there is # only one candidate or it is obvious which candidate to choose by doing a # simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still # accept a match between prototype and implementation in such cases. # The default value is: NO. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo # list. This list is created by putting \todo commands in the documentation. # The default value is: YES. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test # list. This list is created by putting \test commands in the documentation. # The default value is: YES. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug # list. This list is created by putting \bug commands in the documentation. # The default value is: YES. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) # the deprecated list. This list is created by putting \deprecated commands in # the documentation. # The default value is: YES. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional documentation # sections, marked by \if ... \endif and \cond # ... \endcond blocks. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the # initial value of a variable or macro / define can have for it to appear in the # documentation. If the initializer consists of more lines than specified here # it will be hidden. Use a value of 0 to hide initializers completely. The # appearance of the value of individual variables and macros / defines can be # controlled using \showinitializer or \hideinitializer command in the # documentation regardless of this setting. # Minimum value: 0, maximum value: 10000, default value: 30. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated at # the bottom of the documentation of classes and structs. If set to YES, the # list will mention the files that were used to generate the documentation. # The default value is: YES. SHOW_USED_FILES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. This # will remove the Files entry from the Quick Index and from the Folder Tree View # (if specified). # The default value is: YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces # page. This will remove the Namespaces entry from the Quick Index and from the # Folder Tree View (if specified). # The default value is: YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command command input-file, where command is the value of the # FILE_VERSION_FILTER tag, and input-file is the name of an input file provided # by doxygen. Whatever the program writes to standard output is used as the file # version. For an example see the documentation. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. You can # optionally specify a file name after the option, if omitted DoxygenLayout.xml # will be used as the name of the layout file. # # Note that if you run doxygen from a directory containing a file called # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE # tag is left empty. LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files containing # the reference definitions. This must be a list of .bib files. The .bib # extension is automatically appended if omitted. This requires the bibtex tool # to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. # For LaTeX the style of the bibliography can be controlled using # LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the # search path. See also \cite for info how to create references. CITE_BIB_FILES = #--------------------------------------------------------------------------- # Configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated to # standard output by doxygen. If QUIET is set to YES this implies that the # messages are off. # The default value is: NO. QUIET = YES # The WARNINGS tag can be used to turn on/off the warning messages that are # generated to standard error (stderr) by doxygen. If WARNINGS is set to YES # this implies that the warnings are on. # # Tip: Turn warnings on while writing the documentation. # The default value is: YES. WARNINGS = YES # If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate # warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag # will automatically be disabled. # The default value is: YES. WARN_IF_UNDOCUMENTED = YES # If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some parameters # in a documented function, or documenting parameters that don't exist or using # markup commands wrongly. # The default value is: YES. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # are documented, but have no documentation for their parameters or return # value. If set to NO, doxygen will only warn about wrong or incomplete # parameter documentation, but not about the absence of documentation. # The default value is: NO. WARN_NO_PARAMDOC = NO # If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when # a warning is encountered. # The default value is: NO. WARN_AS_ERROR = NO # The WARN_FORMAT tag determines the format of the warning messages that doxygen # can produce. The string should contain the $file, $line, and $text tags, which # will be replaced by the file and line number from which the warning originated # and the warning text. Optionally the format may contain $version, which will # be replaced by the version of the file (if it could be obtained via # FILE_VERSION_FILTER) # The default value is: $file:$line: $text. WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning and error # messages should be written. If left blank the output is written to standard # error (stderr). WARN_LOGFILE = #--------------------------------------------------------------------------- # Configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag is used to specify the files and/or directories that contain # documented source files. You may enter file names like myfile.cpp or # directories like /usr/src/myproject. Separate the files or directories with # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. INPUT = libopenmpt/dox/index.dox \ libopenmpt/dox/quickstart.md \ README.md \ libopenmpt/dox/dependencies.md \ libopenmpt/dox/packaging.md \ libopenmpt/dox/tests.md \ libopenmpt/dox/changelog.md \ libopenmpt/dox/todo.md \ libopenmpt/libopenmpt.hpp \ libopenmpt/libopenmpt.h \ libopenmpt/libopenmpt_stream_callbacks_buffer.h \ libopenmpt/libopenmpt_stream_callbacks_fd.h \ libopenmpt/libopenmpt_stream_callbacks_file.h \ libopenmpt/libopenmpt_config.h \ libopenmpt/libopenmpt_version.h \ libopenmpt/libopenmpt_ext.hpp \ libopenmpt/libopenmpt_ext.h # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses # libiconv (or the iconv built into libc) for the transcoding. See the libiconv # documentation (see: http://www.gnu.org/software/libiconv) for the list of # possible encodings. # The default value is: UTF-8. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and # *.h) to filter out the source-files in the directories. # # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not # read by doxygen. # # If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, # *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, # *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, # *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, # *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf. FILE_PATTERNS = # The RECURSIVE tag can be used to specify whether or not subdirectories should # be searched for input files as well. # The default value is: NO. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. # # Note that relative paths are relative to the directory from which doxygen is # run. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. # The default value is: NO. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. # # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test # # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories use the pattern */test/* EXCLUDE_SYMBOLS = LIBOPENMPT_API \ LIBOPENMPT_CXX_API \ LIBOPENMPT_API_HELPER_EXPORT \ LIBOPENMPT_API_HELPER_IMPORT \ LIBOPENMPT_API_HELPER_PUBLIC \ LIBOPENMPT_API_HELPER_LOCAL \ OPENMPT_API_VERSION_HELPER_STRINGIZE \ OPENMPT_API_VERSION_STRINGIZE \ openmpt::detail # The EXAMPLE_PATH tag can be used to specify one or more files or directories # that contain example code fragments that are included (see the \include # command). EXAMPLE_PATH = examples/ \ LICENSE # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and # *.h) to filter out the source-files in the directories. If left blank all # files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude commands # irrespective of the value of the RECURSIVE tag. # The default value is: NO. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or directories # that contain images that are to be included in the documentation (see the # \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command: # # # # where is the value of the INPUT_FILTER tag, and is the # name of an input file. Doxygen will then use the output that the filter # program writes to standard output. If FILTER_PATTERNS is specified, this tag # will be ignored. # # Note that the filter must not add or remove lines; it is applied before the # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. # # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not # properly processed by doxygen. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: pattern=filter # (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how # filters are used. If the FILTER_PATTERNS tag is empty or if none of the # patterns match the file name, INPUT_FILTER is applied. # # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not # properly processed by doxygen. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will also be used to filter the input files that are used for # producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). # The default value is: NO. FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) and # it is also possible to disable source filtering for a specific pattern using # *.ext= (so without naming a filter). # This tag requires that the tag FILTER_SOURCE_FILES is set to YES. FILTER_SOURCE_PATTERNS = # If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that # is part of the input, its contents will be placed on the main page # (index.html). This can be useful if you have a project on for instance GitHub # and want to reuse the introduction page also for the doxygen output. USE_MDFILE_AS_MAINPAGE = #--------------------------------------------------------------------------- # Configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will be # generated. Documented entities will be cross-referenced with these sources. # # Note: To get rid of all source code in the generated output, make sure that # also VERBATIM_HEADERS is set to NO. # The default value is: NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body of functions, # classes and enums directly into the documentation. # The default value is: NO. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any # special comment blocks from generated source code fragments. Normal C, C++ and # Fortran comments will always remain visible. # The default value is: YES. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES then for each documented # function all documented functions referencing it will be listed. # The default value is: NO. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES then for each documented function # all documented entities called/used by that function will be listed. # The default value is: NO. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set # to YES then the hyperlinks from functions in REFERENCES_RELATION and # REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will # link to the documentation. # The default value is: YES. REFERENCES_LINK_SOURCE = YES # If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the # source code will show a tooltip with additional information such as prototype, # brief description and links to the definition and documentation. Since this # will make the HTML file larger and loading of large files a bit slower, you # can opt to disable this feature. # The default value is: YES. # This tag requires that the tag SOURCE_BROWSER is set to YES. SOURCE_TOOLTIPS = YES # If the USE_HTAGS tag is set to YES then the references to source code will # point to the HTML generated by the htags(1) tool instead of doxygen built-in # source browser. The htags tool is part of GNU's global source tagging system # (see http://www.gnu.org/software/global/global.html). You will need version # 4.8.6 or higher. # # To use it do the following: # - Install the latest version of global # - Enable SOURCE_BROWSER and USE_HTAGS in the config file # - Make sure the INPUT points to the root of the source tree # - Run doxygen as normal # # Doxygen will invoke htags (and that will in turn invoke gtags), so these # tools must be available from the command line (i.e. in the search path). # # The result: instead of the source browser generated by doxygen, the links to # source code will now point to the output of htags. # The default value is: NO. # This tag requires that the tag SOURCE_BROWSER is set to YES. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a # verbatim copy of the header file for each class for which an include is # specified. Set to NO to disable this. # See also: Section \class. # The default value is: YES. VERBATIM_HEADERS = YES # If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the # clang parser (see: http://clang.llvm.org/) for more accurate parsing at the # cost of reduced performance. This can be particularly helpful with template # rich C++ code for which doxygen's built-in parser lacks the necessary type # information. # Note: The availability of this option depends on whether or not doxygen was # generated with the -Duse-libclang=ON option for CMake. # The default value is: NO. CLANG_ASSISTED_PARSING = NO # If clang assisted parsing is enabled you can provide the compiler with command # line options that you would normally use when invoking the compiler. Note that # the include paths will already be set by doxygen for the files and directories # specified with INPUT and INCLUDE_PATH. # This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. CLANG_OPTIONS = #--------------------------------------------------------------------------- # Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all # compounds will be generated. Enable this if the project contains a lot of # classes, structs, unions or interfaces. # The default value is: YES. ALPHABETICAL_INDEX = YES # The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in # which the alphabetical index list will be split. # Minimum value: 1, maximum value: 20, default value: 5. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all classes will # be put under the same header in the alphabetical index. The IGNORE_PREFIX tag # can be used to specify a prefix (or a list of prefixes) that should be ignored # while generating the index headers. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. IGNORE_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output # The default value is: YES. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of # it. # The default directory is: html. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for each # generated HTML page (for example: .htm, .php, .asp). # The default value is: .html. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a user-defined HTML header file for # each generated HTML page. If the tag is left blank doxygen will generate a # standard header. # # To get valid HTML the header file that includes any scripts and style sheets # that doxygen needs, which is dependent on the configuration options used (e.g. # the setting GENERATE_TREEVIEW). It is highly recommended to start with a # default header using # doxygen -w html new_header.html new_footer.html new_stylesheet.css # YourConfigFile # and then modify the file new_header.html. See also section "Doxygen usage" # for information on how to generate the default header that doxygen normally # uses. # Note: The header is subject to change so you typically have to regenerate the # default header when upgrading to a newer version of doxygen. For a description # of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each # generated HTML page. If the tag is left blank doxygen will generate a standard # footer. See HTML_HEADER for more information on how to generate a default # footer and what special commands can be used inside the footer. See also # section "Doxygen usage" for information on how to generate the default footer # that doxygen normally uses. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading style # sheet that is used by each HTML page. It can be used to fine-tune the look of # the HTML output. If left blank doxygen will generate a default style sheet. # See also section "Doxygen usage" for information on how to generate the style # sheet that doxygen normally uses. # Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as # it is more robust and this tag (HTML_STYLESHEET) will in the future become # obsolete. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_STYLESHEET = # The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined # cascading style sheets that are included after the standard style sheets # created by doxygen. Using this option one can overrule certain style aspects. # This is preferred over using HTML_STYLESHEET since it does not replace the # standard style sheet and is therefore more robust against future updates. # Doxygen will copy the style sheet files to the output directory. # Note: The order of the extra style sheet files is of importance (e.g. the last # style sheet in the list overrules the setting of the previous ones in the # list). For an example see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_STYLESHEET = # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the # $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these # files. In the HTML_STYLESHEET file, use the file name only. Also note that the # files will be copied as-is; there are no commands or markers available. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen # will adjust the colors in the style sheet and background images according to # this color. Hue is specified as an angle on a colorwheel, see # http://en.wikipedia.org/wiki/Hue for more information. For instance the value # 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 # purple, and 360 is red again. # Minimum value: 0, maximum value: 359, default value: 220. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors # in the HTML output. For a value of 0 the output will use grayscales only. A # value of 255 will produce the most vivid colors. # Minimum value: 0, maximum value: 255, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the # luminance component of the colors in the HTML output. Values below 100 # gradually make the output lighter, whereas values above 100 make the output # darker. The value divided by 100 is the actual gamma applied, so 80 represents # a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not # change the gamma. # Minimum value: 40, maximum value: 240, default value: 80. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting this # to YES can help to show when doxygen was last run and thus if the # documentation is up to date. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_TIMESTAMP = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_DYNAMIC_SECTIONS = NO # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries # shown in the various tree structured indices initially; the user can expand # and collapse entries dynamically later on. Doxygen will expand the tree to # such a level that at most the specified number of entries are visible (unless # a fully collapsed tree already exceeds this amount). So setting the number of # entries 1 will produce a full collapsed tree by default. 0 is a special value # representing an infinite number of entries and will result in a full expanded # tree by default. # Minimum value: 0, maximum value: 9999, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_INDEX_NUM_ENTRIES = 100 # If the GENERATE_DOCSET tag is set to YES, additional index files will be # generated that can be used as input for Apple's Xcode 3 integrated development # environment (see: http://developer.apple.com/tools/xcode/), introduced with # OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a # Makefile in the HTML output directory. Running make will produce the docset in # that directory and running make install will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at # startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_DOCSET = NO # This tag determines the name of the docset feed. A documentation feed provides # an umbrella under which multiple documentation sets from a single provider # (such as a company or product suite) can be grouped. # The default value is: Doxygen generated docs. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_FEEDNAME = "Doxygen generated docs" # This tag specifies a string that should uniquely identify the documentation # set bundle. This should be a reverse domain-name style string, e.g. # com.mycompany.MyDocSet. Doxygen will append .docset to the name. # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_BUNDLE_ID = org.doxygen.Project # The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style # string, e.g. com.mycompany.MyDocSet.documentation. # The default value is: org.doxygen.Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. # The default value is: Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three # additional HTML index files: index.hhp, index.hhc, and index.hhk. The # index.hhp is a project file that can be read by Microsoft's HTML Help Workshop # (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on # Windows. # # The HTML Help Workshop contains a compiler that can convert all HTML output # generated by doxygen into a single compiled HTML file (.chm). Compiled HTML # files are now used as the Windows 98 help format, and will replace the old # Windows help format (.hlp) on all Windows platforms in the future. Compressed # HTML files also contain an index, a table of contents, and you can search for # words in the documentation. The HTML workshop also contains a viewer for # compressed HTML files. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_HTMLHELP = NO # The CHM_FILE tag can be used to specify the file name of the resulting .chm # file. You can add a path in front of the file if the result should not be # written to the html output directory. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_FILE = # The HHC_LOCATION tag can be used to specify the location (absolute path # including file name) of the HTML help compiler (hhc.exe). If non-empty, # doxygen will try to run the HTML help compiler on the generated index.hhp. # The file has to be specified with full path. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. HHC_LOCATION = # The GENERATE_CHI flag controls if a separate .chi index file is generated # (YES) or that it should be included in the master .chm file (NO). # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. GENERATE_CHI = NO # The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) # and project file content. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_INDEX_ENCODING = # The BINARY_TOC flag controls whether a binary table of contents is generated # (YES) or a normal table of contents (NO) in the .chm file. Furthermore it # enables the Previous and Next buttons. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members to # the table of contents of the HTML help documentation and to the tree view. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that # can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help # (.qch) of the generated HTML documentation. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify # the file name of the resulting .qch file. The path specified is relative to # the HTML output folder. # This tag requires that the tag GENERATE_QHP is set to YES. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help # Project output. For more information please see Qt Help Project / Namespace # (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_QHP is set to YES. QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt # Help Project output. For more information please see Qt Help Project / Virtual # Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- # folders). # The default value is: doc. # This tag requires that the tag GENERATE_QHP is set to YES. QHP_VIRTUAL_FOLDER = doc # If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom # filter to add. For more information please see Qt Help Project / Custom # Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- # filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_NAME = # The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see Qt Help Project / Custom # Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- # filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's filter section matches. Qt Help Project / Filter Attributes (see: # http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_SECT_FILTER_ATTRS = # The QHG_LOCATION tag can be used to specify the location of Qt's # qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the # generated .qhp file. # This tag requires that the tag GENERATE_QHP is set to YES. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be # generated, together with the HTML files, they form an Eclipse help plugin. To # install this plugin and make it available under the help contents menu in # Eclipse, the contents of the directory containing the HTML and XML files needs # to be copied into the plugins directory of eclipse. The name of the directory # within the plugins directory should be the same as the ECLIPSE_DOC_ID value. # After copying Eclipse needs to be restarted before the help appears. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_ECLIPSEHELP = NO # A unique identifier for the Eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have this # name. Each documentation set should have its own identifier. # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. ECLIPSE_DOC_ID = org.doxygen.Project # If you want full control over the layout of the generated HTML pages it might # be necessary to disable the index and replace it with your own. The # DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top # of each HTML page. A value of NO enables the index and the value YES disables # it. Since the tabs in the index contain the same information as the navigation # tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. DISABLE_INDEX = NO # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. If the tag # value is set to YES, a side panel will be generated containing a tree-like # index structure (just like the one that is generated for HTML Help). For this # to work a browser that supports JavaScript, DHTML, CSS and frames is required # (i.e. any modern browser). Windows users are probably better off using the # HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can # further fine-tune the look of the index. As an example, the default style # sheet generated by doxygen has an example that shows how to put an image at # the root of the tree instead of the PROJECT_NAME. Since the tree basically has # the same information as the tab index, you could consider setting # DISABLE_INDEX to YES when enabling this option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_TREEVIEW = YES # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that # doxygen will group on one line in the generated HTML documentation. # # Note that a value of 0 will completely suppress the enum values from appearing # in the overview section. # Minimum value: 0, maximum value: 20, default value: 4. # This tag requires that the tag GENERATE_HTML is set to YES. ENUM_VALUES_PER_LINE = 4 # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used # to set the initial width (in pixels) of the frame in which the tree is shown. # Minimum value: 0, maximum value: 1500, default value: 250. # This tag requires that the tag GENERATE_HTML is set to YES. TREEVIEW_WIDTH = 250 # If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to # external symbols imported via tag files in a separate window. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of LaTeX formulas included as images in # the HTML documentation. When you change the font size after a successful # doxygen run you need to manually remove any form_*.png images from the HTML # output directory to force them to be regenerated. # Minimum value: 8, maximum value: 50, default value: 10. # This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are not # supported properly for IE 6.0, but are supported on all modern browsers. # # Note that when changing this option you need to delete any form_*.png files in # the HTML output directory before the changes have effect. # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see # http://www.mathjax.org) which uses client side Javascript for the rendering # instead of using pre-rendered bitmaps. Use this if you do not have LaTeX # installed or if you want to formulas look prettier in the HTML output. When # enabled you may also need to install MathJax separately and configure the path # to it using the MATHJAX_RELPATH option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. USE_MATHJAX = NO # When MathJax is enabled you can set the default output format to be used for # the MathJax output. See the MathJax site (see: # http://docs.mathjax.org/en/latest/output.html) for more details. # Possible values are: HTML-CSS (which is slower, but has the best # compatibility), NativeMML (i.e. MathML) and SVG. # The default value is: HTML-CSS. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_FORMAT = HTML-CSS # When MathJax is enabled you need to specify the location relative to the HTML # output directory using the MATHJAX_RELPATH option. The destination directory # should contain the MathJax.js script. For instance, if the mathjax directory # is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax # Content Delivery Network so you can quickly see the result without installing # MathJax. However, it is strongly recommended to install a local copy of # MathJax from http://www.mathjax.org before deployment. # The default value is: http://cdn.mathjax.org/mathjax/latest. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_RELPATH = http://www.mathjax.org/mathjax # The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax # extension names that should be enabled during MathJax rendering. For example # MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_EXTENSIONS = # The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces # of code that will be used on startup of the MathJax code. See the MathJax site # (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an # example see the documentation. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_CODEFILE = # When the SEARCHENGINE tag is enabled doxygen will generate a search box for # the HTML output. The underlying search engine uses javascript and DHTML and # should work on any modern browser. Note that when using HTML help # (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) # there is already a search function so this one should typically be disabled. # For large projects the javascript based search engine can be slow, then # enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to # search using the keyboard; to jump to the search box use + S # (what the is depends on the OS and browser, but it is typically # , /